Benötigst du für ein Projekt die aktuelle Temperatur? In diesem Tutorial lernst du wie du analoge Temperaturmodule mit dem Arduino nutzt.
Ein Temperaturmodul ist eine interessante Option für Einsteigerprojekte mit dem Arduino. Man kann beispielsweise einen Ventilator steuern, einen Frostwächter oder sogar eine kleine Wetterstation bauen. Es gibt viele Projekte, die mit Temperatursensoren arbeiten, und ich möchte dich dazu ermutigen, deine eigenen zu entwickeln. In diesem Tutorial wirst du lernen, wie du analoge Temperaturmodule mit dem Arduino benutzen kannst. Diese Module verwenden typischerweise einen NTC-Thermistor. Wenn du mehr über Thermistoren wissen willst, dann schau dir die Hintergrund-Tutorials zu Thermistoren und den Temperaturberechnungsformeln an.
Bevor wir fortfahren, möchte ich darauf hinweisen, dass es verschiedene analoge Temperaturmodule gibt. Es gibt zwei Haupttypen: Temperaturschalter und Module zur Messung eines absoluten Temperaturwertes. Das Bild zeigt den ersteren Typ auf der linken Seite und den zweiten auf der rechten Seite. In diesem Tutorial werden wir uns auf die Temperaturmessung konzentrieren. Ich habe das Modul KY-013 verwendet, werde aber auch zeigen, wie du einen NTC-Thermistor direkt verwenden kannst. Für Projekte, bei denen der eigentliche Temperaturwert nicht benötigt wird, sollte der erste Typ als einfacher zu verwendende Alternative in Betracht gezogen werden. Bei diesen Modulen ist es möglich, mit einem Potentiometer einen Schwellenwert einzustellen. Die Module verfügen über einen digitalen Ausgang, der sich ändert, sobald dieser Schwellenwert überschritten wird. Wir werden uns diese Alternative im nächsten Tutorial näher ansehen. Genug geredet, fangen wir an!
Das Anschließen des Temperaturmoduls an das Arduino ist relativ einfach. Der Pin für das Ausgangssignal ist mit einem S
gekennzeichnet und muss mit einem analogen Pin des Arduino verbunden werden. Ich habe Pin A0
gewählt. Als Nächstes müssen wir die Versorgungsspannung anschließen. Bei meinem Modul muss GND
mit dem linken Pin, der mit –
markiert ist, verbunden werden. Der mittlere Pin wird mit 5V
verbunden.
Neben dem Anschlussplan habe ich den Schaltplan des Moduls abgebildet. Es handelt sich im Prinzip um eine einfache Spannungsteilerschaltung zur Widerstandsmessung mit dem NTC-Thermistor und einem Festwiderstand von 10 kΩ als R1.
Es gibt anscheinend einige KY-013-Module, die falsch herum beschriftet sind. Wenn der Code aus diesem Tutorial nicht funktioniert, dann musst du die korrekte Belegung mit einem Multimeter herausfinden. Durch Messen des Widerstandes lässt sich der Analogausgang S
leicht identifizieren. Der Ausgangspin besitzt einen Widerstand von etwa 10 kΩ zu den beiden anderen Pins. Wenn bei Erwärmung des Sensors niedrigere Temperaturwerte im seriellen Monitor ausgegeben werden, müssen 5V
und GND
vertauscht werden.
Wie können wir nun die Temperatur berechnen?
Wir müssen die Spannung an A0
messen und dann Widerstand und Temperatur berechnen:
// Measurements and Calculations
float voltage = analogRead(A0)*5/1024.0;
float resistance = calculateSensorResistance(voltage);
float temperature = calculateTemperature(resistance);
Der Code verwendet zwei Hilfsfunktionen: calculateSensorResistance
berechnet den Widerstand des Thermistors anhand der gemessenen Spannung und calculateTemperature
berechnet schließlich den Temperaturwert in Grad Celsius. Wenn du die Temperatur Grad Fahrenheit benötigst, ist ein zusätzlicher Schritt notwendig, um das Ergebnis umzurechnen. Dies kann mit einer einfachen Umrechnungsfunktion gelöst werden:
float convertTemperatureFahrenheit(float tDegree) {
return tDegree/5.0*9.0 + 32.0;
}
Werfen wir einen Blick auf die Widerstandsberechnung. Wir können einfach die Spannungsteilerformel verwenden und sie nach R2 auflösen. Die Eingangsspannung beträgt 5 V. R1 ist unser fester 10 kΩ Widerstand. Im Code habe ich seinen Widerstand R_FIXED
genannt. Der daraus resultierende Code für die Widerstandsberechnungsfunktion sieht wie folgt aus:
// Fixed resistor in voltage divider
const float R_FIXED = 10000;
float calculateSensorResistance(float voltage) {
return R_FIXED / (5.0/voltage - 1);
}
Als Nächstes die Hilfsfunktion für die Temperaturberechnung. Ich habe mich für die Verwendung der Beta-Formel entschieden. Zur Berechnung der korrekten Temperaturanzeige müssen wir den Betawert des Thermistors kennen, der auf dem Modul KY-013 verbaut ist. In meinem Fall ist dies 3435 K. Der entsprechende Code für die Temperaturberechnung dann wie folgt aus:
// Temperature sensor
const float B = 3435;
const float R0 = 10000;
const float ABS_ZERO = -273.15;
const float T0 = 25-ABS_ZERO;
float calculateTemperature(float resistance) {
return 1.0 / (log(resistance/R0)/B+1.0/T0) + ABS_ZERO;
}
Verschiedene NTC-Thermistoren weisen unterschiedliche Temperatur-Widerstandskurven auf. Der Betawert ist spezifisch für den NTC-Thermistor, der auf deinen KY-013-Modul genutzt wird. Leider kann es Versionen dieses Moduls geben, die einen anderen Thermistor verwenden. Wenn die in der seriellen Konsole angezeigten Temperaturwerte nicht stimmen, dann überprüfe, ob du den Betawert verwendet hast, der im Datenblatt deines Thermistors angegeben ist. Informationen darüber, wie man herausfindet, welchen Sensor man besitzt, auch wenn man kein Datenblatt hat, findest du im Hintergrund-Tutorial zu den Temperaturberechnungsformeln. Dort ist eine mögliche Prozedur zur Kalibrierung des Sensors beschrieben.
Lass uns nun alles zu einem Arduino-Programm kombinieren, das die Messungen auf dem seriellen Monitor ausgibt. Der vollständige Code sieht wie folgt aus:
// Temperature sensor
const float B = 3435;
const float R0 = 10000;
const float ABS_ZERO = -273.15;
const float T0 = 25-ABS_ZERO;
float calculateTemperature(float resistance) {
return 1.0 / (log(resistance/R0)/B+1.0/T0) + ABS_ZERO;
}
float convertTemperatureFahrenheit(float tDegree) {
return tDegree/5.0*9.0 + 32.0;
}
// Fixed resistor in voltage divider
const float R_FIXED = 10000;
float calculateSensorResistance(float voltage) {
return R_FIXED / (5.0/voltage - 1);
}
void setup() {
// Init Serial Port
Serial.begin(9600);
}
void loop() {
// Measurements and Calculations
float voltage = analogRead(A0)*5/1024.0;
float resistance = calculateSensorResistance(voltage);
float temperature = calculateTemperature(resistance);
float temperatureF = convertTemperatureFahrenheit(temperature);
// Print out result
Serial.print("Voltage (V): ");
Serial.println(voltage);
Serial.print("Resistance (Ohm): ");
Serial.println(resistance);
Serial.print("Temperature (°C): ");
Serial.println(temperature);
Serial.print("Temperature (°F): ");
Serial.println(temperatureF);
// Wait for 1s
delay(1000);
}
Nachdem du den Code auf den Arduino hochgeladen hast, öffne den seriellen Monitor. Dort sollten die Messwerte angezeigt werden:
Voltage (V): 2.61
Resistance (Ohm): 10940.69
Temperature (°C): 22.69
Temperature (°F): 72.84
Statt eines vorgefertigten Moduls könnten wir auch einen beliebigen 10 kΩ NTC-Thermistor verwenden. Wir brauchen nur einen zusätzlichen 10 kΩ Widerstand und können dann die Spannungsteilerschaltung selbst aufbauen.
Du hast vielleicht bemerkt, dass es einen Unterschied zur Schaltung des Originalmoduls gibt. Ich habe mich dafür entschieden, den NTC-Thermistor an der Stelle einzubauen, an der R1 in der ursprünglichen Schaltung war. Der Festwiderstand ist jetzt R2. Es hat keinen besonderen Vorteil, die beiden Bauteile zu vertauschen, aber ich empfinde es als etwas natürlicher, eine Schaltung zu verwenden, bei der die Spannung mit steigender Temperatur zunimmt. Dies ist jedoch eine Frage des persönlichen Geschmacks. Du hast jetzt beide Varianten kennengelernt. Fühl dich frei, die zu nutzen, die dir besser gefällt. Natürlich müssen wir den Code an unser neues Schaltungslayout anpassen. Dazu lösen wir die Spannungsteilerformel für R1 anstelle von R2:
float calculateSensorResistance(float voltage) {
return R_FIXED * (5.0/voltage - 1);
}
Nachdem das erledigt ist, müssen wir den Code an den NTC anpassen. Der von mir genutzte Sensor hat einen Betawert von 4300 K. Der angepasste Temperaturcode sieht also wie folgt aus:
// Temperature sensor
const float B = 4300;
const float R0 = 10000;
const float ABS_ZERO = -273.15;
const float T0 = 25-ABS_ZERO;
float calculateTemperature(float resistance) {
return 1.0 / (log(resistance/R0)/B+1.0/T0) + ABS_ZERO;
}
Falls du die Steinhart-Hart-Gleichung anstelle der Beta-Formel verwenden möchten, musst du die Funktion calculateTemperature
so anpassen, dass sie die Steinhart-Hart-Gleichung mit den drei Koeffizienten \(a\), \(b\) und \(c\) deines NTCs nutzt:
// Temperature sensor
const float a = 0.00129495;
const float b = 0.000215997;
const float c = 0.000000891608;
const float ABS_ZERO = -273.15;
float calculateTemperature(float resistance) {
float logR = log(resistance);
return 1.0 / (a + b * logR + c * logR * logR * logR) + ABS_ZERO;
}
Verschiedene NTC-Thermistoren weisen unterschiedliche Temperatur-Widerstandskurven auf. Der Betawert und die Steinhart-Hart-Koeffizienten sind spezifisch für den Typ des jeweiligen NTCs. Wenn die in der seriellen Konsole angezeigten Temperaturwerte nicht stimmen, dann überprüfe, ob du den Betawert oder die Koeffizienten verwendet hast, die im Datenblatt deines Thermistors angegeben sind. Die im obigen Code gezeigten Steinhart-Hart-Koeffizienten sind für meinen NTC-Thermistor mit einem Betawert von 4300 K berechnet. Informationen darüber, wie man herausfindet, welchen Sensor man besitzt, auch wenn man kein Datenblatt hat, findest du im Hintergrund-Tutorial zu den Temperaturberechnungsformeln. Dort ist eine mögliche Prozedur zur Kalibrierung des Sensors beschrieben.
Wenn du die Temperaturmesswerte des Arduino mit anderen Temperaturmodulen oder Thermometern vergleichst, wirst du wahrscheinlich Abweichungen in den Messwerten feststellen. NTC-Thermistoren besitzen immer eine gewisse Ungenauigkeit. Diese liegt gewöhnlich im Bereich von ± 0,5 °C bei 25 °C.
Die traurige Wahrheit ist, dass es eine weitere Quelle für potentielle Ungenauigkeiten gibt. Die Messungen werden mit der 5-V-Eingangsspannung als Spannungsreferenz durchgeführt. Das ist das, was wir in unserem Code angenommen haben. Daran ist nichts falsch, außer dass die Versorgungsspannung des Arduino, wenn er über USB versorgt wird, möglicherweise nicht exakt 5 V beträgt. Der zulässige Spannungsbereich laut USB-Spezifikation beträgt 4,4 V bis 5,25 V für USB 2.0 und 4,45 V bis 5,25 V für USB 3.0. Normalerweise liegt die Spannung ziemlich nahe an 5 V und es sollte kein Problem geben. Es gibt jedoch keine Garantie dafür. Wenn du auf Probleme stößt, überprüfe die Versorgungsspannung mit einem Multimeter.
Wenn die Versorgungsspannung abweicht, erhöht sich die Ungenauigkeit unserer Messung. Eine mögliche Lösung ist es, zusätzlich eine Batterie an die DC-Buchse des Arduino anzuschließen. Der Arduino schaltet dann automatisch auf die DC-Buchse um und verwendet die 5-V-Spannung, die vom eingebauten Spannungsregler erzeugt wird. Auch dieser Regler ist nicht hundertprozentig genau, aber in der Regel gut genug für die meisten Anwendungsfälle. Die Alternative wäre, die tatsächliche Versorgungsspannung zu messen und den gemessenen Wert für die Berechnung zu verwenden, aber das ist ein Thema für ein eigenes Tutorial.
Für die meisten Projekte spielt die Genauigkeit ohnehin keine große Rolle. Wenn man sie allerdings wirklich braucht, sollte man lieber einen vorkalibrierten digitalen Temperatursensor nutzen.