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