Mehrere DS1820 Sensoren am Raspberry Pi mit Python einlesen

Veröffenticht am 08.10.2016    von     in der Kategorie Raspberry Pi, Sensoren     bisher 23 Reaktionen    Zuletzt überarbeitet am 21.02.2017


Der in diesem Beitrag veröffentlichte Programm-Code soll die automatische Einbindung der am 1-Wire Bus des Raspberry Pi angeschlossenen DS1820 Sensoren ermöglichen. Dieses soll dir die Einbindung der Sensoren in das Python Programm vereinfachen bzw. soll das Programm auch nach einem Wechsel des Sensors weiter funktionieren.

Die notwendigen Schritte zur Einbindung der Sensoren in Raspbian findest du in meinem Beitrag “Temperatur-Sensor DS1820 am Raspberry Pi mit Python“, für welchen das folgende Programm als Erweiterung dienen soll.

Anschluss der DS1820 Sensoren

Wie folgendes Steckplatinen-Schaubild verdeutlichen soll, kannst du die DS1820 Temperatursensoren in Reihe an den 1-Wire-Port des Raspberry Pi schließen. Der Widerstand ist nur einmal notwendig.

Schaubild von mehreren DS1820 Sensoren am Raspberry Pi

Die fritzing Projektdatei habe ich für dich zum Download bereitgestellt.

Funktionsweise des Programmcodes

DS1820 Sensoren einlesen

Da jeder Sensor am 1-Wire Bus eine eigene ID hat, der DS18B20 Sensor hat die Kennung “28-xxx” und der DS18S20 Sensor die Kennung “10-xxxx”, wird in ds1820einlesen() das Verzeichnis der Sensoren am 1-Wire Bus ausgelesen.

Temperaturwerte auslesen

In ds1820auslesen() werden gem. der ermittelten Anzahl der vorhandenen Sensoren und deren einzelnen Bezeichnungen nun die dazugehörigen Werte ausgelesen.

 

 

 



Servus, ich bin Wolfgang.

Blogger – Maker – web & mobile Developer – Dobermann Besitzer.

Mit meinem über die Jahre gesammelten Wissen als Webworker möchte ich dir Hilfestellungen und Anregungen zur Nutzung der sich aus dem digital Lifestyle ergebenden Möglichkeiten und Notwendigkeiten geben.

Einen aktuellen Schwerpunkt auf meinem Blog bildet das Thema IoT im Zusammenspiel mit dem Raspberry Pi.


Unterstützen

Dieser Beitrag hat dir gefallen und konnte dir bei deinem Projekt oder Problem behilflich sein? Dann würde ich mich sehr freuen, wenn du dich mit einer noch so kleinen Spende erkenntlich zeigen möchtest.


Hinterlasse einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Notwendige Felder sind mit * markiert.

