In diesem Projekt wird ein digitaler Temperaturfühler vom Typ DS18B20 am Raspberry Pi per 1-Wire-Schnittstelle betrieben. Nach Aktivierung der 1-Wire-Schnittstelle liefert der Kernel die Messwerte über das Sysfs-Interface. Ein Python-Modul liest diese Werte ein und gibt die aktuelle Temperatur in Grad Celsius auf der Kommandozeile aus.
Der DS18B20 kommuniziert über die 1-Wire-Schnittstelle. Dabei erfolgt die gesamte Datenübertragung seriell über die DATA-Leitung (GPIO4) mit einem Pull-Up-Widerstand gegen 3.3 V.
Verdrahtung:
| Modul | Raspberry Pi GPIO |
|---|---|
| GND | beliebigen GND |
| DATA | GPIO4 (Pin 7) |
| VCC | 3.3 V |
Es kann nicht jeder beliebige GPIO-Pin verwendet werden. Standardmäßig ist dafür GPIO4 vorgesehen. Andere Pins müssen explizit über das Device-Tree-Overlay konfiguriert werden; dies wird hier nicht behandelt.
Beim DS18B20 gilt:
Ein Programm muss lediglich die Datei w1_slave auslesen.
Die Programmierung erfolgt nun immer mit der gewählten Umgebung!
source ~/devel/projects/course_env/bin/activate
Unsere Beispiel-API ist bewusst einfach gehalten und unterstützt hier nur einen einzelnen Sensor. Bei Bedarf kann die Implementierung problemlos auf mehrere Sensoren erweitert werden; darauf wird in diesem Projekt jedoch verzichtet.
import glob import time # ----------------------------- # API-Funktionen ds18b20 # ----------------------------- SENSOR_TIMEOUT = 1 # Sekunden def is_sensor(): """Prüft, ob mindestens ein DS18B20 Sensor angeschlossen ist""" sensors = glob.glob("/sys/bus/w1/devices/28-*") return len(sensors) > 0 def get_sensor(): """Gibt den ersten DS18B20 Sensor zurück oder None""" if not is_sensor(): return None sensors = glob.glob("/sys/bus/w1/devices/28-*") return sensors[0] + "/w1_slave" def get_temperature(): """Liest Temperatur vom ersten Sensor aus, None bei Fehler oder Timeout""" sensor_file = get_sensor() if sensor_file is None: return None start_time = time.time() while True: with open(sensor_file, "r") as f: lines = f.readlines() if lines[0].strip().endswith("YES"): break if time.time() - start_time > SENSOR_TIMEOUT: return None time.sleep(0.1) temp_line = lines[1] temp_str = temp_line.split("t=")[1] return float(temp_str) / 1000.0
#!/usr/bin/env python3 from hardware import get_temperature def main(): temp = get_temperature() if temp is not None: print(f"Temperatur: {temp:.2f} °C") else: print("Sensor nicht gefunden!") if __name__ == "__main__": main()
Nach dem Programmstart wird auf der Kommandozeile die Temperatur in Grad Celsius ausgegeben, sofern der Sensor korrekt erkannt wurde und die Messung erfolgreich war.
cd ~/devel/projects/course_temp_reader/src chmod 755 temp_reader.py ./temp_reader.py # Beispielausgabe: Temperatur: 21.25 °C