Raspberry Pi Temperatursensor (1-Wire): Temperatur messen

In diesem Tutorial soll gezeigt werden, wie man mit einem Raspberry Pi Temperatursensor die Temperatur der Umgebung auslesen kann. In einem weiteren Tutorial werden wir mittels Sensor und Lüfter für das RaspberryPi Gehäuse eine Kühlung bauen.

Vorweg sei gesagt, dass der in diesem Tutorial verwendete Raspberry Pi Temperatursensor keine Luftfeuchtigkeit oder Luftdruck messen kann. Dies ist jedoch auch ohne weiteres am Pi möglich. Wie das funktioniert, habe ich in einem anderem Tutorial erklärt.

 

Zubehör

Den Temperatursensor DS18B20 gibt es auch als wasserfeste Variante.

Beschreibung des 1-Wire Raspberry Pi Temperatursensor

Der Temperatursensor gibt einen 9 bis 12bit langen Wert zurück, welcher ausgelesen und umgewandelt werden kann. Das ist allerdings (bisher) nur an GPIO Pin 4 (Pin 7) möglich. Dafür kann man allerdings auch mehrere Sensoren in Reihe schalten (da es auf dem 1-Wire Protokoll basiert).

Aufbau

Dargestellt ist ein Aufbau mit einem Temperatursensor, als Widerstand habe ich einen 4,7k Ω genommen.

Raspberry Pi Temperatursensor 1-wire Aufbau

Raspberry Pi Temperatursensor Aufbau

Wenn alles entsprechend verkabelt ist, können wir das 1-Wire Protokoll damit aktivieren:

sudo modprobe w1-gpio
sudo modprobe w1-therm

Ob es geklappt hat, können wir herausfinden, indem wir folgendes eingeben:

lsmod

Die Module und müssten nun aufgelistet sein, falls nicht wird ein anderer GPIO Pin als 4 benutzt oder es trat ein Fehler beim aktivieren auf.

Damit nicht bei jedem Start die Module geladen werden, tragen wir sie in die Datei /etc/modules ein:

sudo nano /etc/modules

und fügen als letztes die folgenden zwei Zeilen ein:

w1_gpio
w1_therm

Für den nächsten Schritt benötigen wir als erstes die ID des Sensors. Falls du vorhast mehrere in Reihe anzuschließen, teste am besten jeden einzeln und notiere dir die ID, damit du sie später nicht verwechselst.

Wir wechseln das Verzeichnis und geben uns die Dateien aus

cd /sys/bus/w1/devices/
ls

Eine der Dateien heißt 10-000802b4ba0e (bei dir anders) und ist die ID, mit der wir den Sensor abfragen (bitte ID anpassen):

cat /sys/bus/w1/devices/10-000802b4ba0e/w1_slave

In der Ausgabe sehen wir als letzte Angabe die Temperatur (in „Milligrad“)

31 00 4b 46 ff ff 05 10 1c : crc=1c YES
31 00 4b 46 ff ff 05 10 1c t=24437

Durch 1000 geteilt macht das 24.437°C.

Um die Temperatur einfacher auszulesen, habe ich ein kleines Skript geschrieben. Wer später durch einfache eingabe von temperature die Ausgabe erhalten will, sollte es in /usr/bin/ anlegen:

sudo nano /usr/bin/temperature

Der Inhalt:

Nun noch entsprechende Rechte geben

sudo chmod +x /usr/bin/temperature

und wenn man nun in die Konsole

temperature

eingibt, so erscheint die aktuell gemessene Temperatur. Falls eine Fehlermeldung kommt, so musst du wohl bc nachinstallieren.

sudo apt-get install bc

Abschließend noch ein kleinner Tipp: Wer mit den Sensor außerhalb (z.B. aus dem Fenster hängend) messen will und durch die Fensterdichtung keine großen Kabel bekommt, dafür eignet sich ein Flachbandkabel (altes IDE oder Diskettenlaufwerkkabel). Gut eingepackt in einen Frischhaltebeutel ist das ganze dann auch wetterfest (Luft rauslassen und gut zukleben, dann beeinflusst es die Messung auch nur minimal).

