Stellt Ihr Euch auch oft die Frage – wie warm oder kalt es ist – ich möchte Euch helfen mit dem Raspberry Pi Temperaturmessungen (mit Temperatursensor DS18B20) vorzunehmen. Dies ist einfacher als man denken mag. Zum Messen der Temperatur benötigen wir mindestens einen Temperatursensoren (DS18B20) und einen Widerstand (ca. 4,7 kOhm).
Mit Hilfe des Temperatursensors DS18B20 kann man direkt am Raspberry Pi die Temperatur messen. Der DS18B20 nutzt das 1-Wire Protokoll (Eindraht-Bus). Mit dem 1-Wire-Protokoll können verschiedene Sensoren und Schaltkreise direkt an einem einzigen GPIO-Kontakt des Raspberry Pi verwendet werden. In dem Tutorial: Raspberry Pi – Temperaturmessung sollte die verwendete Software auch mit älteren Versionen der Firmware und Raspbian funktionieren.
DS18B20 & Raspberry Pi verbinden
Der Temperatursensor DS18B20 wird mit nur drei PINs an den Raspberry Pi angeschlossen. In dem Tutorial habe ich folgende Schaltung verwendet:
Die Datenleitung des DS18B20 wird an den GPIO-Kontakt 4 (Pin 7, auch 1-Wire), die Stromversorgung (VCC) an Pin 1 und die Masse (GND – Ground) an Pin 6 oder 9 angeschlossen. Zwischen der Stromversorgungs- (Pin 1) und Datenleitung (Pin 7) sollte ein 4,7 kOhm Widerstand verwendet werden. Die Temperatursensoren DS18B20 können wie Glühbirnen einer Weihnachtskette (als Parallelschaltung) angeordnet und auslesen werden. Den Aufbau der Anschlüsse des Raspberry Pi werden sehr gut im Elektronik Kompendium (Aufbau GPIO) beschrieben.
In diesem Tutorial verwende ich ein / zwei DS18B20 in einer Parallelschaltung, jedoch solltet Ihr die Temperatur problemlos mit einem Temperatursensor auslesen können. Weitere Temperatursensoren könnt Ihr nach dem gleichem Schema hinzufügen. Auf dem Bild oben könnt Ihr meinen Steckboardaufbau mit einem DS18B20 sehen. Auf meinem Steckboard habe ich VCC an PIN 17, DATA an PIN 7 (GPIO 4) & GND an PIN 25 angeschlossen. Zum besseren Nachbau habe ich den zweiten DS18B20 weggelassen.
Den DS18B20 am Raspberry Pi testen
Mit dem Terminal (Console von Rasbian (Linux)) können wir einfach Testen und die Messergebnisse je Sensor anzeigen lassen. Im Anschluss zeige ich euch im Tutorial, wie Ihr die Messungen mit Python praktizieren und speichern könnt.
Bevor wir die Temperatur des Temperatursensor DS18B20 auslesen können, muss das “Einkabel” Protokoll (auch 1-Wire-Bus) beim Raspberry Pi aktiviert werden. Die Aktivierung des 1-Wire-Bus können wir über das Konfigurationsmenü des Raspberry PIs vornehmen.
Nebenbei möchte ich anmerken, dass in vielen anderen Tutorials – die Config.txt des Raspberry Pi – verändert werden soll. In der aktuellen Version des Rasbian Betriebssystems besteht hierzu keine Notwendigkeit und würde ich hiervon abraten.
Nach einem Neustart (Reboot) sollte euer Raspbian die benötigten Module für das One-Wire-Protokoll automatisch laden. Mit dem Befehl “sudo lsmod” können wir das im Terminal testen.
Falls die Module nicht aktiviert sind, können wir diese über das Terminal temporär aktivieren. Hierzu nutzen wir folgende Befehle im Terminal:
1 2 3 |
sudo modprobe wire sudo modprobe w1-gpio sudo modprobe w1-therm |
Mit dem Befehl “sudo lsmod” prüfen wir erneut, ob die Module geladen wurden.
Mit dem Terminal die Temperatur auslesen
Im Terminal können wir uns die Temperaturdaten des DS18B20 als Textdatei ohne Programmierung anzeigen lassen. Im Rasbian-System können wir zu dem Systempfad (“cd /sys/bus/w1/devices/”) navigieren. Mit dem Befehl “ls” werden uns die verfügbaren (Temperatur-)Sensoren als Ordner anzeigt.
Meine beiden Temperatursensoren werden mit 28-011623289bee und 28-02161f5a48ee aufgelistet. Mit dem Befehl “cat” und der Nennung des Sensor (“/w1_slave”) kann ich mir die Temperatur anzeigen lassen (“cat 28-011623289bee/w1_slave” & “cat 28-02161f5a48ee/w1_slave”). Der Wert t=18062 zeigt die Temperatur in Grad Celsius jedoch um das 1000 fache an. Hierzu müssen wir den Wert durch 1000 teilen und erhalten im unteren Beispiel 18,062 Grad Celsius.
Auslesen des DS18B20 mit Python
Mittels Python kann man sehr einfach auf die GPIO zugreifen. Hierzu besteht jedoch keine Notwendigkeit. Wir können die Temperatur wie eine Datei auslesen. Das Python-Script liest alle 10 Sekunden die Temperatur aus und schreibt die Daten in die Console (Terminal).
Codebeispiel 1
Im folgenden Codebeispiel lese ich einen Sensor alle 10 Sekunden aus und schreibe die Temperatur in die Console.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
#!/usr/bin/python3 # -*- coding: utf-8 -*- import time # Systempfad zum den Sensor, weitere Systempfade könnten über ein Array # oder weiteren Variablen hier hinzugefügt werden. # 28-02161f5a48ee müsst ihr durch die eures Sensors ersetzen! sensor = '/sys/bus/w1/devices/28-02161f5a48ee/w1_slave' def readTempSensor(sensorName) : """Aus dem Systembus lese ich die Temperatur der DS18B20 aus.""" f = open(sensorName, 'r') lines = f.readlines() f.close() return lines while True : """Mit einem Timestamp versehe ich meine Messung und lasse mir diese in der Console ausgeben.""" print(time.strftime('%H:%M:%S') +" - " + str(readTempSensor(sensor))) # Nach 10 Sekunden erfolgt die nächste Messung time.sleep(10) |
Als Ausgabe im Terminal erhalten wir folgendes:
Die Ausgabe ist für eine weitere Verarbeitung sehr unpraktisch, sodass ich das Script angepasst habe und die Temperatur als String (Zeichenkette) herauslese.
Codebeispiel 2
Im folgenden Python-Script verarbeite ich die eingelesen Zeilen zu einem Array mit den umgewandelten Temperaturen. Die Temperaturen können als Text ausgegeben und/oder zum Beispiel in einer Datenbank bzw. Datei gespeichert werden.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 |
#!/usr/bin/python3 # -*- coding: utf-8 -*- import time, sys # Systempfad zum den Sensor, weitere Systempfade könnten über ein Array # oder weiteren Variablen hier hinzugefügt werden. # 28-02161f5a48ee müsst ihr durch die eures Sensors ersetzen! sensor = '/sys/bus/w1/devices/28-02161f5a48ee/w1_slave' def readTempSensor(sensorName) : """Aus dem Systembus lese ich die Temperatur der DS18B20 aus.""" f = open(sensorName, 'r') lines = f.readlines() f.close() return lines def readTempLines(sensorName) : lines = readTempSensor(sensorName) # Solange nicht die Daten gelesen werden konnten, bin ich hier in einer Endlosschleife while lines[0].strip()[-3:] != 'YES': time.sleep(0.2) lines = readTempSensor(sensorName) temperaturStr = lines[1].find('t=') # Ich überprüfe ob die Temperatur gefunden wurde. if temperaturStr != -1 : tempData = lines[1][temperaturStr+2:] tempCelsius = float(tempData) / 1000.0 tempKelvin = 273 + float(tempData) / 1000 tempFahrenheit = float(tempData) / 1000 * 9.0 / 5.0 + 32.0 # Rückgabe als Array - [0] tempCelsius => Celsius... return [tempCelsius, tempKelvin, tempFahrenheit] try: while True : # Mit einem Timestamp versehe ich meine Messung und lasse mir diese in der Console ausgeben. print("Temperatur um " + time.strftime('%H:%M:%S') +" drinnen: " + str(readTempLines(sensor)[0]) + " °C") # Nach 10 Sekunden erfolgt die nächste Messung time.sleep(10) except KeyboardInterrupt: # Programm wird beendet wenn CTRL+C gedrückt wird. print('Temperaturmessung wird beendet') except Exception as e: print(str(e)) sys.exit(1) finally: # Das Programm wird hier beendet, sodass kein Fehler in die Console geschrieben wird. print('Programm wird beendet.') sys.exit(0) |
Ausblick
Die ausgelesenen Temperaturdaten könnten wir in einer Datei oder Datenbank speichern oder auf einem Display ausgeben. Alle drei Optionen wären zeitgleich möglich. In einem Projekt von mir speichere eine Innen- und Außentemperatur in einer MySQL-Datenbank auf einem externen Webserver.
Weiterführende Links
1-Wire auf Wikipedia – https://de.wikipedia.org/wiki/1-Wire
DS18B20 Datenblatt – https://datasheets.maximintegrated.com/en/ds/DS18B20.pdf
GPIO Belegung – https://www.elektronik-kompendium.de/sites/raspberry-pi/1907101.htm