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