23 Reaktionen (22 Kommentare)

  • pensionär schrieb am 18. Oktober 2018:

    hallo,
    auch durch das lesen aller kommentare habe ich mein problem gelöst. die sensoren können ausgelesen werden….. soweit alles ok. ich würde die daten gerne nach thingspeak beamen um mir arbeit zu ersparen. datenbanken sind mir zu neu, zu kompliziert da lass ich die finger lieber weg ….. thingspeak wäre ne lösung

    • Wolfgang schrieb am 18. Oktober 2018:

      Hallo,
      wie schon in meiner Antwort auf deine Nachricht geschrieben, habe ich persönlich keine Erfahrung mit Thingspeak. Allerdings müsste die Plattform eine API zur Datenanbindung mit dem eigenen Account anbieten. Genauere Informationen sind bestimmt auf der Thingspeak-Seite zu finden. Aber vielleicht kann dir einer der Leser dieses Beitrags helfen.

  • Sean schrieb am 25. August 2018:

    Moin
    Leider bekomme ich immer eine Fehlmeldung, Bin noch Anfänger mit dem Pi, Habe den Code 1 zu 1 Kopiert. Habe aber noch irgend wo ein Fehler. der Meldung ich erhalte lautet ” Missing Parentheses in call to Print”
    Ich verwende DS18B20 Fühler mit 1m Kabel.
    Danke für ihre mühe.
    mfg Sean

    # !/usr/bin/python
    # coding=utf-8
    # messprogramm.py
    #————————————————————

    import os, sys, time

    # Global für vorhandene Temperatursensoren
    tempSensorBezeichnung = [] #Liste mit den einzelnen Sensoren-Kennungen
    tempSensorAnzahl = 0 #INT für die Anzahl der gelesenen Sensoren
    tempSensorWert = [] #Liste mit den einzelnen Sensor-Werten

    # Global für Programmstatus /
    programmStatus = 1

    def ds1820einlesen():
    global tempSensorBezeichnung, tempSensorAnzahl, programmStatus
    #Verzeichnisinhalt auslesen mit allen vorhandenen Sensorbezeichnungen 28-xxxx
    try:
    for x in os.listdir(“/sys/bus/w1/devices”):
    if (x.split(“-“)[0] == “28”) or (x.split(“-“)[0] == “10”):
    tempSensorBezeichnung.append(x)
    tempSensorAnzahl = tempSensorAnzahl + 1
    except:
    # Auslesefehler
    print “Der Verzeichnisinhalt konnte nicht ausgelesen werden.”
    programmStatus = 0

    def ds1820auslesen():
    global tempSensorBezeichnung, tempSensorAnzahl, tempSensorWert, programmStatus
    x = 0
    try:
    # 1-wire Slave Dateien gem. der ermittelten Anzahl auslesen
    while x < tempSensorAnzahl:
    dateiName = "/sys/bus/w1/devices/" + tempSensorBezeichnung[x] + "/w1_slave"
    file = open(dateiName)
    filecontent = file.read()
    file.close()
    # Temperaturwerte auslesen und konvertieren
    stringvalue = filecontent.split("\n")[1].split(" ")[9]
    sensorwert = float(stringvalue[2:]) / 1000
    temperatur = '%6.2f' % sensorwert #Sensor- bzw. Temperaturwert auf 2 Dezimalstellen formatiert
    tempSensorWert.insert(x,temperatur) #Wert in Liste aktualisieren
    x = x + 1
    except:
    # Fehler bei Auslesung der Sensoren
    print "Die Auslesung der DS1820 Sensoren war nicht möglich."
    programmStatus = 0

    #Programminitialisierung
    ds1820einlesen() #Anzahl und Bezeichnungen der vorhandenen Temperatursensoren einlesen

    # Temperaturausgabe in Schleife
    while programmStatus == 1:
    x = 0
    ds1820auslesen()
    print "Sensorbezeichnung und Temperaturwert:"
    while x < tempSensorAnzahl:
    print tempSensorBezeichnung[x] , " " , tempSensorWert[x] , " °C"
    x = x + 1
    time.sleep(.5)
    print "\n"

    # Programmende durch Veränderung des programmStatus
    print "Programm wurde beendet."

    • Wolfgang schrieb am 25. August 2018:

      Hallo Sean,
      das Skript ist für Python 2.7 geschrieben. Die Fehlermeldung lässt mich vermuten, dass du Python 3 verwendest. Der Print-Befehl wird mit Klammern verwendet, siehe als Beispiel hierzu den Kommentar von Willi vom 16.04.2018.
      Viele Grüße
      Wolfgang

  • olaf schrieb am 28. Juni 2018:

    Hallo,
    der Code funktioniert perfekt. Ich möchte die Werte der einzelnen Sensoren aller 10min in eine Mariadb schreiben. Ich habe bereits eine DB “Sensoren” mit den Feldern ID, Datum, Uhrzeit, S1, S2, … , S10 angelegt. Irgendwie fehlen mir leider die entsprechenden Programmierkentnisse dies umzusetzen. Es sind derzeit 4 Sensoren angeschlossen. Wenn ich richtig verstanden habe werden neue Sensoren immer hinten angefügt. Die Werte der Sensoren sollten in die Felder S1 bis S10 geschrieben werden, in Felder wo keine Sensoren / Daten vorhanden sind, sollte eine 0 geschrieben werden. Könnten Sie mir bitte etwas Starthilfe geben.

    Danke

    • Wolfgang schrieb am 2. Juli 2018:

      Hallo Olaf,
      das Skript liest die Sensoren aufsteigend der Sensorenbezeichnung ein. Sollte ein weiterer Sensor zu den vier verwendeten hinzukommen, kann es sein, dass dieser plötzlich an der Stelle S1 steht. Daher würde ich zuerst eine Art Zuordnungsliste (Sensor xxx ist S1, usw.) anlegen.
      Durch die Zuordnungsliste kann das Einlesen der Temperaturwerte in einer Schleife erfolgen, wenn kein Sensor vorhanden ist, ist der Temperaturwert 0. Die in der Schleife ermittelten Werte können danach in die Datenbank geschrieben werden.
      Hoffe ich konnte eine Starthilfe geben.

      Viele Grüße
      Wolfgang

  • willi schrieb am 17. April 2018:

    Hallo und danke,
    nachdem ich die Kommentare weggenommen und die fehlende klammer ergänzt habe, läuft das programm .
    allerdings wird nur ein sensor angezeigt obwohl 2 gefunden und vorhanden sind.
    zudem läuft das programm ohne ende und zeigt nur die werte des einen sensor.
    diese Anweisung aus der temperatur ausgabe wird nicht durchgeführt.
    print (“Sensorbezeichnung und Temperaturwert:”)
    ich musste mit Contr. C stoppen
    was kann nun fehlerhaft sein ?

    • Wolfgang schrieb am 18. April 2018:

      Hallo Willi,
      das Programm ist tatsächlich so aufgebaut, dass es so lange in einer Dauerschleife läuft bis sich der Wert programmStatus ändert. In diesem Beispiel ist keine Option eingebaut. Du kannst natürlich auch einen Zähler verwenden. Da er nur einen Sensor anzeigt, könnte es daran liegen, dass du die x Erhöhung nicht in der while Schleife x < tempSensorAnzahl erhöhst. Viele Grüße Wolfgang

  • willi schrieb am 16. April 2018:

    hier das programm was den fehler verursacht, .
    wenn du bitte einmal drüber schauen kannst.und mir sagt wo das problem liegt ?
    Danke
    #!/usr/bin/python3.5
    # coding=utf-8
    # Sensoren2.py
    #————————————————————

    import os,sys,time

    # Global für vorhandene Temperatursensoren
    tempSensorBezeichnung = [] #Liste mit den einzelnen Sensoren-Kennungen
    tempSensorAnzahl = 0 #INT für die Anzahl der gelesenen Sensoren
    tempSensorWert = [] #Liste mit den einzelnen Sensor-Werten

    # Global für Programmstatus /
    programmStatus = 1

    def ds1820einlesen():
    global tempSensorBezeichnung, tempSensorAnzahl, programmStatus
    #Verzeichnisinhalt auslesen mit allen vorhandenen Sensorbezeichnungen 28-xxxx
    try:
    for x in os.listdir(“/sys/bus/w1/devices”):
    if (x.split(“-“)[0] == “28”) or (x.split(“-“)[0] == “10”):
    tempSensorBezeichnung.append(x)
    tempSensorAnzahl = tempSensorAnzahl + 1
    except:
    # Auslesefehler
    print (“Der Verzeichnisinhalt konnte nicht ausgelesen werden.”)
    programmStatus = 0

    def ds1820auslesen():
    global tempSensorBezeichnung, tempSensorAnzahl, tempSensorWert, programmStatus
    x = 0
    try:
    # 1-wire Slave Dateien gem. der ermittelten Anzahl auslesen
    while x < tempSensorAnzahl:
    dateiName = "/sys/bus/w1/devices/" + tempSensorBezeichnung[x] + "/w1_slave"
    file = open(dateiName)
    filecontent = file.read()
    print(dateiName)
    print(x)
    file.close()
    # Temperaturwerte auslesen und konvertieren
    stringvalue = filecontent.split("\n")[1].split(" ")[9]
    sensorwert = float(stringvalue[2:]) / 1000
    temperatur = '%6.2f' % sensorwert #Sensor- bzw. Temperaturwert auf 2 Dezimalstellen formatiert
    tempSensorWert.insert(x,temperatur) #Wert in Liste aktualisieren
    #x=x+1
    except:
    # Fehler bei Auslesung der Sensoren
    print ("Die Auslesung der DS1820 Sensoren war nicht möglich.")
    programmStatus = 0

    #Programminitialisierung
    print (x)
    ds1820einlesen() #Anzahl und Bezeichnungen der vorhandenen Temperatursensoren einlesen

    # Temperaturausgabe in Schleife
    while programmStatus == 1:
    x = 0
    ds1820auslesen()
    print ("Sensorbezeichnung und Temperaturwert:")
    while x < tempSensorAnzahl:
    print (tempSensorBezeichnung[x] ), (" " ), (tempSensorWert[x] , (" °C")
    #x = x + 1
    time.sleep(0.5)
    print ("\n")

    # Programmende durch Veränderung des programmStatus
    print ("Programm wurde beendet.")

    • Wolfgang schrieb am 16. April 2018:

      Hallo,
      auf den 1. Blick fällt mir in der Print-Anweisung vor der auskommentierten Erhöhung des Integer x, dass Du eine Klammer hinter tempSensorWert[x] vergessen hast. Die richtige Anweisung müsste meines Wissens nach allerdings print (tempSensorBezeichnung[x] , ” ” , tempSensorWert[x] , ” °C”) lauten. Die Fehlermeldung bezieht sich zwar auf die Zeile x = x + 1, dies liegt allerdings an der fehlerhaften Syntax in dem vorherigen Befehl. Daher kannst und musst du die Kommentierung entfernen, da sonst der zweite Sensor nicht angezeigt werden kann.
      Viele Grüße
      Wolfgang

  • willi schrieb am 13. April 2018:

    hallo Wolfgang,
    ich bin anfänger mit dem pi und habe dein Programm für die Temperaturmessung gefunden und versucht es unter Python 3.5 zum laufen zu bringen nachdem ich die Print Anweisungen angepasst habe. ich verwende 2 Ds 2820
    Nun gibt es folgenden fehler:
    File “./Sensoren2.py”, line 64
    x = x + 1
    ^
    SyntaxError: invalid syntax
    Sobald ich diese zeile als kommentar setze erhalte ich diesen Fehler
    File “./Sensoren2.py”, line 65
    time.sleep(0.5)
    ^
    SyntaxError: invalid syntax
    ich habe versucht mir zwischenergebnisse mit Print als testhilfe in der while Schleife ausgeben zu lassen aber es erfolgte keinne Ausgabe.s. hier
    while x < tempSensorAnzahl:
    dateiName = "/sys/bus/w1/devices/" + tempSensorBezeichnung[x] + "/w1_slave"
    file = open(dateiName)
    filecontent = file.read()
    print(dateiName) <–
    print(x)<–
    file.close()
    nun weis ich auch nicht mehr weiter, kannst du mir hinweise geben ?
    im übrigen finde ich es prima wie du die es gelöst hast das man mehrere Sensoren anschließen kann

    • Wolfgang schrieb am 14. April 2018:

      Hallo Willi,
      aus der Ferne ist es für mich etwas schwierig den Fehler zu analysieren. Bitte sende mir doch einmal Deinen kompletten Programmcode.
      Viele Grüße
      Wolfgang

  • Axel schrieb am 29. November 2017:

    Hallo Wolfgang,
    ich habe zwischenzeitlich einwenig weiter probiert und jetzt funktioniert es: Der Widerstand war nicht das Problem, denn auch auf diese relativ große Entfernung lag der Widerstand bei nur knapp 800 Ohm. Ich habe mich einfach getraut, dem Sensorenbündel etwas mehr Strom zu gönnen und habe auf 5V umgesteckt – siehe da, es klappte. Dein Script funktioniert wunderbar, damit kann ich jetzt weiterarbeiten.
    Nochmal vielen Dank und viele Grüße
    Axel

  • Axel schrieb am 29. November 2017:

    Hallo Wolfgang,
    danke für die gute Beschreibung. Nach langer Zeit bastele ich mal wieder mit dem Raspi. Mein Ziel ist eine Steuerung für unseren privaten Kühlraum. Die Sensoren habe ich im Kühlraum installiert, das Kabel führt vom Keller ins Dachgeschoss. Die Verbindung habe ich mit Telefonkabel hergestellt. Leider bekomme ich keine Antwort von meinen Sensoren. Hast Du eine Idee, ob der Widerstand auf die Entfernung zu groß ist? Sollte ich vielleicht eine zusätzliche Stromquelle einbinden? Ein einzelner Sensor, den ich direkt anschließe, funktioniert einwandfrei.

  • Skipper schrieb am 27. Juli 2017:

    Hallo Wolfgang…

    Ich baue derzeit ein grafisches Interface (Tkinter) für eine Eigenbaumaschine, in dem unter anderem die Temperaturen von diversen Komponenten erfasst & angezeigt werden sollen..

    Wie kann ich nun aus deinem Programm eine “Klasse” bauen, die es mir ermöglicht in gewissem Zeitintervallen die Sensordaten der in der Maske verwendeten DS18B20 Sensoren anzuzeigen?

    Evtl Aufruf der Klasse mit Übergabe der SensorID

    […]
    messwert(28-xyz)
    […]

    Ich hoffe Du verstehst was ich meine… bin noch ziemlich am Anfang der Programmierung in Python…

    • Wolfgang schrieb am 27. Juli 2017:

      Hallo,

      Du kannst die Funktionen natürlich in Klassen einbinden, siehe hierzu folgendes Tutorial einbinden. Oder Du rufst die Funktion ds1820auslesen() mit der gewünschten Bezeichnung auf. Hierzu wäre vielleicht, da Du ja die einzelnen Bezeichnungen Deiner Sensoren für die Zuordnung weißt, die Funktion aus diesem Beitrag sinnvoller. In diesem Beispiel könntest Du abhängig Deiner an die Funktion übergebenen Bezeichnung, den Pfad zur 1-wire Slave Datei setzen.

      Viele Grüße
      Wolfgang

  • Wilfried schrieb am 17. Juli 2017:

    Hi Wolfgang,

    das ist bisher das beste Script, das ich zum Auslesen der 1-wire-slave-Dateien gefunden habe. Danke für deine Vorarbeit.

    • Wolfgang schrieb am 18. Juli 2017:

      Hallo Wilfried,
      vielen Dank für Deinen netten Kommentar.

      Viele Grüße
      Wolfgang

  • Dennis schrieb am 30. Dezember 2016:

    Wie kann ich jedem Sensor noch den Namen des Messortes zuordnen?

    • Wolfgang schrieb am 31. Dezember 2016:

      Hallo Dennis,

      eine Zuordnung einer eigenen Bezeichnung für einen Sensor habe ich per SQLite gelöst.

      Viele Grüße
      Wolfgang

  • Marcus schrieb am 20. Oktober 2016:

    Servus,
    interessanter Ansatz. Was ist wenn die Sensorbezeichnungen abweichend sind? Meine beginnen mit unterschiedlichen Zahlen (10 und 28).

    • Wolfgang Raab schrieb am 21. Oktober 2016:

      Hallo Marcus,
      den DS18S20 Temperatursensor (ID 10) habe ich ehrlich gesagt nicht bedacht. Vielen Dank für den Hinweis. 🙂
      Ich habe den Beitrag diesbezüglich ergänzt und die if Abfrage in ds1820einlesen() ergänzt.
      if (x.split(“-“)[0] == “28”) or (x.split(“-“)[0] == “10”):
      Nun werden die beiden Sensoren DS18B20 und DS18S20 Sensoren eingelesen, also 28 oder 10.
      Viele Grüße
      Wolfgang