MPS20N0040D nyomásmérő vízszint méréshez

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 szinte vákuum. Azonban a 40KPa (kilopascal) sem stimmel, mert a normál légköri nyomás 100KPa nyomásnak felel meg. 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 milibar 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 =14504 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 100-szor 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:
14311,58 psi /14504,00 psi =0,986733
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. Ebből adódóan a légnyomást úgy kaphatjuk meg az eszközből kiolvasott értékből, hogy elosztjuk 1431,43-al (1431158/1431,43=999,8 mbar). Ezt a váltószámot nem kiszámoltam, hanem kiolvastam egy a neten fellelt átváltási táblázatból.
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. Feltételezve, hogy két legyártott szenzor közel azonos értéket mutat, a megadott állandóval lehet dolgozni.

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ő, erősíteni kell, és még az erősítés is kevés, mert a feszültség változás a légköri nyomás változását figyelembe véve még egy 0-5V tartományra erőstett jel esetén is rendkívül kicsi lesz. Í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:

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 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 13cm vízmagasságot eredményezett. Azért ennyit, mert a feleségem 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 13cm 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. Aztá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 100-el osztottam, hogy áttekinthetőbb legyen a kapott adat. Integerre is alakítottam, mert a kapott szám már elég stabil lett így, nem változott állandóan az utolsó egy-két számjegyben. Így a 13 cm mélységben pont 800-al nőtt a nyomás, tehát egy cm 57 psi-nek adódik. Nem kell sokat agyalni rajta, ennyi és kész. Arra számítok, hogy a kútba leeresztett kb 12m-es cső esetén ez 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 megadni, de ez csak várakozás. Az a bizonyos 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. 14504Psi normál légköri nyomás 14504/0,9=16115Psi-re nőtt volna meg. A növekedés elméletben 1611Psi. A szenzor ennek a változásnak mint legfelül láthattuk a 100-szorosát adja vissza, amit én a programban 1000-el osztottam. Így a változásnak 161-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!
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!

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);
}

Mennyire volt hasznos amit olvastál?

Kattints egy csillagra az értékeléshez!

Sajnálom, hogy amit olvastál nem volt hasznos számodra!

Szeretném ha elégedett lennél!

Írd le kérlek, hogy mi nem tetszett!?