====== Projekt DS18B20 digitaler Temperatursensor ====== [[python| ☚ zurück]] //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. // ====== Überblick ====== * Voraussetzungen * 1-Wire aktivieren * Hardware ansteuern * Messprinzip * Software * Environment aktivieren * Beispiel Programm ---- ====== Details ====== ===== Voraussetzungen ===== |{{ :raspberry_pi:wire-1.png?550 |}}| | In ''raspi-config'' wird die 1-Wire-Schnittstelle aktiviert. Danach ist das Verzeichnis ''/sys/bus/w1/devices'' vorhanden. Hier erscheint dann der Sensor, falls er korrekt angeschlossen wurde.| ===== Hardware ansteuern ===== 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. |{{ :raspberry_pi:ds18b20.png?350 |}}| | Für Einsteiger sind die //etwas teureren Fertigmodule// sinnvoller, da die benötigten Zusatzbauteile (hier insbesondere der 4,7 kΩ Pull-Up-Widerstand) bereits integriert sind. Dadurch kann der **DS18B20** mit nur drei Leitungen **(VCC, GND, DATA)** direkt angeschlossen und getestet werden.| Verdrahtung: ^ Modul ^ Raspberry Pi GPIO ^ | GND | beliebigen GND | | DATA | **GPIO4** (Pin 7) | | VCC | **3.3 V ** | **Wichtig** 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: * Auflösung: 0,0625 °C (12 Bit) * Genauigkeit: ±0,5 °C * Messbereich −55 °C bis +125 °C ==== Messprinzip ==== Das Messprinzip ist unter Linux sehr einfach. **Ein Programm muss lediglich die Datei ''w1_slave'' auslesen.** |{{ :raspberry_pi:w1_device.png?600 |}}| |Mit ''cat w1_slave'' kann die Temperatur ausgelesen werden. Hier entspricht **t=21500** einer Temperatur von **21.500 °C**. | ++++ Hintergrund | Nach Aktivierung von 1-Wire über ''raspi-config'' stellt der Kernel die Temperatur als Datei im ''Sysfs'' bereit, z. B.: ''/sys/bus/w1/devices/28-000000714b90/w1_slave'' Der Name ''28-000000714b90'' ist die eindeutige ''64-Bit-ROM-ID'' des **DS18B20** und ist bei jedem Sensor unterschiedlich (Familiencode 28). Die gesamte 1-Wire-Kommunikation übernimmt der Kernel. * Bei jedem Lesezugriff auf diese Datei stößt der Kernel automatisch eine neue Temperaturumwandlung an. * In der ersten Zeile signalisiert „YES“, dass die CRC-Prüfung erfolgreich war. * In der zweiten Zeile steht der Temperaturwert hinter „t=“ in Milligrad Celsius. ++++ ===== Software ===== === Programmstruktur === |{{ :raspberry_pi:temperature_test.png?450 |}}| |Im Projektordner „course_temp_reader“ befinden sich im Verzeichnis ''src'', die beiden Dateien „hardware.py“, welche den Sensor anspricht und den Temperaturwert ausliest, sowie das kleine Testprogramm „temp_reader.py“ als Demonstration.| ==== Environment aktivieren ==== **Aktiviere die Python-Environment** Die Programmierung erfolgt nun immer mit der gewählten Umgebung! source ~/devel/projects/course_env/bin/activate ==== DS18B20 API ==== 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 ==== Temperature ==== #!/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() ==== Ausführen des Programms ==== 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