Arduino-Thermometer

...oder: Wie man map() in der Praxis verwendet.

von Patrick Kaiser 





Als ich die letzte Schaltung (10.27) im Buch zum Lernpaket Arduino gesehen habe, dachte ich mir: Da muss doch mehr drin sein als ein Temperaturschalter!
Die Antwort darauf ist ein klares "jein", aber zunächst die Skizze der Schaltung:




Der Widerstand hat einen Wert von 47 k und die Diode ist vom Typ 1N4148. Man kann auf etwa 5 Grad Celsius genau messen, wenn man den im Buch beschriebenen Aufbau vorher kalibriert. Es ist zum Messen im Wetter-technischen Sinn nur bedingt geeignet.





Wenn es allerdings ganz unnütz wäre, würde ich nichts dazu schreiben: In verschiedenen Foren kann man lesen, dass Leute eine solche Schaltung zum Messen ihrer selbstgebauten Reflow-Öfen (Methode der Leiterplatten-Herstellung), ihrer umgebauten Laminiergeräte oder der Lötkolben-Temperatur verwenden. Demnach scheint die Diode auch 250 Grad auszuhalten - getestet habe ich das aber nicht. Außerdem könnte die Diode damit wohl auch als Überhitzungsschutz (in kontrollierten Umgebungen!) verwendet werden. Hier ist eigentlich mehr der Weg als das Ergebnis interessant, denn mit folgender Vorgehensweise kann man auch andere temperaturempfindliche Bauteile (oder sonstige Sensoren) kalibrieren und verwenden:

Zuerst wird die Schaltung aufgebaut - hier nach Experiment 10.27 im Buch. Dabei ist darauf zu achten, dass möglichst wenig Strom durch den Sensor fließt, damit er sich nicht selbst erwärmt und das Ergebnis verfälscht. Dann öffnet man das der Entwicklungsumgebung beiliegende Programm im Menü unter "File->Examples->Analog->AnalogInSerial, lädt es in den Controller und öffnet den "Serial Monitor". Dargestellt wird nun der Digitalwert des Analogeingang 0, der 0 bis 5V mit einem Digitalwert im Bereich zwischen 0 und 1023 darstellt. Nun bringt man den Temperatursensor (hier also die Diode) in eine Umgebung, deren Temperatur man kennt und notiert den dargestellten Wert. Gleiches macht man mit einer zweiten Umgebung, deren Temperatur man kennt.
In meinem Fall waren das 99 bei 23,0°C, die ich mit dem Raumthermometer nachweisen konnte.



Die zweite Temperatur von 0°C habe ich mir erzeugt indem ich ein Wassereis (aus Mangel an Eiswürfeln) in ein Glas gab und  nach kurzer Zeit das Eiswasser (das dann nahe 0°C sein dürfte) gemessen. Bei mir wurde 108 als Wert ausgegeben.



Daran erkennt man schon zwei Dinge:
1) Wenn ein Bereich von 23°C mit (108 - 99 = ) 9 Wert-Punkten angegeben wird, beträgt die theoretische Auflösung (23 / 9 = ) 2,56°C.
2) Wenn das Temperaturschalter-Experiment aus dem Buch sinnvoll verwendet werden soll, muss man wohl die Werte aus dem Buch-Beispiel drastisch ändern oder die Diode unter ein Feuerzeug halten, was sie zerstören könnte. Für die, die das Buch nicht haben:
Es wird der Digitalwert (also noch nicht als Spannung umgerechnet) der Messung in einer Variable Uf gespeichert und abhängig davon eine LED ein- oder ausgeschaltet. Eingeschaltet wird sie, wenn der Wert größer als 40 ist und ausgeschaltet, wenn der Wert kleiner als 20 ist.

Die gemessenen Werte werden oben im Programm eingesetzt:

//Werte wurden mit dem der Entwicklungsumgebung beigelegten
//Beispiel "Examples->Analog->AnalogInSerial" erzeugt

//Temperatur muss mit 10 multipliziert und als Ganzzahl
//gegeben werden. Die Reihenfolge ist egal.

#define wert1 108
#define temp1 0 //Grad Celsius/10
#define wert2 99
#define temp2 230 //Grad Celsius/10

void setup() {
Serial.begin(9600);
}

void loop() {
// lese Wert vom Analogpin in Variable
int analogValue = analogRead(0);
analogValue=map(analogValue,wert1,wert2,temp1,temp2);
// gebe das Ergebnis mit einer Nachkommastelle aus:
Serial.print("Temperatur: ");
Serial.println((analogValue/10.0),1);
// Warte 1 Sekunde bevor der nächste Wert gelesen wird
delay(1000);
}
Download: p_temperatur.zip

Das Umrechnen der Digitalwerte in Temperaturwerte (oder andere Sensorwerte) übernimmt hier die Funktion map(). (Man nennt diesen Vorgang auch "mappen") Da die Funktion nur Ganzzahlen verarbeitet, kann man eine Festkomma-Zahl erzeugen indem man die Eingabewerte mit 10 multipliziert und die Ausgabewerte beim Ausgeben wieder entsprechend dividiert. Normalerweise sollte man möglichst unterschiedliche Referenz-Messwerte verwenden um die Auflösung zu verbessern. Problematisch kann das werden, wenn sich der Sensor nicht linear verhält: Die map()-Funktion differenziert nämlich nur zwei Werte und extrahiert daraus eine Gleichung 1. Grades (y = m*x + n(*1)). (siehe https://secure.wikimedia.org/wikipedia/de/wiki/Differentialrechnung)
Kurz: Bei nicht-linearen Sensoren sollte der Sensor in einem kleinen Bereich kalibriert werden, nahe an dem Temperaturbereich, in dem man später auch messen möchte.

Wichtig ist, dass man möglichst nur den Sensor in die Messumgebung bringt, denn in dieser Schaltung ist zum Beispiel der Diode ein Kohlewiderstand vorgeschaltet: Der Widerstand ist ein Kaltleiter (PTC, https://secure.wikimedia.org/wikipedia/de/wiki/Kaltleiter), die Diode ein Heißleiter (NTC, https://secure.wikimedia.org/wikipedia/de/wiki/NTC). Würde man beide in die Messumgebung bringen würden sich die thermo-elektrischen Effekte beider Bauteile gegenseitig abschwächen.

Hinweis:
Im Netz finden sich natürlich auch mapping-Algorithmen, die auch nicht-linear interpolieren können - dazu benötigt man allerdings genügend Referenzwerte. Da ordentliche Algorithmen recht aufwendig (sie müssen z.B. mit Streuungen innerhalb der Referenzwerte umgehen können) und rechenintensiv sind, gehe ich darauf nicht weiter ein. Weiterhin wäre es möglich statt der Diode aus dem Beispiel, richtige NTC- oder PTC-Widerstände zu benutzen. Wer es noch professioneller haben will, sollte sich aber mit der I²C-Schnittstelle und Bausteinen wie dem DS1621 anfreunden.

Falls Sie einfach nur Temperaturen messen wollen ohne selbst zu programmieren, dann finden Sie hier die passenden Sensoren und Geräte:
www.warensortiment.de/messtechnik/regeltechnik/temperatursensoren.htm


zurück