Az egyik legegyszerűbb módja, ha Arduinoval szeretnénk hőmérsékletet mérni – az LM35 hőmérő chip használata. Ez az érzékelő meglehetősen pontos és nem igényel külső alkatrészeket a működéséhez. Tehát néhány vezetékkel és egy rövid kóddal pillanatok alatt mérni lehet a hőmérsékletet!
Hozzávalók
Eszközök
- Egybeépített karakteres kijelző és I2CLCD modul,
- Arduino UNO alaplap,
- LM35 hőmérő chip, kábel.
Szoftver
- Arduino IDE keretrendszer
A cikk a Windows alatti 1.8.13 verzióval készült.
Az LM35 hőmérséklet érzékelő
Az LM35 chip egy alacsony feszültségű, precíziós hőmérséklet-érzékelő, amelyet a Texas Instruments gyárt. Ez egy olyan chip, amely a °C-ban mért hőmérséklettel lineárisan arányos kimeneti feszültséget biztosít, ezért Arduino-val nagyon könnyen használható.
Az LM35 hőmérséklet-érzékelő meglehetősen precíz, soha nem használódik, széles hőmérsékleti tartományban működik és nem igényel külső alkatrészt. Ezenkívül az LM35 érzékelőt nem kell kalibrálni és tipikusan jó pontosságot biztosít szobahőmérsékleten ±0,5°C, teljes –55°C és +155°C közötti hőmérsékleti tartományban pedig ±1°C pontosságú. Az érzékelő 4 V-tól 30 V-ig terjedő tápfeszültségről táplálható és kevesebb, mint 60 µA-t fogyaszt az aktív hőmérséklet-mérések során – így nagyon alacsony az önmelegedése: kevesebb, mint 0,08 °C írható a számlájára.
A chip főbb specifikációi:
Paraméter | Érték |
---|---|
Tápfeszültség | 4V-30V |
Működési áramfelvétel | 60µA |
Mérési tartomány | -55°C .. +155°C |
Pontosság | ±0.5°C |
Kimeneti arány | 10mV/°C |
Kimeneti feszültség (25°C ) | 250mV |
Bővebb adatokat az adatlap tartalmaz: LM35 adatlap
Az LM35 érzékelő egyetlen hátránya, hogy negatív előfeszítő feszültséget igényel a negatív hőmérséklet méréséhez! Tehát, ha az érzékelőt negatív hőmérséklet mérésére kell használni, akkor a talpponti feszültségét meg kell emelni – de ekkor már inkább ajánlott a TMP36 hőmérséklet-érzékelő használata! Az Analog Devices által gyártott TMP36 meglehetősen pontos (-40°C és 125°C között); és megvan az az előnye, hogy képes negatív hőmérsékleteket mérni anélkül, hogy negatív előfeszítő feszültségre lenne szükség.
Az LM35-nek van még egy alternatívája – a Dallas DS18B20 hőmérője. A digitális hőmérséklet-érzékelők jobb zajtűréssel rendelkeznek, ami akkor hasznos, ha az érzékelőt nagyobb távolságra vagy elektromosan zajos környezetben kell elhelyezni.
Működési elv
Az LM35 hőmérsékletmérő mérési elve azon alapul, hogy a félvezetők ún. pn-átmenetének feszültségjellemzője hőmérsékletfüggő és a hőmérséklet emelkedésével az átmeneti feszültség ismert mértékben csökken. Ennek a feszültségváltozásnak a pontos felerősítésével könnyen előállítható a hőmérséklettel egyenesen arányos analóg jel.
A félvezetők esetén jó közelítéssel lineáris a kapcsolat a feszültség-esés és a hőmérséklet között. Ez a jellemző az oka annak, hogy a diódákat (vagy bármilyen pn-átmenetet) hőmérsékletmérő eszközökként használják. Lényegében egy dióda a lelke az eszköznek – így mérik a hőmérsékletet (bár az évek során történt némi fejlesztés ebben a technikában is). A pn átmenet feszültségváltozása linearizálásra, szinteltolásra, belső kalibrálásra is kerül.
Az LM35 chip belső felépítésének vázlata is jól tükrözi a működést:
A jó hír az, hogy a linearizálást, kalibrációt és mindezeket az összetett számításokat, illesztéseket az LM35 belsejében az elektronika elvégzi – így a hőmérséklettel lineárisan arányos feszültséget ad ki magából.
Hogyan lehet hőmérsékletet mérni?
Az LM35 nagyon egyszerűen használható: csak csatlakoztatni kell az ábra szerint a tápfeszültséghez (4..30V) és a közös földponthoz. A középső kivezetésen a hőmérséklettel arányos analóg feszültségszint jelenik meg. A kijövő analóg jel és a Celsius fok-skála közt egyértelmű összefüggés van: Ez jól látható a kimeneti feszültség – hőmérséklet karakterisztikán is. Fontos! Az analóg kimeneti feszültség független a tápegységtől.
A kimeneti feszültség és a hőfok közti összefüggés:
Hőmérséklet (°C) = Vout * 100
Azaz például, ha a kimenő feszültség 0,5 V, az azt jelenti, hogy a hőmérséklet 0,5 * 100 = 50 °C
Az LM35 tesztelése
Az lm35 hőmérő chipet meglehetősen egyszerű tesztelni: csak csatlakoztatni kell a tápcsatlakozóit 4..30V tápfeszültségre (négy AA elem kiválóan alkalmas a célra, vagy egy USB telefontöltő, stb). Majd egy multimétert DC voltmérésként a GND és a középső kivezetés közé kötve a feszültség leolvasható. Szobahőmérsékleten (25°C) a feszültségnek körülbelül 0,25 V-nak kell lennie.
Tesztelhető a hideg pl. jégkockával, míg a meleg akár kézrátéttel…. A kimeneti feszültség a hőmérsékletet mutatja.
Tipp: sózott jég esetén elérhetünk 0 fok alatti hőfokot is!
Fontos! Vizes, sós közegben a hőmérőt érdemes folpack-ba csomagolni! A sós nedvesség igen korrozív – tesztelés után le kell mosni!
LM35 érzékelő kivezetés
Az LM35 három különböző kivitelben kapható, de a legelterjedtebb típus a 3 lábú TO-92 tokozású. Ez úgy néz ki, mint egy tranzisztor:
A jelzett kivezetések:
- Vcc: az érzékelő tápellátása, amely 4V és 30V között lehet,
- Vout: analóg feszültségkimenet, amely egyenesen arányos (lineáris) a hőmérséklettel. Processzoros rendszer esetén az analóg (ADC) bemenethez kell csatlakoztatni,
- GND: közös földpotenciál.
Az LM35 hőmérséklet-érzékelő csatlakoztatása Arduino-hoz
Az LM35 Arduino-hoz csatlakoztatása rendkívül egyszerű. Összesen a három kivezetést kell bekötni – mindenféle járulékos alkatrész nélkül. A kivezetések közül kettő a tápellátást biztosítja, míg a harmadikon keresztül az analóg hőmérséklettel összefüggő értéket lehet megkapni és a processzor analóg lábára kell bekötni. Az érzékelő tápellátását a rendszer 5V-járól a legegyszerűbb megoldani. A pozitív feszültségez a Vcc kivezetésre, a föld pedig a GND-hez csatlakozik. A középső Vout kivezetés az érzékelő analóg jelkimenete, és az Arduino analóg bemenetén keresztül lehet mérni az értékét.
Áramló vagy álló levegő hőmérsékletének méréséhez az érzékelő maradhat a szabad levegőn. Ha tárgyhőfokot kell mérni (pl. hűtőbordát), akkor egyszerűen hozzá kell rögzíteni, vagy akár a bordák közé benyomni…
Tipp: a véletlen zárlat elkerülésére a lábakat illetve a hőmérőt érdemes védő zsugorcsőbe helyezni…
Az analóg hőmérsékleti adatok olvasása
Ahogyan a fenti kapcsolási rajzon látható, az LM35 kimenete az Arduino egyik analóg bemenetéhez csatlakozik. Ennek az analóg bemenetnek az értékét az analogRead()
függvénnyel lehet kiolvasni.
Az analogRead()
függvény azonban valójában nem az érzékelő kimeneti feszültségét adja meg, hanem leképezi a 0V (GND) és az ADC referenciafeszültség (Aref) közötti feszültségtartományra (az Aref alapértelmezetten az AVR chip tápfeszültsége (azaz 5 V Uno, mmega, leonardo) vagy 3,3 V (pro mini 3v3)) és az analóg bemenet 10 bites felbontású (0…210-1) egész értékek – azaz 0…1023 közötti szám. Az ADC feszültségbemenetén levő feszültségérték ténylegesen a mért analóg értékből az alábbi képlettel számítható:
Vout = (beolvasott ADC érték) * (5 / 1024)
A képlettel a beolvasott 0-1023 ADC értéket 0-5V tartományra számoljuk át. Azután a feszültséget hőmérsékletté alakítunk:
Hőfok (°C) = Vout * 100
Arduino kód – Egyszerű hőmérő
A következő program az LM35 hőmérséklet-érzékelő gyors leolvasásának módját mutatja be – így gyakorlati kísérletek és projektek mintájául is szolgálhat. A mintaprogram beolvassa az A2 analóg bemeneten keresztül az LM35 feszültségkimenetét és a soros portra kiírja az aktuális hőmérsékletet (°C-ban és °F-ban egyaránt). A mintakódot egyszerűen fel kell tölteni az Arduino lapra – semmiféle plusz könyvtár nem szükséges hozzá.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #define sensorPin A2 void setup(){ Serial.begin(9600); } void loop() { int reading = analogRead(sensorPin); float voltage = reading * (5.0 / 1024.0); float temperatureC = voltage * 100; Serial.print("Temperature: "); Serial.print(temperatureC); Serial.print("\xC2\xB0"); // shows degree symbol Serial.print("C | "); float temperatureF = (temperatureC * 9.0 / 5.0) + 32.0; Serial.print(temperatureF); Serial.print("\xC2\xB0"); // shows degree symbol Serial.println("F"); delay(1000); } |
A soros monitort az Eszközök-Soros monitor menüben vagy a nagyító ikonnal lehet megnyitni.
A képernyőn valami ilyesmit lehet látni a soros monitort megnyitva:
A kód működése
A program elején definiáljuk, hogy a szenzor kimenete (Vout) melyik analóg Arduino bemenetre van kötve:
1 | #define sensorPin A0 |
A setup()
részen a soros kommunikációt definiáljuk és a sebességét is megadjuk:
1 2 3 | void setup() { Serial.begin(9600); } |
A loop()
főprogramban először az analóg bemeneten (melyet a program elején definiáltunk) beolvassuk az LM35 által kiadott feszültség értékét az analogread()
utasítással.
1 | int reading = analogRead(sensorPin); |
Ezután a korábban megismert képlet segítségével az analóg bemenet feszültségértékét hőfokra számítjuk át:
1 2 | float voltage = reading * (5.0 / 1024.0); float temperatureC = voltage * 100; |
és végül az eredményt a soros porton kiírjuk.
1 2 3 4 | Serial.print("Temperature: "); Serial.print(temperatureC); Serial.print("\xC2\xB0"); // shows degree symbol Serial.print("C | "); |
A programban a kapott Celsius fokot (°C) Fahrenheitbe (°F) átszámítjuk, és a soros monitorra szintén kiírjuk…
T(°F) = T(°C) × 9/5 + 32
1 2 3 4 | float temperatureF = (temperatureC * 9.0 / 5.0) + 32.0; Serial.print(temperatureF); Serial.print("\xC2\xB0"); // shows degree symbol Serial.println("F"); |
Projekt: LM35 hőmérő mérési eredményének kiírása az I2C LCD-re
Néha felmerül, hogy a hőmérsékleti értékeket valós időben kellene megjeleníteni és riasztást küldeni (ha a hőmérséklet egy megadott tartományon kívül esik). A fiókban valószínűleg van egy 16×2 karakteres LCD – az I2CLCD bővítővel megfejelve – erre lesz szükség a kiíráshoz a soros monitor helyett. Ebben a példában az I2CLCD az LM35-tel együtt az Arduino-hoz csatlakoztatjuk.
Az I2CLCD csatlakoztatása meglehetősen egyszerű, amint az az alábbi kapcsolási rajzon látható. Az I2CLCD kijelzőről itt lehet olvasni bővebben (legalább áttekintés szinten érdemes átfutni-áttekintést).
A következő program a hőmérsékleti értékeket az I2C LCD-re írja ki. A kód hasonló az előző példához, azzal a különbséggel, hogy az értékek az I2C LCD-n jelennek meg.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | #include <LiquidCrystal_I2C.h> LiquidCrystal_I2C lcd(0x3F, 16, 2); byte Degree[] = { B00111, B00101, B00111, B00000, B00000, B00000, B00000, B00000 }; #define sensorPin A2 void setup() { lcd.init(); lcd.backlight(); lcd.createChar(0, Degree); } void loop() { int reading = analogRead(sensorPin); float voltage = reading * (5.0 / 1024.0); float temperatureC = voltage * 100; lcd.setCursor(0, 0); lcd.print("Temperature:"); lcd.setCursor(0, 1); lcd.print(temperatureC, 1); lcd.write(0); // print the custom degree character lcd.print("C "); float temperatureF = (temperatureC * 9.0 / 5.0) + 32.0; lcd.print(temperatureF, 1); lcd.write(0); // print the custom degree character lcd.print("F "); delay(1000); } |
Valami ilyesmit láthatnunk a kijelzőn a program feltöltése után:
A programkód működése a soros portra történő kiíráshoz hasonlóan történik, csak itt az LCD kijelző a megjelenítő felület. Az I2CLCD és a működéséről a →Karakteres IIC/TWI LCD és kezelése… cikkben lehet bővebben olvasni. A kiírás a soros port helyett az LCD-re történik és a mérés másodpercenként frissül.
A programkódban LCD specifikus újdonságként az lcd.createChar(0, Degree);
utasítás és a Degree[]
tömb – ezek segítségével történik meg a fokjel létrehozása.
Ugráló mérési eredmény
A kiírások során időnként kiugró adatokat, irreális mérési eredményeket is láthatunk. Ugyanakkor, ha az LM35 kimenetét multiméterrel vizsgáljuk – semmiféle mozgó adatot nem találunk rajta… Sőt, a kiírt számoknál sem a szép lassan elkúszó eredményt látjuk (mintha a kapott eredmény a melegedés vagy hűlés miatt fokozatosan történne) – hanem nagyobb ugrások történnek….
Mérési pontosság
A mérési eredményt az analóg bemeneten olvassuk be. Az Arduino esetén az alapértelmezett beállítások: 0-5V tartományt mér és a felbontása 10 bites (1024 részre osztva). Így 1 ADC osztás : 5.0V/1024=4,88mV.
Az LM35 kimenete a korábbiakban leírt adatok alapján: 10mV változás fokonként.
E két adat alapján a mérés precizitása a 0,5fok!
De hogyan is növelhető a pontosság?
Erre a lehetőségünk, hogy az analóg felbontást kell valamilyen módon növelni. A legegyszerűbb megoldás az, hogy az ADC mérési tartományát kellene valahogyan lecsökkenteni, így 1 ADC egységre kisebb mérési lépcső jut.
Az adatlapot megnézve, az ADC felső értékét az Aref értéke határozza meg. Ez lehet:
- AVR chip tápfeszültsége (itt 5V)
- Külső referenciafeszültség (minimum 1.1V!)
- AVR belső referenciafeszültsége
Külső Aref feszültséget a lapon egy helyen találunk: a rendszerszintű 3.3V-ot. Ezt egyszerű átkötéssel lehet megoldani, amikor a Aref kivezetést a lap 3.3V tápkivezetésére kell áthidalni.
Azonban a belső referencia-feszültség az AVR chiptől függően lehet 1.1V vagy 2.56V vagy akár mind a kettő.
Azt, hogy ténylegesen ezek közül melyiket használjuk , azt a programunk elején kell megmondani a setup()
részen az analogReference(type)
utasítással – ahol a type utal arra, hogy melyik referenciát használjuk. Az Uno lap estén az ATMega328 chip a központi kontroller – ez belső 1.1V referenciával rendelkezik.
Fontos! Ha az AVR ADC-je külső referenciafeszültséggel lesz használva TILOS a belső referenciát beállítani – ez a belső referencia-áramkör meghibásodását okozza!
Az első mintaprogram – immár a belső referenciafeszültséggel (jelezve a változások):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | #define sensorPin A2 void setup() { Serial.begin(9600); analogReference(INTERNAL); //<----Itt van a változás! Serial.println(" TEMP(C) | TEMP(F) | ADC"); } void loop() { int reading = analogRead(sensorPin); float voltage = reading * (1.1 / 1024.0); //<----Itt van a változás! float temperatureC = voltage * 100; Serial.print("Temperature: "); Serial.print(temperatureC); Serial.print("\xC2\xB0"); Serial.print("C | "); float temperatureF = (temperatureC * 9.0 / 5.0) + 32.0; Serial.print(temperatureF); Serial.print("\xC2\xB0"); Serial.print("F | "); Serial.println(reading); delay(1000); } |
És a kimenet:
A mérési kiírásban látható, hogy a beolvasás már jóval pontosabb lett. Az 1.1V referencia esetén 1 ADC osztás: ~1mV-nak felel meg, így a 10mV/C LM35 kimenete esetén a mérés már ~0.1°C pontosságú!
További pontosság növelése…
A mérési elrendezés és a belső működés miatt sosem a pontos értéket olvashatjuk le az ADC használatával. Minden esetben ún. kvantált (lépcsős) eredményt kapunk, hiszen az ADC fix lépcsővel működik, az analóg kimenet meg folyamatos. Ábrázolva így lehet ezt a folyamatot:
A trükk az, hogy lassan változó jelek esetén a mérési szórás kiegyenlítődik és a statisztikai középérték adja meg a pontos(abb) értéket. Bővebben a →Wikipedia:Túlmintavételezés (angol) cikkben lehet olvasni az alapelvekről.
A mintaprogramban ez így néz ki – kombinálva a belső referenciafeszültséggel:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | float val; float sample_avg; float temp; int sample_count = 0; void setup() { Serial.begin(9600); analogReference(INTERNAL); } void loop() { sample_count++; val = analogRead(2); sample_avg = sample_avg + (val - sample_avg) / sample_count; if (sample_count >= 4096){ temp=(1.1 * sample_avg * 100.0) / 1024.0; Serial.print(temp,DEC); Serial.println("º"); sample_count = 0; delay(1000); } } |
A soros kimeneten az alábbi eredményt láthatjuk:
Kapcsolódó anyagok
- LM35DZ – temperature sensor. Big differences while reading it (Arduino fórum)
- LM35 adatlap
- Karakteres IIC/TWI LCD és kezelése…
- LM35 hőmérő és az Arduino cikk mintakódok