Budapesti Műszaki és Gazdaságtudományi Egyetem Méréstechnika és Információs Rendszerek Tanszék
Geoelectro geofizikai monitoring rendszerhez mérésvezérlő program készítése Önálló laboratórium (2.) zárójegyzőkönyv 2013/14. II. félév
Vincze Zsolt (ELVS69) I. évf, vill. szakos hallgató MSc Beágyazott információs rendszerek szakirány
Konzulensek: Krébesz Tamás István tanársegéd (Méréstechnika és Információs Rendszerek Tanszék)
Feladat Fejlessze a meglévő mérésvezérlő szoftvert a Geoelectro geofizikai monitoring rendszerhez! A második félév végén a program legyen képes önálló terepi mérés végrehajtására, ennek feltételei:
•
Szenzor fájl megnyitása
•
Mérési sorozat elvégzése
•
Mért eredményeket kívánt formátumú fájlba menteni
•
Hibakezelési feladatok megvalósítása a mérés sikeressége érdekében
•
Hardver fejlesztésében való részvétel
................................... Krébesz Tamás István
Tartalom Bevezetés..................................................................................................................4 Geoelectro geofizikai monitoring rendszer..................................................4 A fólia hibák detektálása hibatérkép felvételével.........................................6 A mérések műszere.......................................................................................7 A fejlesztendő program................................................................................8 Az elkészült program...............................................................................................10 Felhasználói felület.......................................................................................11 Működés.......................................................................................................12 Hibakezelés...................................................................................................14 Tesztelés.......................................................................................................15 USB – RS485 interfész............................................................................................17 Mellékletek...............................................................................................................19 1. melléklet: A program forráskódja.............................................................19 2. melléklet: az USB – RS485 interfész kapcsolási rajza.............................33
Bevezetés A Geoelectro Kft. egy 2004-ben alakult kis családi vállalkozás, mely elsősorban saját fejlesztésű
és
készítésű
vezetőképesség-mérő,
műszerekkel
egyenáramú
elektromágneses
geoelektromos,
frekvenciaszondázó,
elektromágneses
VLF-rádiófrekvenciás,
mágneses, akusztikus méréseket tud végezni. Geoelectro geofizikai monitoring rendszer
Új
hulladéklerakó
telepek
létesítésénél
ma
már
szigorú
környezetvédelmi
követelményeknek kell megfelelni. Az egyik legfontosabb, a lerakótér medencéjének megfelelő vízzárósága, hogy a hulladékot átmosó víz ne tudjon szennyező anyagokat szállítani a környezet felé. A medencék szigetelésére a leghatékonyabb módszer plasztikus szigetelő fólia alkalmazása. A fólia azonban a telepítés vagy üzemeltetés során megsérülhet, utat engedve a szennyező anyagokat tartalmazó csurgalékvíznek a védendő környezet felé. A környezet biztonsága érdekében célszerű tehát olyan ellenőrző rendszert kiépíteni, amely alkalmas a plasztikus szigetelő fólia vízzáróságának hosszú idejű ellenőrzésére. Ilyen ellenőrző rendszer a geoelektromos geofizikai módszeren alapuló szenzorhálózat alkalmazása. A módszer azon elven alapul, hogy a plasztikus szigetelő fólia elektromosan is szigetelő, megakadályozza az áramvezetést a medence anyaga és a környezet közt. A fólia sérülése esetén, a mindig jelenlévő nedvesség következtében áram folyhat a sérülésen keresztül a medence anyaga és a környezet közt. Ezen áramfolyások helyének kimérésével közvetve megtalálhatóak a fólia sérülési helyei. A módszer alkalmazásához, többnyire szabályos négyzetháló formájában, elektróda hálózatot (szenzor hálózat) telepítünk a plasztikus szigetelő fólia alá, amelyek a medence szélén elhelyezett csatlakozó dobozokhoz vezetünk ki. A hibahelyek feltárása, az aktuális geoelektromos viszonyok alapján megtervezett, geoelektromos geofizikai mérésekkel történik. A méréseredmények feldolgozásához, kiértékeléséhez és megjelenítéséhez számítógépes programokat veszünk igénybe. A rendszer tehát a következő három fő részből tevődik össze: -
Szenzorhálózat, kábelek, csatlakozó dobozok.
-
Geoelektromos geofizikai módszerek és műszerek.
-
Számítógépes feldolgozó, kiértékelő és megjelenítő programok.
A szenzor elektródák kábelkivezetéseit a medence szélén elhelyezett csatlakozó dobozokhoz vezetjük. Ezek IP56 tokozási besorolású műanyag dobozok, aranyozott, ipari Dsub csatlakozókkal. Egy csatlakozó dobozba általában maximum 4 darab 25 pólusú D-sub csatlakozó kerül, felváltva apa-anya-apa-anya csatlakozókkal. A szenzor kiosztási rajzon megadott szenzor számok értelemszerűen megfelelnek a csatlakozón feltüntetett kivezetés számokkal. Az első csatlakozó 1. számú érintkezője vezet az 1. számú szenzorhoz, és folytatólagosan, a második csatlakozó 1. számú kivezetése pedig a 26. számú szenzorhoz vezet, stb. A vezetékek a fólia alatt nem kapnak külön védelmet. A leszorító árkon keresztül bújó kábelkorbácsra flexibilis műanyag védelem kerül, a dobozhoz történő felállás pedig 40mm-es pvc védőcsőbe fut. A dobozt ¾”-os festett acélcső tartja, ami le van verve a talajba. A szenzorhálózat kiosztásának dokumentálását mutatja a következő példa. A szenzorok helyének és számának feltüntetése mellett szerepel a csatlakozó doboz helye is és a vezetékek nyomvonala.
Szenzorhálózat: NVCSS
25
20
15
10
5
6
12
18
24
30
36
5
11
17
23
29
35
4
10
16
22
28
34
3
9
15
21
27
33
2
8
14
20
26
32
1
7
13
19
25
31
0
5
10
15
20
25 m
Jelmagyarázat: 1
cs
Szenzor elektróda és sorszáma Csatlakozó doboz és jele Vezetékek nyomvonala
0
cs
A szenzorhálózat helyszínrajza a kábelkorbács nyomvonalával
A fólia hibák detektálása hibatérkép felvételével Amennyiben a plasztikus szigetelő fólián hibák vannak, a talajnedvesség folytán áramvezetés jön létre a hibahelyen keresztül, ha gerjesztést alkalmazunk a fólia két oldala között. Mivel a hiba általában pontszerűnek tekinthető, a hibahelyek feltárásánál a pontforrás modellt használhatjuk a potenciálkép értelmezéséhez. A hibahely környékén tehát olyan potenciáltér alakul ki, amely pontforrás jelleget képvisel, vagyis koncentrikus körökhöz hasonló képet mutat. A mérés végrehajtásához az egyik áramelektródát az altalajba helyezzük el, a vizsgált területtől viszonylag távol (végtelen forrás), míg a másik áramelektródát a medence anyagába, minél nagyobb területen (általában vonalforrás). A potenciálmérés referencia pontjául szintén távoli pontot választunk. A potenciált a szenzorhálózat pontjain mérjük. Ha az így mért potenciáltérképen kiugró, koncentrikus jellegű anomáliát látunk, az a fólia hibáját jelzi. Ezzel a módszerrel a szenzorhálózat raszter méretének megfelelő pontossággal állapíthatjuk meg a hiba helyét. Amennyiben a fólián több hiba is van, mindig a legnagyobb hibaáramot eredményező hiba (nem szükségképpen a legnagyobb méretű) jelentkezik a legnagyobb anomáliával. Ha a hibák egymáshoz közel vannak, azok hatása összemosódik. A nagyobb hibák anomáliái elfedhetik a kisebbek hatását. 2007. febr. 21.
Sz1415h4 140
120
100
80
20
0
0
36
64
67
40
74
90
0.5
-0.3
0.8
0.6
0.3
0.2
94
81 0.2
7
22
12
27
42
45
48
51
54
70
61
77
93
97
1.8
1.6
1.2
1.1
0.8
0.4
0
0.1
0.1
0.3
0.5
0.3
0.3
0.5
15
17
19
9
24
39
29
32
35
38
66
57
73
89
80
84
1.9
1.7
1.4
1
0.8
0.6
-0.5
-1.4
-0.5
-0.3
-0.4
0.3
0.5
-0.4
0.2 96
2
4
6
21
11
26
41
44
47
50
53
69
60
76
92
1.6
1.6
1.2
1.1
0.8
0.7
0.3
-0.8
-4.5
-0.8
0.1
0.2
-0.3
0.2
0.2
0
14
16
18
8
23
13
28
31
34
37
65
56
72
63
79
83
1.1
1.2
0.8
0.6
0.8
0.7
0.4
0.2
-0.5
-0.3
0.2
0.4
0.1
0.2
0.4
0.3
1
3
5
20
10
25
78
43
46
49
52
68
59
75
85
95
0.5
1
0.9
0.7
0.8
0.6
0.3
0.1
0.1
-0.1
-0.2
0.1
0.3
0.2
-0.5
12
18
96
0.8
40
33 0.6
1.8
6
60
30 1.1
24
30
36
42
48
54
60
66
72
78
84
90
0.6
0.6
0.6
0.5
0.4
0.3
-0.3
-2.5
-0.3
0.1
0.1
0.2
5
11
17
23
29
35
41
47
53
59
65
71
77
83
89
95
0.6
0.8
0.5
0.6
0.6
0.7
0.5
0.4
0.1
0.6
-0.7
-0.6
-0.3
0.2
-0.1
-0.7
4
10
16
22
28
34
40
46
52
58
64
70
76
82
88
94
0.6
0.5
0.5
0.5
0.6
0.5
0.6
0.6
0.1
0.1
-0.7
-1.8
-0.8
-0.4
-0.3
-0.4
3
9
15
21
27
33
39
45
51
57
63
69
75
81
87
93
0.4
0.7
0.4
0
0
0.3
0.6
0.4
0.4
0.1
-0.6
-2.1
-1.6
-0.3
-0.4
-0.6
80
86
92
-1
-4.5 91
2
8
14
20
26
32
38
44
50
56
62
68
74
0.5
0.5
0.4
0.4
0
0.4
0.4
0.4
0.5
0.2
-0.1
-0.2
0
1
7
13
19
25
31
37
43
49
55
61
67
73
79
85
0.5
0.5
0.4
0.5
0.4
0.4
0.4
0.6
0.6
0.4
0.3
0
-0.2
-0.3
-1.4
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
0.5
0.5
0.6
0.5
0.7
0.7
0.6
0.6
0.5
0.6
0.4
0.4
0.3
0.1
-0.7
-2.2
20
40
60
80
A hibatérkép
100
120
140
160
A mérések műszere A fent ismertetett mérésekhez, az indukciós vezeték nyomvonal követés kivételével egyenáramú geofizikai mérőműszer szükséges. A fenti feladatokra speciáliisan kifejlesztett mérőműszer a GeoPic-100, saját fejlesztésű általános, 100 csatornás, egyenáramú mérőműszer. A műszer a geofizikai gyakorlatba széles körben elterjedt un. „kvázi egyenáramú” berendezés. Ez azt jelenti, hogy az alacsony frekvenciás gerjesztést pólusváltásokkal valósítja meg. A beépített akkumulátora segítségével, DC-DC konvertere több száz voltos egyenfeszültséget állít elő, amely polaritását félvezető híd biztosítja. A galvanikusan elválasztott vevő rész, a zavaró hálózati és nagyfrekvenciás zavarok kiszűrése után nagy érzékenységgel képes az elektródák közti potenciálkülönbség mérésére. A gerjesztési és mérési periódusidők széles határok közt programozhatók. Több mérés eredményéből, súlyozott átlagolás után szolgáltatja a méréseredményt. A műszerbe beépítésre került egy 100 csatornás kapcsoló egység, amely lehetővé teszi a szenzorhálózatok automatikus mérését. A műszert működését Microchip gyártmányú, 8 bites RISC mikrovezérlő felügyeli. Grafikus LCD kijelzővel és fólia billentyűzettel rendelkezik.
A Geoelectro Geofizikai Monitoring Rendszer műszere
A fejlesztendő program A program a Visual Studio 2013-as fejlesztőkörnyezetben készült, C# nyelven. Erre a környezetre és nyelvre azért esett a választás, mert a széles körben elterjedt .NET keretrendszerre épül, így a Windows operációs rendszerrel ellátott készülékek bármelyikén futtatható. A program képes soros porton kommunikálni, arra utasítást kiadni, arról eredményeket visszaolvasni, a visszaolvasott eredményeket eltárolni, és a kívánt jelalakokat kirajzolni, mely által teljesíti a vele szemben támasztott követelményeket. A fejlesztendő program egy ablakból áll, melyen található egy „Measure” feliratú nyomógomb, egy szövegmező, és egy rajzmező.
A program felhasználói felülete
A program indulásakor inicializál egy soros portot előre definiáltan a COM1 néven, és beállítja a Baudrate-et 19200-as értékre, majd vár a felhasználóra. A „Measure” gomb megnyomásakor kapcsolatba lép a mérőműszerrel, a soros porton keresztül. (Mivel jelenleg nincs timeout védelem, a soros porton a műszernek bekapcsolva kell lennie, különben a program lefagy.) A program elküldi karakterenként a #X parancsot, melyet egy kocsi vissza karakterrel lezár. Minden egyes karaktert a küldés után visszaolvas a portról. Ezzel biztosítja, hogy a műszer befogadta az adott karaktert, és fel is tudta dolgozni. A mérési utasítás átvétele után a műszer megkezdi a mérést, majd a mért adatokat kiküldi a soros portra, melyet a mérésvezérlő program kiolvas onnan. A mért adatok a következők:
•
NS: gerjesztés bekapcsolásakor hány mintát vesz
•
NO: gerjesztés kikapcsolásakor hány mintát vesz
•
NI: hányszor ismétel
•
TD: gerjesztés bekapcsolása utáni késleltetés ideje
•
GA: erősítés
•
RO: fajlagos ellenállás
•
VS: az elektródán mérhető természetes potenciál
•
MN: M és N elektróda közötti körellenállás
•
AB: A és B elektróda közötti körellenállás
•
VM: gerjesztő feszültség
•
IT: kifolyó áram
•
IP: pozitív gerjesztéshez tartozó áram
•
IN: negatív gerjesztéshez tartozó áram
•
VD: MN-en mért feszültség
•
VP: pozitív mért feszültség
•
VN: negatív mért feszültség
•
V[]: a gerjesztés alatt mért feszültség pillanatnyi értéke
•
I[]: a gerjesztés alatt mért áram pillanatnyi értéke
A program a kiolvasás után a mért értékeket kiírja a szövegmezőbe, utána kiírja a mérés elkezdésének idejét, a mérés befejezésének idejét, majd a kettő különbségét. Végezetül egy „OK!” karaktersorral lezárja a kiírást jelezvén, hogy idáig eljutott a program, és minden rendben ment. A kiírások után a rajzmezőbe a program kirajzol egy vízszintes vonalat, mint időtengely, majd a V[] és I[] tömbökből visszaolvassa a mért értékeket, és azok alapján megrajzolja a feszültség és áram jelalakokat, az feszültséget kék, az áramot piros színnel.
Az elkészült program A program az objektum orientált szemléletnek megfelelően készült, három osztályt tartalmaz, melyek a SerialController, MainForm és a Measure osztályok. A SerialController osztály felelős a soros port kezelésért, melybe beletartozik a portok létrehozása, a rendelkezésre álló COM portok lekérdezése, a portok megnyitása, és bezárása, illetve azok erőforrásának felszabadítása. A MainForm valósítja meg a grafikus felhasználói felületet, tartalmazza a szükséges mezőket, és gombokat, illetve az azokhoz tartozó metódusokat. Az érdekesebb metódusok közé tartozik az UpdateGraph, mely minden mérésnél a gerjesztő feszültség és áram jelalakokat rajzolja ki. Ezen metódus kódja a fejlesztendő programból származik. Másik metódus a MeasureAll, mely a mérési sorozatot vezényli le. A btnOpenFile_Click metódus szerepe a szenzorfájl megnyitása és tartalmának megfelelő beolvasása. A Measure osztály felelős egy darab elemi mérés végrehajtásáért, a Start metódusban található kód nagy része a fejlesztendő szoftverből származik. A Start metódus felel a mérőegységgel való kommunikációért, a mérési utasítás kiadásáért, és a mért értékek átvételéért.
Osztályok és metódusaik
A szoftver tartalmaz szálkezelést is, amíg a mérés fut, a felhasználói felülethez szabadon hozzá lehet férni. A jelen verzióban ezt a tulajdonságot még nem lehet kihasználni, de ez adja az alapját, hogy később, mérés közben paramétereket lehessen állítani a mérési környezettől függően.
Felhasználói felület A GUI egyszerűen áttekinthető egy ablakos felület, mely három fő részre tagolódik: A beállítást és kezelést lehetővé tévő gombokra és mezőkre, az adatmezőre, és a grafikonmezőre.
A program felhasználói felülete
A Vezérlés címszó alatt lehet megadni, hogy a kapcsoló, illetve a mérő egység mely portokat használja. Azért szükséges két portot is kiosztani, mert habár egy házba van integrálva a mérő- és a kapcsolóegység, a modularitás érdekében a kapcsoló egységnek önállóan kell tudni működni. Így lehetővé válik újabb vagy régebbi generációs mérőegységekkel való együttműködés is. Az „Open File” gombra kattintva előugrik egy fájlkiválasztó ablak, mely segítségével elnavigálhatunk, és megnyithatjuk a kívánt szenzorfájlt. A „Measure” gombbal indíthatjuk a mérési sorozatot, mely ha sikeresen lefutott, egy „All sensor measured!” feliratú ablak ugrik fel. Sikeres mérés után válik elérhetővé az addig kikapcsolt „Save” gomb, melynek megnyomásával menthetjük a mérési sorozat eredményeit a kívánt helyre, a kívánt néven. Az adatmezőbe kerül beírásra a kiolvasott szenzorfájl tartalma. Ez nem más, mint soronként az egyes szenzorok x és y koordinátája és sorszáma. A mérési sorozat indulásakor az adatmező törlődik, és soronként megjelenik az egyes szenzorokhoz tartozó x és y koordináta, a sorszám, és a két legfontosabb mért adat: a fajlagos ellenállás, és az M-N elektródák közötti körellenállás. A grafikonmezőbe kerülnek kirajzolásra mérésenként a gerjesztő feszültség és áram jelalakok, a feszültség kék, az áram piros színnel. A kirajzolás lehetővé teszi a mérést végző személynek a mérést gátló esetleges hibaokok, zavarok feltárását.
Működés A program a szenzor fájl megnyitása és a megfelelő beállítások elvégzése után mérésre kész állapotban van. A mérési sorozat indulásakor sor kerül a beállítások vizsgálatára, hogy ténylegesen lehet e hibamentesen mérni. Ezután létrehoz egy szálat, melyben a méréssel kapcsolatos teendőket végzi, eközben lehetőséget adva a felhasználónak a mindenkori beavatkozásra. A mérési szálban korlátozásra kerülnek azok a beállítási lehetőségek, melyek változtatása hibát okozna. Ezek tipikusan a mérő- és kapcsolóegységekhez választható COM portok, illetve a „Measure” gomb, hiszen értelemszerűen nem jó, ha újra indítunk egy mérést, miközben már folyamatban van. Ezek után a portok inicializálása történik, majd indul a mérési sorozat. A mérési sorozat annyi mérési pontból áll, ahány sora van a szenzor fájlnak. A hátralevő mérési pontok számát folyamatosan nyomon lehet követni a „Measure” gomb felett. Minden mérési pontban két mérés történik, a vezérlő szoftver ezen mérések eredményét összeveti, és ha a mért fajlagos ellenállások egy konstans 0.5-nél nagyobb eltérést mutatnak, akkor megismétli a két mérést annál a mérési pontnál. Ha az eltérés háromszor is meghaladja a beállított értéket, akkor a mérés eredményének a double változóban eltárolható maximális érték lesz beírva, melyből azonnal kiderül, hogy ott hibás érték szerepel. Ha a két mérés eltérése nem haladja meg az előírt értéket, akkor a mért eredmények átlagolt értéke kerül eredményként beírásra. A mérési sorozat elvégzése után az „All sensor measured!” ablak jelenik meg, és a letiltott vezérlési lehetőségek újra állíthatóak lesznek. Ezen kívül a Save gomb is engedélyeződik.
A program működés közben
A mérési sorozat működési diagramja
Hibakezelés Ahhoz hogy az emberi hibák jelentős részét ki tudjuk szűrni, néhány hibakezelési funkciót is be kellett tenni a programba. A program a mérés megkezdése előtt kettő alapvető hibára tesztel: van e szenzorfájl betöltve, ami alapján lehet mérni, és nincs e ugyanaz a COM port hozzárendelve a kapcsolóműhöz, és a mérőegységhez is. Ezen kívül még képes kezelni, és jelezni, ha nincs bedugva, vagy mérés közben szétcsúszna a soros kábelcsatlakozó. A fejlesztendő programmal ellentétben ilyenkor nem fagy le a szoftver.
Hibakezelés: Nincs szenzorfájl betöltve
Hibakezelés: Mindkét eszköz ugyanazt a COM portot használja
Hibakezelés: COM port nincs bedugva
Tesztelés A program feladata, hogy a kapcsolóegységet, és a mérőegységet megfelelő ütemben működtesse. Tudjon mérési sorozatot indítani, azt befejezni, az eredményeket elmenteni, illetve mérés közben a kapcsolóművet vezérelni. A tesztelés első fázisa ezen feladatok ellátásának ellenőrzése volt laborkörülmények között, szimulált bemeneti jelekkel ún. mérőföld segítségével. Ezen szakaszban az összes mérés szinte ugyan azokat az értékeket adta, így a zavarszűrést nem lehetett kipróbálni. Amikor a program az első fázisban tesztelt funkciókat sikerrel ellátta, valós körülmények között, próbarendszeren lett tesztelve. A Geoelectro Kft. területén kiépítettem egy 25 elektródából álló próbarendszert. Ezek után kitelepítettem a méréshez szükséges segédelektródákat, és összeállítottam a mérőműszerből, kapcsolóműből és mérésvezérlő számítógépből álló mérőrendszert. A teszt szenzorfájl megírása és betöltése után végeztem a próbamérést, melynek eredménye, hogy a beállított konstans az adott körülményekhez képest megfelelő volt, nem akadályozta a mérést, mivel nem voltak olyan mértékű véletlen zavarjelek, melyek indokolták volna a mért értékek nagy eltérését. Mivel a tesztelésnél a program fejlesztőkörnyezete nem állt rendelkezésre, az előre beállított konstans értékét nem tudtam állítani, hogy megnézzem mi a legalacsonyabb használható érték. (További fejlesztési lehetőség, hogy ezen küszöbértéket a kezelőfelületről tetszés szerint lehessen módosítani.)
A 25 db mérőelektródából álló próbarendszer
A mérőrendszer
USB - RS485 interfész A geoelektromos szenzorrendszerrel kapcsolatban felmerülhet olyan igény, hogy naponta vagy akár kisebb időközönként történjen a rendszeren mérés. Ez főleg akkor indokolt, ha a lerakó frissen épült, és még vékony a medence alján lévő szemétréteg, vagy ha nagyon nagy kiterjedésű rézsűt tartalmaz. Ekkor a kompaktor könnyen okozhat sérülést a fólián, melyet ha csak jóval, akár egy évvel később mutat ki a soron következő mérés, a hibajavítási költség nagyon meg tud ugrani a megvastagodott szeméttest miatt. Ezen igényeket elégíti ki a Geoelectro Kft. által forgalmazott automata mérőrendszer, mely a szenzorok telepítését követően kerül kihelyezésre és beüzemelésre.
Az automata mérőrendszer vázlata
A rendszer a csatlakozódobozokban elhelyezett kapcsolópanelekből, egy külön dobozba kihelyezett mérőműszerből, egy soros – vezeték nélküli (ism, bluetooth, gprs) kommunikációs interfészből, a fogadó oldalon az ellen párjából, és egy adatgyűjtő PC-ből áll. A rendszer beüzemelésekor nehéz az adatgyűjtő PC-ről elhárítani az esetleges hibákat, a vezeték nélküli kommunikációs szakasz miatt. Ezért felmerült az igény egy olyan interfész megvalósítására, mely segítségével a mérésvezérlő műszerhez közvetlen, vezetékes úton is hozzá lehet férni. Ekkor viszont nagyon fontos, hogy az interfész tartalmazzon galvanikus leválasztást, mert a kitelepített mérőmű akkumulátorának negatív kivezetése, és a PC védőföldje nem kerülhet összeköttetésbe. Továbbá a PC védőföldje a méréskor is komoly hibát okozna. A galvanikus leválasztás optocsatolókkal lett megvalósítva. A TXEN vonal egyszerű, míg az adatvonalak nagy sebességű optocsatolókkal lettek leválasztva, hogy a kommunikáció sebességét követni tudják. Az interfész a vezetékes soros RS!(% kommunikáción kívül még képes beilleszkedni a fenti ábrán látható rendszerbe oly módon, hogy rendelkezik egy RS232 kommunikációs vonallal is, melyen a vezeték nélküli kommunikációs vevő egységgel tudja tartani a kapcsolatot. Ez által lehet tetszés szerint közvetlenül vagy a vezeték nélküli kommunikációt magába foglaló kapcsolatot teremteni a
mérőegységgel. Ez a kettősség teszi lehetővé a rendszer beüzemelésekor esetlegesen felbukkanó hibák kiszűrését kezelését és megoldását.
Az automata mérőrendszer USB – RS485 interfésszel kiegészített vázlata
Az elkészült USB – RS485 interfész
Labortevékenységem során dokumentálási és alkatrész beültetési munkákat végeztem az eszköz fejlesztése során.
Mellékletek 1. melléklet: A program forráskódja MainForm.cs using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Globalization; using System.IO; using System.Linq; using System.Text; using System.Threading; using System.Windows.Forms; using SerialPortDemo.Control; namespace SerialPortDemo { struct SensorAttr { public int id; public double x, y; public SensorAttr(double x, double y, int id) { this.id = id; this.x = x; this.y = y; } } public partial class MainForm : Form { private SerialController controllerMeas controllerSwitch = new SerialController();
=
new
SerialController(),
private List<SensorAttr> allSensorAttr = new List<SensorAttr>(); private double[] mnRes, ro; private int mpLeft; bool stopThread, measureThreadReady;
Thread measureThread; Bitmap bmpGraph; Graphics gGraph; public MainForm() { InitializeComponent(); CheckForIllegalCrossThreadCalls = false; bmpGraph = new Bitmap(ptbGraph.Size.Width, ptbGraph.Size.Height); gGraph = Graphics.FromImage(bmpGraph); gGraph.Clear(Color.White); ptbGraph.Image = bmpGraph; } private string SelectedMeasPort { get { return cbPortListMeas.Text.Trim(); } } private string SelectedSwitchPort { get { return cbPortListSwitch.Text.Trim(); } } private void MainForm_Load(object sender, EventArgs e) { try { //controller.DataReceived EventHandler<SerialDataEventArgs>(controller_DataReceived); PopulateData(); } catch (Exception ex) { DisplayError(ex.Message);
+=
new
Application.Exit(); } } private void MainForm_FormClosing(object sender, FormClosingEventArgs e) { stopThread = true; if (measureThread != null) { while (measureThread.IsAlive) ; } controllerMeas.ClosePort(); //Kapcsolómű: controllerSwitch.ClosePort(); } private void PopulateData() { cbPortListMeas.DataSource = controllerMeas.PortList; cbPortListSwitch.DataSource = controllerSwitch.PortList; } private void UpdateGraph() { Measure.dx = ptbGraph.Width / Measure.n;
//PictureBox
szélessége/n Measure.dy = 0.1905f; magassága/20000
//381 / 2000 -> Picturebox
Measure.yz = 190; gGraph.Clear(Color.White); gGraph.DrawLine(Pens.Black, 0, Measure.yz, ptbGraph.Width, Measure.yz); int k; for (k = 0; k <= Measure.n - 2; k++) { gGraph.DrawLine(Pens.Blue, k * Measure.dx, 190 - (Measure.v[k] - 2047) * Measure.dy, (k + 1) * Measure.dx, 190 - (Measure.v[k + 1] - 2047) * Measure.dy); } for (k = 0; k <= Measure.n / 2 - 2; k++) { gGraph.DrawLine(Pens.Red, k * Measure.dx, 190 - Measure.i[k] *
Measure.dy, (k + 1) * Measure.dx, 190 - Measure.i[k + 1] * Measure.dy); } gGraph.DrawLine(Pens.Red, (k) * Measure.dx, 190 - Measure.i[k] * Measure.dy, (k + 1) * Measure.dx, 190 + Measure.i[k + 1] * Measure.dy); for (k = Measure.n / 2; k <= Measure.n - 2; k++) { gGraph.DrawLine(Pens.Red, k * Measure.dx, 190 + Measure.i[k] * Measure.dy, (k + 1) * Measure.dx, 190 + Measure.i[k + 1] * Measure.dy); } ptbGraph.Refresh(); } private void MeasureAll() { btnMeasure.Enabled = false; cbPortListMeas.Enabled = false; cbPortListSwitch.Enabled = false; tbPortData.Clear(); try { controllerMeas.OpenPort(SelectedMeasPort); //Kapcsolómű: controllerSwitch.OpenPort(SelectedSwitchPort); Measure.port = controllerMeas.Port; mnRes = new double[allSensorAttr.Count]; ro = new double[allSensorAttr.Count]; mpLeft = allSensorAttr.Count; int tmpInt; for (int i = 0; i < allSensorAttr.Count && !stopThread; i++) { //A következő két sort élesíteni controllerSwitch.Port.Write(new byte[] { (byte)(129 + i) }, 0, 1); tmpInt = controllerSwitch.Port.ReadByte(); bájtot a soros portról //Ez csak teszteléshez van // tmpInt = 129 + i;
//kiolvas egy
double ro1, ro2; for (int j = 0; j < 3; j++) { Measure.Start(); UpdateGraph(); mnRes[i] = Measure.mn; ro1 = Measure.ro; Measure.Start(); UpdateGraph(); ro2 = Measure.ro; if (Math.Abs(ro1 - ro2) <= 0.5) //nem biztos, hogy 0.5 { ro[i] = (ro1 + ro2) / 2; break; } else { ro[i] = double.MaxValue; } } Interlocked.Decrement(ref mpLeft); labelMeasurePoints.Text = "Measure Points Left: " + mpLeft; tbPortData .Text += allSensorAttr[i].x + ", " + allSensorAttr[i].y + ", " + allSensorAttr[i].id + ", " + mnRes[i] + ", " + ro[i] + Environment.NewLine; } controllerMeas.ClosePort(); stopThread = false; measureThreadReady = true; btnSave.Enabled = true; MessageBox.Show("All sensor measured!"); } catch (Exception ex) { DisplayError(ex.Message); controllerMeas.EmptyBuffers(); //Kpcsolómű: controllerSwitch.EmptyBuffers();
} btnMeasure.Enabled = true; cbPortListMeas.Enabled = true; cbPortListSwitch.Enabled = true; } private void btnMeasure_Click(object sender, EventArgs e) { if (allSensorAttr.Count < 1) { MessageBox.Show("Nincs file betöltve!"); return; } if (SelectedMeasPort == SelectedSwitchPort) { MessageBox.Show("A kapcsolómű és a mérőműszer nem használhatja ugyan azt a portot!"); return; } stopThread = false; measureThreadReady = false; measureThread = new Thread(new ThreadStart(MeasureAll)); measureThread.IsBackground = true; measureThread.Start(); while (!measureThread.IsAlive) ; } /*private void controller_DataReceived(object sender, SerialDataEventArgs e) { this.Invoke((MethodInvoker)delegate { tbPortData.AppendText(e.Data); }); }*/ private void DisplayError(string message) { MessageBoxIcon.Error);
MessageBox.Show(message,
"Hiba!",
MessageBoxButtons.OK,
} private void btnOpenFile_Click(object sender, EventArgs e)
{ DialogResult dialogResult = openFileDialog.ShowDialog(); if (dialogResult == DialogResult.OK) { string fileName = openFileDialog.FileName; string line; StreamReader file = new StreamReader(fileName); tbPortData.Clear(); while ((line = file.ReadLine()) != null) { string[] s = line.Split(','); CultureInfo.InvariantCulture), Convert.ToInt32(s[2]));
SensorAttr sd = new SensorAttr(double.Parse(s[0], double.Parse(s[1], CultureInfo.InvariantCulture),
allSensorAttr.Add(sd); Environment.NewLine;
tbPortData.Text += sd.id + ", " + sd.x + ", " + sd.y +
} file.Close();
allSensorAttr.Count;
labelMeasurePoints .Text
=
"Measure
Points
Left:
"
+
} } private void saveFileDialog1_FileOk(object sender, CancelEventArgs e) { string fileName = saveFileDialog.FileName; TextWriter tw = new StreamWriter(fileName); for (int i = 0; i < allSensorAttr.Count; i++) { tw.WriteLine(allSensorAttr[i].x + ", " + allSensorAttr[i].y + ", " + allSensorAttr[i].id + ", " + ro[i] + ", " + mnRes[i]); } tw.Close(); } private void button1_Click(object sender, EventArgs e) {
saveFileDialog.ShowDialog(); } } }
SerialController.cs using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.IO.Ports; namespace SerialPortDemo.Control { public class SerialController : IDisposable { private SerialPort port; public SerialPort Port { get { return port; } } //public event EventHandler<SerialDataEventArgs> DataReceived; //public string LastError { get; private set; } public SerialController() { } public string[] PortList { get { return SerialPort.GetPortNames(); } } public bool IsOpen
{ get { if (port == null) return false; return port.IsOpen; } } public void OpenPort(string portName) { if (IsOpen) throw new ApplicationException("Port is already open!"); port = new SerialPort(portName); port.BaudRate = 19200; port.ReadTimeout = 1000; port.WriteTimeout = 1000; port.Open();
SerialDataReceivedEventHandler(port_DataReceived);
//port.DataReceived
+=
new
} public void ClosePort() { if (port != null) port.Dispose(); } public void EmptyBuffers() { port.DiscardInBuffer(); port.DiscardOutBuffer(); } public void Dispose() { ClosePort(); } /*private void port_DataReceived(object sender, SerialDataReceivedEventArgs e)
{ try { string data = port.ReadExisting(); if (DataReceived != null) { SerialDataEventArgs eventArgs = new SerialDataEventArgs() { Data = data }; DataReceived(this, eventArgs); } } catch (Exception ex) { LastError = ex.Message; } }*/ } }
Measure.cs using System; using System.Collections.Generic; using System.Linq; using System.Globalization; using System.Text; using System.IO.Ports; namespace SerialPortDemo { struct ReceivedData { } static class Measure { public static SerialPort port; public static string sResults; public static double ro, mn;
//ez a szöveg formátumú kimenet
public static int n; public static float dx, dy, yz; public static float[] v = new float[1025], i = new float[1025];
public static void Start() { int rx = 0; string ns; string no; string ni; string td; string ga; string le1; int nsInt; int noInt; int niInt; int[] t = new int[1025]; string le2; object vs; object ab; object vm; object it; object jp; object jn; object vd; object vp; object vn; string le3; DateTime time = new DateTime(); int start; int sztop; float diff; sResults = ""; try
{ port.Write("#"); rx = port.ReadByte();
//kiolvas egy bájtot a soros portról
sResults += Convert.ToChar(rx); port.Write("X"); rx = port.ReadByte(); sResults += Convert.ToChar(rx); port.Write(Convert.ToString(Convert.ToChar(13))); // a 13-nak megfeleló karaktert írja ki a portra rx = port.ReadByte(); sResults += Convert.ToChar(rx); egy string
ns = port.ReadTo(",");
//ns kiolvasása, míg ,-t nem talál, ns
no = port.ReadTo(",");
//no kiolvasása, míg ,-t nem talál
ni = port.ReadTo(",");
//ni kiolvasása, míg ,-t nem talál
td = port.ReadTo(",");
//td kiolvasása, míg ,-t nem talál
ga = port.ReadTo(",");
//ga kiolvasása, míg ,-t nem talál
le1 = port.ReadTo(Convert.ToString(Convert.ToChar(13))); olvas a prtról, amíg /r karaktert nem kap
//addig
sResults += "ns="; sResults += ns; sResults += ", no="; sResults += no; sResults += ", ni="; sResults += ni; sResults += ", td="; sResults += td; sResults += ", ga="; sResults += ga; sResults += Environment.NewLine; //sortörés+kocsivissza kiírása a
ritch text boxba
nsInt = Convert.ToInt32(ns);
//ns konverziója Int32-re
noInt = Convert.ToInt32(no); niInt = Convert.ToInt32(ni); n = (nsInt + noInt) * niInt * 2; sResults += n; sResults += Environment.NewLine; time = DateTime.Now; start = time.Second * 1000 + time.Millisecond; for (int k = 0; k <= n - 1; k++) { v[k] = Convert.ToSingle(port.ReadTo(",")); //olvas soros portlól amíg ,-t nem talál, azt konvertálja float-ba, és az lesz v[] tömb k-adik eleme
//sResults += v[k]; //sResults += ", "; i[k] = Convert.ToSingle(port.ReadTo(",")); //sResults += i[k]; //sResults += ", "; } time = DateTime.Now; sztop = time.Second * 1000 + time.Millisecond; le2 = port.ReadTo(Convert.ToString(Convert.ToChar(13))); sResults += Environment.NewLine; ro = double.Parse(port.ReadTo(","), CultureInfo.InvariantCulture); vs = port.ReadTo(","); mn = double.Parse(port.ReadTo(","), CultureInfo.InvariantCulture); ab = port.ReadTo(","); vm = port.ReadTo(","); it = port.ReadTo(","); jp = port.ReadTo(","); jn = port.ReadTo(","); vd = port.ReadTo(","); vp = port.ReadTo(","); vn = port.ReadTo(","); le3 = port.ReadTo(Convert.ToString(Convert.ToChar(13))); sResults += "ro="; sResults += ro; sResults += ", vs="; sResults += vs; sResults += ", mn="; sResults += mn; sResults += ", ab="; sResults += ab; sResults += ", vm="; sResults += vm; sResults += Environment.NewLine; sResults += "it="; sResults += it; sResults += ", ip="; sResults += jp; sResults += ", in="; sResults += jn; sResults += Environment.NewLine; sResults += "vd="; sResults += vd; sResults += ", vp=";
sResults += vp; sResults += ", vn="; sResults += vn; sResults += Environment.NewLine; sResults += start; sResults += Environment.NewLine; sResults += sztop; sResults += Environment.NewLine; diff = sztop - start; sResults += diff; sResults += Environment.NewLine; sResults += "Ok!"; sResults += Environment.NewLine; } catch (Exception ex) { sResults += "Error: " + ex.Message; throw ex; } } } }
2. melléklet: az USB – RS485 interfész kapcsolási rajza