Benutzer-Werkzeuge

Webseiten-Werkzeuge


projekt:python_projekt_ds18b20_digitaler_temperatursensor

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Beide Seiten der vorigen RevisionVorhergehende Überarbeitung
Nächste Überarbeitung
Vorhergehende Überarbeitung
projekt:python_projekt_ds18b20_digitaler_temperatursensor [2026/02/20 08:06] – [Überschrift] torsten.roehlprojekt:python_projekt_ds18b20_digitaler_temperatursensor [2026/02/23 12:09] (aktuell) – [Ausführen des Programms] torsten.roehl
Zeile 3: Zeile 3:
 [[python| ☚ zurück]] [[python| ☚ zurück]]
  
-FIXME  BEITRAG IN ENTSTEHUNG+ 
 +//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 ====== ====== Überblick ======
-  * Hardware ansteuern +  * Voraussetzungen 
-  Environment aktivieren+      * 1-Wire aktivieren 
 +  * Hardware ansteuern  
 +      Messprinzip
   * Software   * Software
 +     * Environment aktivieren
 +     * Beispiel Programm
    
  
  
 ---- ----
- 
 ====== Details ====== ====== Details ======
  
 +===== Voraussetzungen =====
  
-<code python> +|{{ :raspberry_pi:wire-1.png?550 |}}| 
-# ds18b20_smart.py +|<WRAPIn ''raspi-config'' wird die 1-Wire-Schnittstelle aktiviertDanach ist das Verzeichnis ''/sys/bus/w1/devices'' vorhanden. Hier erscheint dann der Sensor, falls er korrekt angeschlossen wurde.</WRAP>|
-import glob +
-import time+
  
