Tartalom:
- Légnyomás mérés mértékegységei, szenzor által szolgáltatott adatok értelmezése
- Wheatstone-hidas mérési mód magyarázata, belső felépítés
- Programkönyvtár letöltése
- A HX711 analóg/digitál átalakító működése, elemi parancsai
- Vízszint mérés visszavezetése légnyomásmérésre, bemutató program
Forrás:https://win.adrirobot.it/sensori/MPS20N0040D/MPS20N0040D_pressure_sensor.htm
A feladat az volt, hogy egy kútban található vízszintet mérjem meg. A gyűrűs kutakban a víz összegyűlik a környező területen található vizekből. Ezt a locsolásra hasznát szivattyú kiszívja. Általában lassabban telik meg a kút, mint amilyen gyorsan a szivattyú kiüríti a vizet, és szerettem volna látni, mi is zajlik ott alul. Az elképzelés szerint egy nyitott végű szilikon csövet engedek le a kút legaljára, a cső másik végét pedig a szenzorhoz csatlakoztatom. Amikor a vízszint növekszik a kútban, a szilikon csőben is egyre magasabbra hatol felfelé a víz, és összenyomja a felette lévő levegőt, aminek így nőni fog a nyomása. Az elv egyszerű, és ez az eszköz alkalmasnak látszik a feladatra.
Műszaki adatai:
Méret: 19 * 18mm (2mm rögzítőfurat)
Feszültség: 3,3–5 V
Nyomás: 0-5,8psi (0-40KPa)
Kimenet: 24 bites ADC
Az eszköz adatlapján psi-ban megadott nyomásértéket nem értem. Az egyes nyomás mértékegységek átszámítására szolgáló táblázatok szerint az 5,8 psi meglehetősen alacsony légnyomás. Azonban a 40KPa (kilopascal) sem stimmel, mert a normál légköri nyomás 100KPa nyomásnak felel meg, bár ezek a légnyomás értékek szinkronban vannak egymással. Lehetséges, hogy a megadott határok nyomás változásra vonatkoznak?? Ezért kicsit utána számoltam, mit is fog ez az eszköz mérni. A mérést nyitott érzékelő csővel szabad levegőn (normál légköri nyomáson) csináltam. A légköri légnyomást inkább a milibár mértékegységben szoktuk használni. A tengerszinten mérhető normál légköri nyomás 1013,25 mbar (1,01325 bar).
A netről sikerült kiderítenem, hogy 1 bar =14,504 psi!
Az eszköz adatlapjaiból nem sikerült egyértelműen kiderítenem, hogy milyen értéket lehet kiolvasni a 24 bites A/D konverter kimenetéből normál légköri nyomás esetén, ezért egyszerűen megmértem. Egy adott pillanatban az általam mért adat 1421158. Ránézésre ez majdnem pont 10000-szer akkora, mint az egy bar nyomás psi-ben megadott értéke. Mivel volt nálam egy légnyomásmérő (BMP180), annak értékét is meg tudom adni, éppen 998mbar értéket mutatott. Ezért feltételezem, hogy a szenzorból kiolvasott adat psi-ben adta meg az aktuális légköri nyomást. Mivel nem tengerszinten voltam, a kapott adatnak kisebbnek kell lennie, mint a tengerszinten mérhető normál légköri nyomásnak, így ez akár igaz is lehet.
Ellenőrizzük le:
14,31158 psi /14,50400 psi =0,986733 (mért nyomás/tengerszinten mért nyomás)
1013,25 mbar x 0,986733 = 999,8 mbar
Igen nagy eséllyel valóban az én lakhelyemen éppen aktuális légnyomást mutathatta az eszközből kiolvasott érték (Kistarcsán lakom, ami magasabban van mint a tengerszint, így kisebb a légnyomás). Az is lehet, hogy ez csak véletlen, de szándékos tervezés eredménye is lehet. A légnyomást úgy kaphatjuk meg az eszközből kiolvasott értékből, hogy megszorozzuk 0.0689475729-al (átváltó programból olvastam ki), és osztjuk 10000-el. Ez 986mbar, ami jóval kevesebb mint amit feljebb számoltam ki, de nincs mihez hasonlítanom, csak egy másik nyomásmérőhöz, ami pontosabb és pontatlanabb értéket is adhatott! Tehát elfogadtam, hogy a kiolvasott adat a lakóhelyemen a nyomás pillanatnyi értéke a PSI-ben, illetve annak 10000 szerese.
Sajnos csak egy szenzorom volt, így nem tudtam kipróbálni, hogy ez a gyári beállítás mennyire azonos két szenzor példányon.
Az érzékelőn belül egy ellenállásokból kialakított Wheatstone-híd található:
A belső szerkezetről nincs információm, de feltételezem, hogy az ellenállások egy membrán felületén lettek kialakítva. A membrán a nyomás hatására változtatja az alakját, és így megváltozik az ellenállások értéke is. A Wheatstone híd működési elvéből adódóan nagyon kicsi ellenállás változás hatására is jelentős feszültség változással reagál. Valahol olvastam, hogy ebben a szenzorban 0-25 mV feszültség változás keletkezik a teljes mérési tartományban.
Ez annyira kicsi jel, hogy közvetlenül nem mérhető. Így került a szenzor mellé egy HX710-es jelerősítő és nagy felbontású A/D átalakító. Adatlapja szerint 128-szoros erősítő van benne, és az A/D felbontása 24bites. Nem véletlen a 128-szoros erősítés: 128 x 25mV = 3200mV. Ha 3,3V tápfeszt adunk az ADC-nak, akkor még éppen kisebb a mérendő feszültség, mint a tápfeszültség. Így néz ki a kapcsolás:
Akkor most nézzük meg, hogyan is lehet Arduino-val használni a szenzort. Pofon egyszerű, mert van hozzá több könyvtár is. Írjuk be a könyvtár kezelőbe a HX711 nevet (ez az ADC típusjelzése), és a következő találatokat kapjuk:
Azt, hogy miért nem a HX710 névre kerestünk, az eredeti cikk írójától érdemes megkérdezni, de az biztos, hogy arra chip-re, amit beépítettek az áramkörbe, az Arduino könyvtár kezelője semmit nem dob ki. Viszont a HX711 ugyanazt csinálja, ezért ez bennünket nem zavar. Én rögtön a legelsőt választottam. A könyvtár telepítése után kapunk példa programokat:
Ez itt azonban már az általam kialakított verzió, amivel légnyomást mértem:
#include "HX711.h" const int LOADCELL_DOUT_PIN = 2; const int LOADCELL_SCK_PIN = 3; HX711 scale; void setup() { Serial.begin(9600); scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN); scale.set_scale(1431.f); } void loop() { if (scale.is_ready()) { long meres = scale.read(); Serial.print("HX711 reading: "); Serial.println(meres); } else { Serial.println("HX711 not found."); } delay(2000); }
Láthatóan nem egy bonyolult program. A kiválasztott könyvtár alapvetően egy mérleg számára készült. A mérlegekben nyúlásmérő ellenállásokat alkalmaznak, és feltehetőleg ugyanezt az ADC chipet. Nekem már annyi is bőven elég amit ebben a programban találtam, de a teljesség érdekében a dokumentációból és részben a könyvtár forráskódjából még kiderült néhány függvény, ami hasznos lehet.
A mérlegek többféle mértékegységben is működnek, így a mért értéket skálázni kell, valamint meg kell határozni egy olyan mérési eredményt, amit üresen mérünk (a mechanika súlya üresen), amihez a 0 súly kijelzése tartozik. Ezeket az adatokat tapasztalati úton a kész szerkezettel történő mérésekkel lehet legegyszerűbben meghatározni (hitelesítés), és beégetni a programba.
Ehhez találunk néhány függvényt:
- scale.set_scale(x) beállítja a skála értékét. A megadott számmal osztja a mérés eredményét, de csak a scale.get_unit() függvény által visszaadott értékben
- scale.get_scale() Visszaadja a beállított skála értéket
- scale.set_offset(x) Beállítja az offset értéket, a scale.get_value() függvény által visszadott értéket úgy állítja elő, hogy a mért értékből kivonja az itt beállított értéket.
- scale.get_offset() Visszaadja a beállított offset értéket
Mérési eredmények lekérdezésére szolgáló függvének:
- scale.read() Elvégez egy mérést és visszaadja a mért értéket
- scale.read_average(x) Elvégez x db mérést és azok átlagát adja vissza
- get_value(x) Elvégez x db mérést és ezek átalgából levonja a beállított offset értéket
- get_units(x) Elvégez x darab mérést ezek átlagából levonja az offset értékét, majd a kapott adatot elosztja a skála értékével
Egyéb függvények:
- scale.tare(x) Elvégez x db mérést, és az így kiszámított átlagot beállítja offset értéknek (ez lesz a 0 érték a mérlegen, TÁRA mérleg funkció)
- scale.power_down() Alacsony fogyasztású módba kapcsolja a szenzort
- scale.power_up() Normál fogyasztású módba kapcsolja a szenzort
Vizszint mérő próbaprogram:
Következzen egy gyakorlati megvalósítás, tényleges vízszint mérés. Vettem egy méteres szilikon csövet. Tudjátok, az az átlátszó cső, amit különböző belső átmérővel lehet kapni. A legkisebb átmérő 2,5mm. Ez sajnos nekem még mindig nagy, mert a szenzoron kialakított csövecske 2mm-es. Ideiglenes megoldásként a szenzor csövére szikszalagot tekertem. Nem vált be, mert magától lecsúszott másnap reggelre, de az alábbi program kipróbálásához elég volt. Előkaptam egy kiürült üdítős üveget (lehetett volna vodkás üveg is, de nem iszom alkoholt). Megtöltöttem vízzel, ami pont 14cm vízmagasságot eredményezett. Azért ennyit, mert a feleségem törött műanyag vonalzója pont ilyen hosszú. Szóval betöltöttem az Arduino UNO-ra az alábbi program 0. verzióját, csak ott még nem voltak vízszint számítások, csupán a natúr nyomás érték. A működő programnál kaptam egy légnyomás értéket, ezt felírtam, és ledugtam a csövet 14cm mélységbe. A kapott adatot szemrevételeztem, és megállapítottam, hogy a nyomásmérő érzékenysége 10000-es nagyságrendeben változott. Szuper. Ezután már csak osztogatni kellett, és kialakult a program. A program elindításakor a cső szája maradjon szabadon, hogy legyen egy nulla vízszintet jelentő referencia értékünk. Itt már 1000-el osztottam, hogy áttekinthetőbb legyen a kapott adat. Integerre is alakítottam, mert így a kapott szám elég stabil lett, nem változott állandóan az utolsó egy-két számjegyben. Így a 14 cm mélységben pont 800-al nőtt a nyomás, tehát egy cm 57-nek adódik. Nem kell sokat agyalni rajta, ennyi és kész, bármit is jelent az 57. Arra számítok, hogy a kútba leeresztett kb. 12m-es cső esetén ez a konstans már nem 57 lesz, mert a cső térfogata a nagyobb hosszúság miatt lényegesen nagyobb és a levegő összenyomható. Így a végleges merőműszeremben egy kisebb számot kell majd megadni, de ez csak várakozás. Az bizonyos, hogy az 57 elég jó kiinduló alap.
Sajnos ennek a tapasztalati számnak a megmagyarázására nem vagyok képes. Az biztos, hogy az 1m-es csőben a levegőt kb 0,9-ed részére nyomtuk össze. Annyit tudunk még, hogy állandó hőmérsékleten a térfogat és a nyomás szorzata állandó. Ebből következik, hogy ha a térfogat a 0,9 szeresére csökken, akkor a nyomásnak ugyanilyen arányban nőnie kell. Így a kb. 14,504Psi normál légköri nyomás 14,504/0,9=16,115Psi-re nőtt volna meg. A növekedés elméletben 1,611Psi. A szenzor ennek a változásnak mint legfelül láthattuk a 10000-szeresét adja vissza, amit én a programban 1000-al osztottam. Így a változásnak 16,1-nek kellett volna lenni. Ezzel szemben 800 volt a változás. Szóval az elméletem nem jó. Ha valakinek sikerül igazolni az 57-et, az szóljon!
És íme a cm-es kijelzésű program:
#include "HX711.h" const int LOADCELL_DOUT_PIN = 2; const int LOADCELL_SCK_PIN = 3; long nyomas; int nullaszint; int vizszint; HX711 scale; void setup() { Serial.begin(9600); scale.begin(LOADCELL_DOUT_PIN, LOADCELL_SCK_PIN); nyomas = scale.read_average(20); //az eslő mérést úgy végeztem, hogy a szilikoncsövet nem dugtam be a vízbe //ekkor gyakorlatilag a légnomást mérem meg. Ha bedugom a csövet a vízbe //a légnyomás növekedni fog, ahogyan a víz egyre magasabbra hatol a csőben //és összenyomja a levegőt nullaszint=(int) (nyomas/1000); Serial.print("Elso meres:"); Serial.println(nullaszint); } void loop() { nyomas = scale.read_average(20); vizszint=((int)(nyomas/1000)-nullaszint)/57; //a szilikon csövet egy pohárba dugtam, az 57 osztó egy gyakorlati szám //amit egy konkrét méréssel állapítottam meg. A pohárban 14cm víz volt //és a nyomás különbség pont 800-ra adódott. Ebből egy cm 57. Serial.print("Vizszint:"); Serial.print(vizszint); Serial.println("cm"); delay(2000); }
Még egy fontos megfigyelés: feltehetőleg a szenzor és a szilikoncső illesztése nem sikerült tökéletesen, és szivárgott a levegő, mert a nyomás a cső víz alá dugását követően nagyon lassan csökkenni kezdett. Kb. 5 perc alatt vissza is állt a normál légköri nyomásra. Remélem ez nem a szenzor tulajdonsága, mert akkor nem lehet vele így vízszintet mérni. Később ki fog derülni! Megírom majd az eredményt!
—————————————————————————————-
Eltelt az utolsó mondat óta néhány hónap. Közben a neten sikerült rendelni elegendően vékony szilikon csövet. A belső átmérő még egy kicsit kisebb is mint 2mm. Valamilyen egészségügyi célra gyártott cső katéter vagy hasonló. A 10m elég sokba került 2-3000Ft-ra emlékszem. Már régebben itt áll, csak most tudtam elővenni a problémát. A rossz hír, hogy így is csökken a nyomás. Nem voltam elég alapos, és csak néhány órát figyeltem az eseményeket, és ebből levontam a következtetést, hogy minden rendben, és korán örültem. Be is írtam ide a jó hírt, amit most meg kel változtatnom! Épp ezért ha régebben itt még mást olvastál, az most megváltozott! Sajnos a működés nem ideális. A nyomás fokozatosan csökkent, néhány nap alatt észrevehető mértékben. Tekintve, hogy a kútban hónapokig fog állni a csőben a vízoszlop (vagy annak hiánya) valószínűleg nem lesz alkalmas vízszint mérésre a szerkezet, mert kiegyenlítődik a nyomáskülönbség a téli időszakban, amikor nem fogunk locsolni.
Vagy mégis működhet? Azt találtam ki, hogy 0 vízszintnek a legmagasabb szintet fogom tekinteni, tehát azt, amikor a kút megtelt vízzel. Ekkor pont fordítva fog minden működni, ahogy a szivattyú szívja ki a vizet, a nyomás csökkenés a vízszint csökkenést fogja jelenteni. Mivel hosszú idő után a nyomás a maximális vízszinten egyenlítődik ki, a szivattyú használata pedig csak relatíve rövid időre változtatja meg a vízszintet, a mérőműszerem pár órás szintváltozások esetén jó értéket fog kijelezni. Sajnos ez a mérés azonban nem az abszolút vízszintet fogja mérni, hanem a relatív vízszintet. Ha netán sok csapadék miatt a kút vízszintje megemelkedik, akkor a szivattyú több vizet fog tudni leszívni, és ezt a nyomásmérőm nem fogja tudni, hiszen alattomos módon beáll az aktuális vízszintre. Sebaj, ettől még lehet jó, nem adom fel!
Sokat gondolkodtam közben, hogyan is épüljön fel a nyomásmérő berendezésem a kút vizében, amit a szivattyú rendszeresen felkavar. A víz tele van szennyeződésekkel, homokszemekkel, és ki tudja még mivel. Félek, hogy a vékony szilikoncső el fog dugulni. Erre azt találtam ki, hogy egy kicsi műanyag palacknak kifúrom a kupakját, hópisztollyal beleragasztom a szilikoncsövet (persze a végét ledugom az aljára). Aztán a kupak felcsavarása előtt futok néhány lukat a palack aljára, és megtöltöm kb. félig apró kavicsokkal. A nyomás terjedni fog a kavicsok között is, de talán a szennyeződések nem úszkálnak be annyira könnyen a palackba. A kupakot visszacsavarom, és az egészet leengedem a kútba. Idővel megtelik majd vízzel, esetleg segítek neki és előre töltök bele. A kavicsok le fogják húzni a kút aljára.
Már csak a szintjelzés kalibrálását kell kitalálni. Nyilván tudok mérni egyet akkor, amikor a palack még úszik a víz felszínén (vagy legalábbis közvetlenül a víz felszín közelében van), és mérhetek akkor is, amikor lesüllyed a kút legaljára. Mondjuk egy picit majd visszahúzom, nehogy eltemesse az iszap. Praktikusan arra a szintre kell visszahúzni, ahol épp kiürül a kút a szivattyúzáskor. Nyilván a palackot valamilyen vékony kötél is tartani fogja, nehogy elszakadjon a szilikon cső. A kötél jelölgetésével mérhető a mélység.
Egyébként már volt egy primitív mélységmérőm. Damilra kötöttem egy műanyag palackot tele levegővel, hogy lebegjen a vízen. A kúton a damilt átvetettem egy csigán és rákötöttem egy kisebb anyacsavart. A csavar szépen emelkedett, amikor fogyott a víz. Csak az a baj, hogy a vízszint változás több mint egy méter, és amikor megtelt a kút a csavar a földre érkezett, és már nem jelzett semmit. Egyébként tökéletes lett volna. Unalmas megoldás!
Szóval a két szint értéket kell a programba beégetni, és készen is vagyunk. A vízszintet nem cm-ben fogom kijelezni, hanem 10 led-et rakok az Arduino nano 10 digitális kimenetére, tele kútnál mind világít, amikor kiürül akkor meg csak a legalsó. Egy azért világítson mindig, hogy lássam működik. Hát ez a nagy terv. Ha elkészültem, megosztom a képeket, a programot és a tapasztalatokat.