49 Kommentare

  1. Danke für diesen Informativen Beitrag,
    die Formatierung temp=`echo "scale=2; "`echo ${tempread: -5 }`" / 1000" | bc` hatt aber einen Fehler:
    Ist die Temperatur kleiner 10 °C gibt es keine ausgabe mehr!
    Lg

    Antworten
    • Vielen Dank für den Hinweis, du hast natürlich recht. Das lag daran, dass ich immer die letzten 5 Zahlen genommen haben.
      Ich habe es nun mal geändert, indem nur noch die Zahlen nach dem letzten Gleichheitszeichen genommen werden. Damit sind auch kleinere Werte möglich.
      temp=`echo "scale=2; "`echo ${tempread:##*=}`" / 1000" | bc`

      LG Felix

      Antworten
  2. Hallo,
    ich komme schon bei „cd /sys/bus/w1/devices/ und ls“ nicht weiter. Der Pfad ist leer, also keine ID vorhanden.
    Ich hoffe du kannst mir helfen.

    Mfg
    Roland

    Antworten
  3. Hallo,

    erstmal vielen Dank für das tolle Tutorial.
    Bei mir klappt es jetzt.
    Allerdings musste ich die eine Zeile so schreiben:
    temp=`echo "scale=2; "`echo ${tempread##*=}`" / 1000" | bc`
    Also ohne den Doppelpunkt in den geschweiften Klammern.

    Viele Grüße
    Sven

    Antworten
  4. Hallo,

    wieso muss eigentlich die Stromversorgung (5.0V) mittels eines 4.7k Widerstand an den Data-Wire des DS18B20 angeschlossen sein. Also erstens wieso die Spannung dahin und wieso die 4.7k Ohm. Ich verstehe, dass der Raspberry am GPIO keine 5V verträgt aber wie lautet die Formel, mit der man errechnet, dass mittels eines 4.7k Widerstand die Spannung von 5.0V auf die des GPIO (3.3V) angepasst wird.

    – Bin ein Laie ^^

    Antworten
    • Der GPIO darf maximal 3.3V bekommen, aber das Problem ist, wenn gar keine Spannung anliegt wird ein zufälliger Wert (High oder Low) ausgegeben. Um das zu verhindern schalten wir über einen sehr großen Widerstand eine Spannung (an VCC oder GND, je nachdem ob Pull-Up/Down), um diesen Effekt zu verhindern.

      Antworten
  5. Hallo zusammen,

    ist bei diesem Setup eine Leitungslänge zwischen dem PI und dem Temperatur Sensor von circa 15-20 Meter möglich?

    Danke vorab!
    Peter

    Antworten
    • Du müsstest mal schauen wie hoch der Spannungsabfall bei 15-20m ist. Kommt aber auch auf das Trägermaterial (Kupfergehalt etc.) an.
      Falls du es testest, würde mich das Ergebnis auch interessieren.
      LG Felix

      Antworten
  6. Hallo,
    bei mir wird keine Datei angezeigt, wenn ih im Verzeichnis w1/devices bin. Also ich gebe ls ein und nichts passiert.
    Bin totaler Anfänger.

    LG Björn

    Antworten
  7. Hallo,
    habe das gleich Problem wie Felix, Jan und Björn. Die Module sind geladen, auch nach einem Neustart, aber der devices Ordner ist leer.
    Jemand eine Idee

    Antworten
    • Danke, das war der Hinweis, den auch ich benötigt habe. Bei mir war das Verzeichnis ebenso leer, aber nach dem Anpassen der boot/config.txt und Neustart funktioniert nun alles wunderbar!

      Antworten
  8. Prima Tutorial, hat auf Anhieb funktioniert, vielen Dank!
    Aber Du meinst bestimmt : mehrere Sensoren werden parallel geschaltet, oder?
    Wie soll man denn sonst ein 1-Wire-System anschließen?

    Antworten
  9. gibt es eine Möglichkeit die Temperatur irgendwie grafisch darzustellen? Wenn Ja wie? ählich dem RPI-Monitor.

    Antworten
  10. Vielen Dank für diese hilfreiche Seite. Die Sensoren lassen sich problemlos auslesen.
    Ich habe folgene Fragen zur Funktion:
    1.) Wie häufig aktuallisiert des System die Temperaturwerte?
    2.) Es finden ja ständig Schreibzyklen auf dem Flashspeicher statt. Flashspeicher erlauben im allgemeinen nur eine begrenzte Anzahl von Schreibzyklen (zwischen 10.000 und 1.000.000)
    Bei angenommen einer Aktuallisierung pro Sekunde sind das 3600 Schreibzyklen pro Stunde. Ist meine Annahme korrekt? Wie sieht das mit der Langzeitstabilität aus?
    Vielen Dank für die Bemühungen im Voraus.

    Antworten
    • Hi Torsten,
      das ist eine gute Frage. Ich habe eben mal einen Blick ins Datenblatt geworfen, aber konnte dazu nichts genaueres finden, außer dass beim Initialisieren der Speicher einmal ausgelesen wird. Ich nehme an, dass erst beim Aufruf doe Aktion zum auslesen getriggert wird und somit nicht zwischengespeichert wird.
      LG, Felix

      Antworten
  11. Danke erstmal für das Tutorial.

    Ich möchte mehrere Temperatur Sensoren an den anschliessen (8 Stück) das geht in 1-Wire kann ich dann jeden einzelnen auslesen es sollen mehrere Temperaturen erfasst werden um dieverse Pumpen und Elektro Ventile zu steuern.

    Antworten
  12. ist die zeichnung korrekt mit der wölbung nach hinten und rechts vcc?
    Denn im datenblatt steht es anders herum

    Antworten
      • Hallo Felix
        ich habe auch das Gefühl, dass in der Grafik was nicht stimmt.
        Bisher dachte ich der LM34 ist ein reiner Analog-Temperatur-Fühler der nicht für 1-wire genutzt werden kann oder liege ich hier falsch?
        Die Wölbung des LM34 in der Grafik scheint mit zudem verkehrt herum zu sein. Lt. Datenblatt ist beim LM34 wenn man von unten auf Pin schaut (flache Seite nach oben ) folgende Pinfolge: +Vs/Vout/GND.
        Stammt die Grafik vielleicht von einem DS18B20? Da würde die Wölbung zu den Anschlüssen passen – beim DS18B20 ist die Pinbelegung (bei gleicher Betrachtungsweise) genau umgekehrt zum LM34: GND/Vout/+Vs.
        Kannst du das vielleicht nochmal prüfen? Danke

  13. Hallo Felix..
    Super tut – vielleicht solltest Du aber die notwendige Änderung der /boot/config.txt in Dein tut aufnehmen…
    Eine Frage hab ich dennoch: wie kann ich es anstellen mehrere Temperatursensoren zyklisch auszulesen und für eine GUI (in python) zur Verfügung zu stellen?

    LG Skipper

    Antworten
    • Hi Skipper,
      Ich stehe vor der gleichen Aufgabe und würde mich interessieren ob du mittlerweile eine Lösung gefunden hast, um mehrere Sensoren auszulesen und per GUI anzeigen zu lassen.
      Ich möchte mehrere Temperatur- und Luftfeuchtigkeitswerte per Raspy loggen und suche dafür eine passende Lösung / Programm.
      Schön wäre eine Anzeige in Tabellenform aber auch in einer GUI Maske und idealerweise mit Kurvendiagramm (mit einstellbarem Zeitfenster per GUI)….
      Gruss
      Jay

      Antworten
  14. Hallo, ich muss gestehen, ich scheitere schon am Schaltbild. Wieso geht der rote Draht rechts zum Pluspol (über die untere Verbindung) und verbindet sich über die selbige mit dem Widerstand zum grünen Draht in der Mitte? Ist das wirklich so? Dacht der mittlere Wäre die Datenverbindung, die zum GPIO geht und nicht an irgendwelchem Pol anliegt.

    Antworten
  15. Hallo Felix
    Ich habe alles soweit angeschlossen
    Und auch die ID abgeändert die bei mir
    Angezeigt wird .Dennoch wenn ich Temperatur eingebe kommt zwar “ Die Temperatur ist“ aber kein Wert. Hast Du eine Idee .

    Udo

    Antworten
      • hat sich erledigt ,ich habe vergessen die ID in den Editor zu ändern.
        Dankeschön für die Promte Antwort .

        Und auch von mir noch einmal ,eine sehr schöne HP und Super Tutorials und sehr gut erklärt

        Udo

  16. Hallo Felix,

    Wie kann man den die Temperatur in ein anderes Programm mit einbinden möchte den Schrittmotor 28BYJ-48 mit ULN2003 Driver Board bei z.b 90° eine volle Umdrehung nach Links machen lassen und bei z.b. 100° eine volle Umdrehung nach Rechts.

    MFG Daniel

    Antworten
  17. Hallo Felix ,ich möchte den temperatur wert im programm mit verarbeiten,
    Wie muss ich das machen ,hast du eine Idee .

    Udo

    Antworten
  18. Hallo Felix,
    Ich möchte meine Heizung der Waschmaschine damit Regeln .
    Wenn zB. 30 C erreicht ist soll er sie abschalten .Die Temperratur kann ich mit os.system („Temperatur“)auslesen das Funktioniert .

    Udo

    Antworten
    • Genau, dann musst du nur noch das Shell-Skript so umändern, dass es nur noch den Wert zurück gibt, bzw. cat /sys/bus/w1/devices/10-000802b4ba0e/w1_slave` per os.system ausführen und entsprechend formatieren.

      Antworten
  19. Hallo Felix ,
    Das ganze werde ich so machen ,ich gebe bescheid wenn es Funktioniert

    Dankeschön für deine prompte hilfe

    Udo

    Antworten
  20. Hallo Felix ,
    ich habe das Shell Skript so abgeändert das ich es per os.system(„temperature“) aufrufen kann ,
    dann bekomme ich nur die Temperature angezeigt ,aber das programm kann damit nichts anfangen.
    Hast Du noch einen Tipp .

    Udo

    Antworten
  21. Hallo Felix ,
    das Programm ist noch ein bisschen einfach bin es noch am ausbauen .Die Komponenten der Maschine Funktionieren aber schon. Ich hoffe es kommt so an .Danke für deine Hilfe .

    Udo

    import RPi.GPIO as GPIO
    import time
    import os
    os.system("clear")
    os.system("temperature")# Shell-Skript ist so abgeändert damit er nur noch den Wert ausgibt.Die Temperatur möchte ich dann für die Heizung nehmen .kommt noch
    GPIO.setmode(GPIO.BCM)
    GPIO.setwarnings(False)
    GPIO.setup(27, GPIO.OUT) # Heizung
    GPIO.setup(22, GPIO.OUT) # Motor an
    GPIO.setup(23, GPIO.OUT) # Wasser 1
    GPIO.setup(24, GPIO.OUT) # Wasser 2
    GPIO.setup(25, GPIO.OUT) # Pumpe
    GPIO.setup(15, GPIO.OUT) # Tuere Auf
    GPIO.setup(18, GPIO.OUT) # Drehrichtung beide Relais muessen an sein
    GPIO.setup(11, GPIO.OUT) # Drehrichtung beide Relais muessen an sein
    
    time.sleep(5)
    print("                                                                  Hallo Willkommen zum Raspberry Pi Waschmaschinen Programm ")
    
    y = int(raw_input(" Wasser Laufzeit "))
    
    time.sleep(5)
    print(" Tuere Verriegelt ")# hier kommt natuertlich "GPIO.output(x, GPIO.High) oder GPIO.output(x,GPIO.LOW)
    time.sleep(5)
    print(" Wasser 1 Ein ")# hier kommt natuertlich "GPIO.output(x, GPIO.High) oder GPIO.output(x,GPIO.LOW)
    time.sleep(y)
    print(" Wasser 1 Aus ")# hier kommt natuertlich "GPIO.output(x, GPIO.High) oder GPIO.output(x,GPIO.LOW)
    time.sleep(5)
    
    i = 1
    
    x = int(raw_input("Motor Laufzeit s "))
    
    while i <= 4:
    
                    time.sleep(x)
                    print(" Motor rechts ")# hier kommt natuertlich "GPIO.output(x, GPIO.High) oder GPIO.output(x,GPIO.LOW)
                    time.sleep(x)
                    print(" Motor Stop ")# hier kommt natuertlich "GPIO.output(x, GPIO.High) oder GPIO.output(x,GPIO.LOW)
                    time.sleep(x)
                    print(" Motor Links ")# hier kommt natuertlich "GPIO.output(x, GPIO.High) oder GPIO.output(x,GPIO.LOW)
                    time.sleep(x)
                    print(" Motor Stop ")# hier kommt natuertlich "GPIO.output(x, GPIO.High) oder GPIO.output(x,GPIO.LOW)
                    i += 1
    else :
                    time.sleep(5)
                    print(" Pumpe ")# hier kommt natuertlich "GPIO.output(x, GPIO.High) oder GPIO.output(x,GPIO.LOW)
                    time.sleep(5)
                    print(" Tuere Endriegelt ")# hier kommt natuertlich "GPIO.output(x, GPIO.High) oder GPIO.output(x,GPIO.LOW)
                    time.sleep(5)
                    print(" Ende ")
    Antworten

Hinterlasse einen Kommentar

Deine Email Adresse wird nicht veröffentlicht.

Blog abonnieren

Abonniere Raspberry Pi Tutorials, um kein Tutorial mehr zu verpassen!