SD-Logger IV. - Adatgyűjtés
Most, hogy már van egy működő kártyánk, egy időmérő eszközünk - végre az eredeti feladatra is koncentrálhatunk. De mit is mérjünk?
Az újra beköszöntött télre való tekintettel a hőmérsékletet és a megvilágítást vesszük a célkeresztbe. Ha nyáron írnám a cikket, akkor még a páratartalom is bekerülne a gyűjtött adatok közé...
De mire jó, ha van egy ilyen eszközünk? Hányszor lenne jó tudni télen, hogy mikor, melyik a hideg sarok, vagy a nap mennyire melegít? Ha nyitogatom a hűtőt, az mikorra hűl vissza? A kerti medencében a víz mennyire hűl le nyáron? Vannak kérdések, amelyek megválaszolásához a méréseket inkább egy automata végezze....
Mi is kell az adatgyűjtőhöz?
Egy Arduino lapka, ami legalább az ATMega328 chipet tartalmazza. De lehet akár a Mega család valamelyik tagja is. És kell egy SD kártyás adatgyűjtő lap szerelt vagy KIT állapotában. És persze SD kártya, tesztelve az Arduino rendszerben.
- A fényméréshez fotoellenállás vagy fototranzisztor és hozzá tartozó felhúzó ellenállás,
- Valamilyen analog kimenetű hőmérő,
- Akkupack vagy faliadapter a független működéshez.
- Forrasztóón, vezeték, kézügyesség...
A szenzorok
A mintaként elkészülő adatgyűjtőben két adatot gyűjtünk:
- a fotoszenzor a megvilágítást méri (például, hogy a hűtőszekrény ajtaja nyitva van-e, vagy a nap felkelt-e már)
- a hőmérő segítségével a tényleges hőfok kerül monitorozásra.
A megvilágításmérő szenzort az Analog 0 kivezetésre kötjük, míg a munka vagy felhúzó-ellenállást az pozitív ág felé.
A hőmérséklet mérése analóg hőmérővel történik. Egyéb kivitelt majd valamelyik későbbi cikkben járok körbe... Az analóg hőmérés és megvilágítás során a pozitív ág az nem a szokásos +5V lesz. Ennek oka, hogy a chip összes digitális és analóg egysége az 5V tápfeszültséget "zajongja" össze. Ez pedig megjelenne a mért jelben. Ami rendelkezésre áll, az a rendszer 3.3V-os belső tápforrása, illetve az Aref kivezetés. Ez utóbbi elvetésre kerül, hiszen az Aref néhány mA-nél jobban nem terhelhető! A 3.3V ideális, hiszen a zaj az 5V-ból nem kerül rá. A mérések során az analóg jeleket a referenciával hasonlítjuk össze. Itt 5V nem lehet - mivel precíz mérésre van szükség és jelenleg is elég zajos. A belső 1.1V vagy 2.56V bizonytalan, kb. 5% pontosságú. Sőt, még a hőfokfüggése is jelentős. A fennmaradó megoldás a külső feszültség-referencia használata. Miért ne használjuk a 3.3V-ot, hamár rendelkezésre áll?
A mérőrendszer bekötése egyszerű. Ezt mutatja a Fritzingben készült ábra is (a referencia nincs még bekötve).
De a megvalósításhoz nem szükséges csupalyuk panel, vagy dugdosós breadboard - hiszen az SD-logger shield tartalmaz fejlesztőpanel részletet! A panel furatgalván kialakítású, így egyszerűen megoldhatóak a forrasztások és a bekötések is.
Ha a 3.3V-os analog rendszer helyett az 5V-osat használod, a méréshez nagyobb lépésköz áll rendelkezésre. Ha a zajt akarod kiküszöbölni, akkor vegyél több mintát és átlagold. A jel nem változik 1 msecről a másikra jelentősen.
Tipp! A referenciafeszültség lehet 3.3V, de tilos összekötni közvetlenül az Aref kivezetéssel! Az AVR chipnél a bekapcsolás után referencialábon 5V/10mA jelenik meg! Így 1 kohm ellenálláson át köthető csak össze a Vref és a 3.3V!
Arduino szenzorteszt
Végre eljutottuk az első adatgyűjtős mintaprogramig. Ebben nem teszünk mást, mint a mérési részegységet leteszteljük:
/* Sensor test sketch (c) TavIR http://www.tavir.hu This sketch tests light sensor and two analog thermosensor. Tested: Arduino 1.0.3 Source: ladyada.net / logshield Modified 17 March 2013 by TavIR / Robert Cseh */ #define aref_voltage 3.27 // we tie 3.3V to ARef and measure it with a multimeter! int photocellPin = 1; // the phototansistor and 47K pullup are connected to A1 int photocellReading = 0; // the analog reading from the analog resistor divider //2x LMx35 Pin Variables int tempPin = 2; int tempPinExt = 3; //the analog pin the LMx35''s Vout (sense) pin is connected to //the resolution is 10 mV / degree centigrade // output will be in Kelvin int tempReading; // the analog reading from the sensor float temp_in_celsius = 0, temp_in_kelvin=0, temp_in_fahrenheit=0; float voltage = 0; void setup(void) { // We''ll send debugging information via the Serial monitor Serial.begin(9600); // If you want to set the aref to something other than 5v (Vcc) analogReference(EXTERNAL); } void loop(void) { photocellReading = analogRead(photocellPin); Serial.print("Fenyszenzor = "); Serial.print(photocellReading); // the raw analog reading // We''ll have a few threshholds, qualitatively determined if (photocellReading < 10) { Serial.println(" - Fenyes"); } else if (photocellReading < 200) { Serial.println(" - Nappali feny"); } else if (photocellReading < 500) { Serial.println(" - Felhomaly"); } else if (photocellReading < 800) { Serial.println(" - Holdfeny"); } else { Serial.println(" - Fekete lyuk"); } Serial.println(); tempReading = analogRead(tempPin); Serial.print("Belso hofok = "); Serial.print(tempReading); // the raw analog reading // converting that reading to voltage, // which is based off the reference voltage voltage = tempReading * aref_voltage / 1024; // print out the voltage Serial.print(" - "); Serial.print(voltage); Serial.println(" V"); //Reads the input and converts it to Kelvin degrees temp_in_kelvin = tempReading * (aref_voltage/1024) * 100; //Converts Kelvin to Celsius minus 2.5 degrees error temp_in_celsius = temp_in_kelvin - 2.5 - 273.15; temp_in_fahrenheit = ((temp_in_kelvin - 2.5) * 9 / 5) - 459.67; //Print the temperature in Celsius to the serial port Serial.print("Celsius: "); Serial.println(temp_in_celsius); //Print the temperature in Fahrenheit to the serial port Serial.print("Fahrenheit: "); Serial.println(temp_in_fahrenheit); Serial.println(); tempReading = analogRead(tempPinExt); Serial.print("Kulso hofok = "); Serial.print(tempReading); voltage = tempReading * aref_voltage / 1024; Serial.print(" - "); Serial.print(voltage); Serial.println(" V"); temp_in_kelvin = tempReading * (aref_voltage/1024) * 100; temp_in_celsius = temp_in_kelvin - 2.5 - 273.15; temp_in_fahrenheit = ((temp_in_kelvin - 2.5) * 9 / 5) - 459.67; Serial.print("Celsius: "); Serial.println(temp_in_celsius); Serial.print("Fahrenheit: "); Serial.println(temp_in_fahrenheit); Serial.println("--------------------------------------------"); delay(1000); }
A mintakód feltöltése és eredménye a soros terminálban:
A minta során kissé befűtésre került a panel környékén. Így a megvilágítás teljes volt, a hőmérséklet is a szokásosnál magasabb. És mindezt európai Celsius-ban és amerikai Fahrenheit-ben is visszakapjuk. Az eredményekből látjuk, hogy nem kötöttünk el semmit - az adatokat beolvashattuk.
Fontos! Ugráló adatok, egyik irányba kiakadt ADC - mind forrasztási/bekötési hibát jelent.
Bascom-AVR szenzorteszt
A program az Arduinohoz kísértetiesen hasonlít, és ugyanazt is végzi el.
''********************************************* ''* Title: Measure analog * ''* About: Tesing analog temp and light * ''* Filename: measure.bas * ''* Compiler: Bascom-AVR 2.0.7.5 * ''* * ''* Author: Robert Cseh * ''* Date : 2013-03-23 * ''* E-mail: avr /kukac/ tavir /pont/ hu * ''* Homepage: http://www.tavir.hu * ''********************************************* $crystal = 16000000 $baud = 9600 $regfile = "m328pdef.dat" Const Aref_voltage = 3.27 ''we tie 3.3V to ARef and measure it with a multimeter! Const Photocellpin = 1 ''the phototansistor and 47K pullup are connected to A1 Dim Photocellreading As Word ''the analog reading from the analog resistor divider ''2x LMx35 Pin Variables Const Temppin = 2 Const Temppinext = 3 ''the analog pin the LMx35''s Vout (sense) pin is connected to ''the resolution is 10 mV / degree centigrade ''output will be in Kelvin Dim Tempreading As Word ''the analog reading from the sensor Dim Temp_in_celsius As Single Dim Temp_in_kelvin As Single Dim Temp_in_fahrenheit As Single Dim Voltage As Single ''Init ''We''ll send debugging information via the Serial monitor $baud = 9600 ''If you want to set the aref to something other than 5v (Vcc) Config Adc = Single , Prescaler = Auto , Reference = Aref Do Photocellreading = Getadc(photocellpin) Print "Fenyszenzor = " ; Photocellreading; ''the raw analog reading ''We''ll have a few threshholds, qualitatively determined If Photocellreading < 10 Then Print " - Fenyes" Else If Photocellreading < 200 Then Print " - Nappali feny" Else If Photocellreading < 500 Then Print " - Felhomaly" Else If Photocellreading < 800 Then Print " - Holdfeny" Else Print " - Fekete lyuk" End If End If End If End If Print "" Tempreading = Getadc(temppin) Print "Belso hofok = " ; Tempreading; ''the raw analog reading '' converting that reading to voltage, '' which is based off the reference voltage '' voltage = tempReading * aref_voltage / 1024; Voltage = Tempreading * Aref_voltage Voltage = Voltage / 1024 '' print out the voltage Print " - " ; Voltage ; " V" ''Reads the input and converts it to Kelvin degrees ''Temp_in_kelvin = Tempreading *(aref_voltage / 1024) * 100 Temp_in_kelvin = Aref_voltage / 1024 Temp_in_kelvin = Temp_in_kelvin * 100 Temp_in_kelvin = Temp_in_kelvin * Tempreading ''Converts Kelvin to Celsius minus 2.5 degrees error Temp_in_celsius = Temp_in_kelvin - 2.5 Temp_in_celsius = Temp_in_celsius - 273.15 Temp_in_fahrenheit = Temp_in_kelvin - 2.5 Temp_in_fahrenheit = Temp_in_fahrenheit * 9 Temp_in_fahrenheit = Temp_in_fahrenheit / 5 Temp_in_fahrenheit = Temp_in_fahrenheit - 459.67 ''Print the temperature in Celsius to the serial port Print "Celsius: " ; Fusing(temp_in_celsius , "#.##") Print "Fahrenheit: " ; Fusing(temp_in_fahrenheit , "#.##") Print Tempreading = Getadc(temppinext) Print "Kulso hofok = " ; Tempreading; ''the raw analog reading '' converting that reading to voltage, '' which is based off the reference voltage '' voltage = tempReading * aref_voltage / 1024; Voltage = Tempreading * Aref_voltage Voltage = Voltage / 1024 '' print out the voltage Print " - " ; Voltage ; " V" ''Reads the input and converts it to Kelvin degrees ''Temp_in_kelvin = Tempreading *(aref_voltage / 1024) * 100 Temp_in_kelvin = Aref_voltage / 1024 Temp_in_kelvin = Temp_in_kelvin * 100 Temp_in_kelvin = Temp_in_kelvin * Tempreading ''Converts Kelvin to Celsius minus 2.5 degrees error Temp_in_celsius = Temp_in_kelvin - 2.5 Temp_in_celsius = Temp_in_celsius - 273.15 Temp_in_fahrenheit = Temp_in_kelvin - 2.5 Temp_in_fahrenheit = Temp_in_fahrenheit * 9 Temp_in_fahrenheit = Temp_in_fahrenheit / 5 Temp_in_fahrenheit = Temp_in_fahrenheit - 459.67 ''Print the temperature in Celsius to the serial port Print "Celsius: " ; Fusing(temp_in_celsius , "#.##") Print "Fahrenheit: " ; Fusing(temp_in_fahrenheit , "#.##") Print "--------------------------------------------" Waitms 1000 Loop
És a program futtatásának eredménye:
Adatgyűjtés
Az adatgyűjtő program adatgyűjtő része szép hosszú lett. Ezt lefordítva és feltöltve az adatgyűjtőre, már majdnem készen is vagyunk. Persze - az SD kártya ne maradjon ki!
A tesztelésnél még a PC kapcsolat maradjon meg - így látjuk mi történik:
A mérés során, a teszt alatt a megvilágításmérőt egyszerűen takarjuk el. Így látjuk, hogy mennyi fényt kap. A hőmérőszenzort egyszerűen csak tapogassuk meg. Így a hőmérséklete 32-35 fokra nő.
Bascom-AVR alatt is hasonló eredményt kell hogy kapjunk.
Kiértékelés
Ha a tesztméréssel végeztünk,vegyük ki az SD kártyát az áramtalanítás után. A PC-ről nézzük meg az eredmény-file-t. Itt több állományt is találhatunk:
Az egyiket nyissuk meg és nézzünk bele. Szép, szöveges állomány, amiből kézzel is rajzolhatunk diagrammot. De a PC korában ez olyan elavult módszer lehet... A leggyorsabb megoldás, valamelyik táblázatkezelő használata.
A Microsoft Office csomag Excel alkalmazása vagy az OpenOffice Spreadsheet/Calc szoftvere a legismertebb.
Kiértékelés
Hogy legyen mit kiértékelni, most megyek és a hűtőben adatgyűjtök..... :)
És az eredmény:
Az ábrából látszik, hogy a hűtőgép már lassan haldoklik. kb. 3 óra alatt melegszik fel és majd'' egy óra alatt hül csak vissza! Bár még lesz kontrollhűtő is, így legalább látom az ingadozást.
A belső hofok ki-/bekapcsolási különbsége majd'' 5-6 fok! Ez egy háztartási hűtőnél nem a legjobb ómen. Az újabbak esetén ez manapság 2-4 fok, a régebbieknál még nem volt pontosabb igény. Így a 14 éves hűtőnél ez elfogadható. Tipp: a hűtőre tegyél 2-4 cm hungarocelt kívülről. Meglepő lesz a fogyasztáscsökkenés!
A sárga vonalak az ajtónyitásokat jelentik. Itt volt amikor "fényt kapott" látszik, hogy a hőmérsékletemelkedés igen gyors. És ezt a hűtő nagyon lassan hűti vissza. A minta vételezés másodperces alapú volt, és ~50 ezer pont került kiértékelésre...
A két hőmérő együttfutása is érdekes. Az Ext jelű hőmérő kicsit közelebb volt a hűtő hátlaphoz, míg a másik az áramköri lapon volt. Ez utóbbit az áramkör 7805 jelű hőfokszabályzója is melegítette (a betáp 9V-os trafó volt!). Végülis meg is hamisította a hőmérsékletnövekedése a mérést. de legalább nem véletlenszerű hiba volt....
Kapcsolódó leírások:
Kapcsolódó áramkörök:
Források:
TavIR-Facebook