-def is_sensor(): +===== Hardware ansteuern  =====
-    """Prüft, ob mindestens ein DS18B20 Sensor angeschlossen ist""" +
-    sensors glob.glob("/sys/bus/w1/devices/28-*"+
-    return len(sensors) > 0+
  
-def get_sensor(): +Der DS18B20 kommuniziert über die 1-Wire-SchnittstelleDabei erfolgt die gesamte Datenübertragung seriell über die DATA-Leitung (**GPIO4**mit einem Pull-Up-Widerstand gegen <color #ed1c24>3.3 V</color>.
-    """ +
-    Gibt automatisch den ersten Sensor zurück. +
-    Ruft intern is_sensor() auf. +
-    Gibt None zurück, wenn kein Sensor da ist. +
-    """ +
-    if not is_sensor(): +
-        return None +
-    sensors = glob.glob("/sys/bus/w1/devices/28-*"+
-    return sensors[0] + "/w1_slave"+
  
-def get_temperature()+|{{ :raspberry_pi:ds18b20.png?350 |}}| 
-    """ +| Für Einsteiger sind die //etwas teureren Fertigmodule// sinnvollerda die benötigten Zusatzbauteile (hier insbesondere der 4,7 kΩ Pull-Up-Widerstandbereits integriert sindDadurch kann der **DS18B20** mit nur drei Leitungen **(VCCGND, DATA)** direkt angeschlossen und getestet werden.|
-    Liest die Temperatur vom ersten Sensor aus. +
-    Nutzt intern get_sensor(). +
-    Gibt None zurückwenn kein Sensor gefunden wird. +
-    """ +
-    sensor_file = get_sensor(+
-    if sensor_file is None: +
-        return None  # Clever: kein Fehlereinfach None +
-    with open(sensor_file, "r"as f: +
-        lines = f.readlines() +
-    while lines[0].strip()[-3:] != "YES": +
-        time.sleep(0.2) +
-        with open(sensor_file"r"as f: +
-            lines = f.readlines() +
-    temp_line = lines[1] +
-    temp_str = temp_line.split("t=")[1] +
-    return float(temp_str) / 1000.0+
  
-# -------- Beispiel Nutzung -------- 
-if __name__ == "__main__": 
-    temp = get_temperature() 
-    if temp is None: 
-        print("Kein DS18B20 Sensor gefunden – bitte prüfen!") 
-    else: 
-        print(f"Aktuelle Temperatur: {temp:.2f} °C") 
  
 +Verdrahtung:
 + 
 +^ Modul ^ Raspberry Pi GPIO ^
 +| GND   | beliebigen GND  |
 +| <color #ffc90e>DATA</color>    | **GPIO4** (Pin 7) |
 +| <color #ed1c24>VCC </color> | **<color #ed1c24>3.3 V </color>**  |   
 +
 +
 +
 +
 +<note tip>**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.
 +</note>
 +
 +Beim DS18B20 gilt:
 +  * Auflösung: 0,0625 °C  (12 Bit)
 +  * Genauigkeit: ±0,5 °C
 +  * Messbereich −55 °C bis +125 °C
 +==== Messprinzip ====
 +
 +<note>Das Messprinzip ist unter Linux sehr einfach.
 +
 +**Ein Programm muss lediglich die Datei ''w1_slave'' auslesen.**
 +</note>
 +
 +|{{ :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 ====
 +
 +
 +<note important>
 +**Aktiviere die Python-Environment**
 +
 +Die Programmierung erfolgt nun immer mit der gewählten Umgebung!
 +<code>
 +source ~/devel/projects/course_env/bin/activate
 </code> </code>
  
-====== Überschrift ======+</note> 
 +==== 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.
  
  
-<code python+<code python hardware.py 
-# ds18b20_smart.py+
 import glob import glob
 import time import time
  
  
-def is_sensor(): +# ----------------------------- 
-    """ +# API-Funktionen ds18b20 
-    Prüft, ob mindestens ein DS18B20 Sensor angeschlossen ist. +----------------------------- 
-    """ +SENSOR_TIMEOUT = 1  # Sekunden
-    return bool(glob.glob("/sys/bus/w1/devices/28-*"))+
  
 +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(): def get_sensor():
-    """ +    """Gibt den ersten DS18B20 Sensor zurück oder None""" 
-    Gibt automatisch den ersten Sensor zurück+    if not is_sensor():
-    Ruft intern is_sensor() auf. +
-    Gibt None zurück, wenn kein Sensor da ist. +
-    """ +
-    sensors = glob.glob("/sys/bus/w1/devices/28-*") +
-    if not sensors:+
         return None         return None
 +    sensors = glob.glob("/sys/bus/w1/devices/28-*")
     return sensors[0] + "/w1_slave"     return sensors[0] + "/w1_slave"
  
- +def get_temperature(): 
-def get_temperature(timeout=5): +    """Liest Temperatur vom ersten Sensor ausNone bei Fehler oder Timeout"""
-    """ +
-    Liest die Temperatur vom ersten Sensor aus+
-    Nutzt intern get_sensor(). +
-    Gibt None zurück, wenn kein Sensor gefunden wird +
-    oder ein Timeout auftritt. +
-    """+
     sensor_file = get_sensor()     sensor_file = get_sensor()
     if sensor_file is None:     if sensor_file is None:
Zeile 107: Zeile 129:
  
     start_time = time.time()     start_time = time.time()
- 
     while True:     while True:
-        try: +        with open(sensor_file, "r") as f: 
-            with open(sensor_file, "r") as f: +            lines = f.readlines()
-                lines = f.readlines() +
-        except OSError: +
-            return None+
  
         if lines[0].strip().endswith("YES"):         if lines[0].strip().endswith("YES"):
             break             break
  
-        if time.time() - start_time > timeout:+        if time.time() - start_time > SENSOR_TIMEOUT:
             return None             return None
  
-        time.sleep(0.2)+        time.sleep(0.1)
  
-    try: +    temp_line = lines[1] 
-        temp_str = lines[1].split("t=")[1] +    temp_str = temp_line.split("t=")[1] 
-        return float(temp_str) / 1000.0 +    return float(temp_str) / 1000.0 
-    except (IndexError, ValueError): +</code>
-        return None+
  
 + 
 +==== Temperature ====
  
--------- Beispiel Nutzung -------- +<code python temp_reader.py > 
-if __name__ == "__main__": +#!/usr/bin/env python3
-    temp = get_temperature()+
  
-    if temp is None: +from hardware import get_temperature 
-        print("Kein DS18B20 Sensor gefunden oder Lesefehler!")+ 
 +def main(): 
 +    temp = get_temperature() 
 +    if temp is not None: 
 +        print(f"Temperatur: {temp:.2f} °C")
     else:     else:
-        print(f"Aktuelle Temperatur: {temp:.2f} °C")+        print("Sensor nicht gefunden!"
 + 
 +if __name__ == "__main__": 
 +    main()
 </code> </code>
 +
 +==== 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.
 +
 +<code bash>
 +cd ~/devel/projects/course_temp_reader/src
 +chmod 755 temp_reader.py
 +./temp_reader.py
 +
 +# Beispielausgabe:
 +Temperatur: 21.25 °C
 +</code>
 +
 +
  
projekt/python_projekt_ds18b20_digitaler_temperatursensor.1771574802.txt.gz · Zuletzt geändert: von torsten.roehl