Raspberry Pi – Temperatur-Sensor 18B20 – Teil 2
Im letzten Teil habe ich gezeigt wie man den Temperatur-Sensor 18B20 an die GPIO Schnittstelle des Raspberry Pi anschließt. Weiters haben wir auch schon über die Kommandozeile die Temperatur mit diesem Sensor gemessen und ausgegeben. Nun wird es spannend, denn wir wollen den Sensor auch in unserer Software nutzen, schließlich können wir nur so periodische Messungen durchführen und diese dann grafisch darstellen. In diesem Artikel zeige ich euch wie man in einem Python Skript die Temperatur ermittelt und ausgibt. In einer erweiterten Version werden wir die gemessenen Werte auch für die statistische Auswertung abspeichern.
Software zur Temperaturmessung
In diesem Beispiel gehe ich davon aus, dass die beiden benötigten Kernel Module bereits der /etc/modules Datei hinzugefügt worden sind, damit diese auch nach einem Neustart wieder zur Verfügung stehen. Sollte das Skript aus irgend einem Grund nicht laufen bitte zuerst prüfen ob diese aktiviert sind.
Messwerte ausgeben
In einer ersten Version wollen wir nun in einem Python Skript die Temperatur messen und auf der Kommandozeile ausgeben. Im Prinzip machen wir dabei nichts anderes, als über die Konsole im ersten Teil der Artikelserie. Der Vorteil des Python Skripts ist nun, das wir dort allen Komfort einer Programmiersprache haben und das Skript jederzeit um weitere tolle Elemente erweitern können.
Wir importieren:
import re import os
Wir benötigen die Bibliotheken für die Regular Expressions (re) und für die Kommunikation mit dem Betriebssystem (os). Als nächstes definieren wir noch den Pfad zu den durch die Treiber Module angelegten Systempfad und holen uns den Inhalt, alle Dateien und Ordner als Array:
directory = "/sys/bus/w1/devices/" #finde alle angeschlossenen 1-wire Geraete devices = os.listdir(directory)
Wir geben hier den Pfad fix ein, denn dieser ist immer gleich. Über die os Bibliothek holen wir uns danach dessen Inhalt als Array. Mit diesem können wir nun in einer Schleife alle Dateien und Ordner durchgehen:
for f in devices: if f != "w1_bus_master1": file = open(directory+f+"/w1_slave") line = file.readline() if re.match(r"([0-9a-f]{2} ){9}: crc=[0-9a-f]{2} YES",line): line = file.readline() m = re.match(r"([0-9a-f]{2} ){9}t=([+-]?[0-9]+)",line) if m: value = str(float(m.group(2)) / 1000.0) print "Measured temperature from "+f+": "+value file.close()
Der Code ist eigentlich recht simpel. Wir prüfen zuerst ob es sich bei dem Dateinamen nicht um die vom Standardordner w1_bus_master1 handelt. Dieser interessiert uns nicht. Falls es andere Ordner gibt öffnen wir die darin hoffentlich enthaltene w1_slave Datei zum Lesen. Wir lesen davon zeilenweise! Das heißt wir holen uns durch die readline Funktion die Zeile und prüfen dessen Inhalt mit einer Regular Expression. Im ersten Fall ob es sich um eine korrekte Messung handelt. Es muss also ein YES am Ende der Zeile stehen. Ich dies der Fall lesen wir auch die 2. Zeile mit dem Messwert. Falls es einen gibt wandeln wir diesen in eine lesbarere Form um. Wir geben anschließend den Wert aus und schließen die Datei!
Damit sind wir auch schon fertig. Das Skript sollte von allen angeschlossenen und erkannten 1-wire Temperatursensoren die Werte ausgeben.
Des fertige Skript könnt ihr hier herunterladen.
Messwerte im Log speichern
Das fertige Python Skript ist schon ganz nett, aber wir wollen ja nicht nur die aktuelle Temperatur angezeigt bekommen. Ideal wäre es, wenn der Raspberry Pi selbstständig automatisiert Temperaturmessungen durchführt und diese zur späteren Analyse protokolliert. Dafür speichern wir uns die Messwerte samt Timestamp in eine Logdatei. Für jede Messung fügen wir eine neue Zeile hinzu.
Um das zu erreichen erweitern wir das Skript um 2 Importe:
import time import datetime
Weiters fügen wir bei der Initialisierung eine neue Variable mit dem Dateinamen des Logs ein:
log = "temperature.log"
Zuletzt ersetzen wir die Zeile in der die aktuelle Temperatur mit einem print ausgegeben wird durch folgenden Code:
logfile = open(log, 'a') ts = time.time() timestamp = datetime.datetime.fromtimestamp(ts).strftime('%d.%m.%Y %H:%M:%S') logfile.write(timestamp+" "+value+"\n") logfile.close()
Wir öffnen das Log-File im Append Modus (wir können weitere Zeile am Ende anhängen). Danach holen wir uns den aktuellen Timestamp vom System und formatieren diesen in eine leserliche Form. Danach schreiben wir den Timestamp samt gemessenem Wert in die Log-Datei und schließen diese wieder.
Das wars auch schon. So einfach haben wir nun unser Skript erweitert. Bei einem Aufruf wird entweder die Log Datei mit dem aktuellen Wert erzeugt oder aber dieser wird ans Ende der Datei angehängt. Am besten wir definieren nun einen Cron, welcher das Skript alle paar Minuten oder Stunden aufruft und sammeln so unsere Werte. In der Wohnung werden wir wohl kaum interessante Werte sammeln können, ideal wäre eine Messung von draußen.
Mit einem externen Tool wie beispielsweise einem Tabellenverarbeitungsprogramm können wir später unser Log auswerten und gegebenenfalls auch Grafiken und Diagramme erstellen lassen.
Das fertige Skript könnt ihr hier herunterladen.
Fazit
Dank Python ist es relativ einfach auch eine automatische Messung von Temperaturwerten zu implementieren. Mit nur wenigen Zeilen Code können wir effektiv die Messwerte abspeichern um sie danach statistisch auszuwerten. Der Raspberry Pi ist dafür das ideale Gerät, denn er ist stromsparend, leicht zu bedienen und über die GPIO Schnittstelle können wir sehr einfach mit externen Sensoren wie beispielsweise der Temperatur-Sensor 18B20 kommunizieren.
Welche Erfahrungen habt ihr mit der Temperaturmessung mit dem Raspberry Pi? Habt ihr einen anderen Sensor zum Laufen gebracht? Wie würdet ihr mein Python Skript erweitern?
Hi Werner,
Ich habe bei mir daheim 3 18B20 Sensoren seit über einem Jahr laufen und bin mehr als zufrieden. Ich zeichne die Temperaturen mittels RRD Datenbanke auf und stelle das ganze auf meiner Homepage die auch am Pi läuft dar.
Weiters habe ich noch einen Luftdrucksensor laufen der mir diesen auch in einer RRD DB aufzeichnet. Auch auf der HP zu finden.
Und zum Schluss läuft noch ein DHT22 der die Luftfeuchtigkeit im Keller aufzeichnet.
Mich würden noch viele Sensoren interessieren, vor allem auf 1-wire Basis da dieses System echt cool ist 😉
Danke für diesen Artikel. Mir ist aufgefallen das die RRD-Tools Methode zwar gut funktioniert, aber an vielen stellen recht komplex ist.
Als Alternative gibt es ein richtiges CMS für solche Daten das man über diverse Wege „füttern“ kann. Vielleicht ist das ja für dein ein oder anderen eine Option.
http://raspberry.tips/hausautomatisierung/rasberry-pi-emoncms-und-rfm12pi-sensordaten-visualisieren/
Hallo,
ich bin Neueinsteiger bei Linux und Raspberry.
Ich habe voller Neugier, alles mit diesen Sensoren aufgebaut, und auch den Ersten Teil dieser Abhandlung durchgearbeitet.
Leider, und so kommt es mir vor, fehlt im 2. Teil einiges, um Schritt für Schritt alles nachzuprogrammieren.
Ich habe zwar mit pyton programmiert, weiß aber leider nicht weiter.
Jetzt mal Schritt für Schritt, Den Import mit re und os
wie mache ich den, muß ich den in eine Datei schreiben?? Wie soll diese heißen.
Dann den Verweis auf das Abholen der Daten, wie und welche Datei soll das sein??
Dann die Auswertung genauso.
Ist es möglich für einen Anfänger den 2. Teil so zu beschreiben, das ich den mit der Konsole programmiere
und wie werden dann die Meßwerte angezeigt?? in der Konsole oder auf dem Schirm??
Sorry aber beim 2. Teil komme ich nicht weiter, und der wäre auch für mein Projekt, das ich plane wichtig.
Danke für das Verständis
Euer
Helma
danke für den Kommentar. Du findest im Artikel verlinkt die beiden Skripte die ich dort erkläre. Das ist jeweils eine einzelne *.py Datei die man mit dem Befehl sudo python Dateiname.py auf der Kommandozeile ausführen kann. Das sudo für Root Rechte benötigt man vorangestellt immer dann, wenn man die GPIO Schnittstelle verwendet.
Python Skript starten dabei immer damit, dass man mit import Bibliotheken einbindet, das sind meist andere Python Skripte oder fertig kompilierte Software anderer Programmiersprachen. re benötigst du um so genannte Regular Expressions ausführen zu können und os für Betriebssystem nahe Funktionen wie etwa das Abspeichern einer Datei.
Der Temperatursensor ist ein so genanntes 1-wire Gerät, das bedeutet es gibt dafür einen Kernel Treiber, der dafür sorgt, dass der gemessene Wert in einer Datei im Dateisystem zu finden ist. Genau diesen Wert holen wir uns und geben diesen mit dem print Befehl auf der Kommandozeile aus.
Das 2. Skript ist eine Erweiterung des ersten Skripts, dort wird der Messwert nicht auf der Konsole ausgegeben, sondern in einer Log Datei.
Ich hoffe das ist verständlicher. Ich würde mir einfach mal die verlinkten Dateien herunterladen und ansehen/ausführen.
Generell ist das aber schon eine etwas komplexere Sache. Ich würde dir empfehlen, mit den LEDs anzufangen.
Hallo Werner,
ich bin seit einiger Zeit dabei, ein Projekt zu verwirklichen und könnte eventuell ein wenig Hilfe brauchen.
Zur Erklärung: wir heizen ausschließlich mit Holz mit einem Kessel, der etwa 20 Jahre alt ist, aber noch tiptop in Schuss.
Die Verbrennung und damit die Kesseltemperatur wird durch einen Feuerzug-Regler und Luftklappe geregelt. Die Kesseltemperatur stelle ich auf 80 – 90 °C ein, das Heißwasser, das im Moment nicht in der Heizung gebraucht wird, wird per 3-Wege Ventile von der kesseleigenen Steuerung in den 1000L Speicher gepumpt. Soweit, sogut – einfach und es funktioniert super. Es gab allerdings einen Nachteil: Schließe ich die Feuerzugklappe nicht selbst nach der Verbrennung des Holzes, kühl der Kessel durch die Frischluft wieder aus.
Dies habe ich kürzlich geändert: den Feuerzug-Regler habe ich mit einem Servo ergänzt, der von einem Raspberry gesteuert wird, dieser erfasst gleichzeitig die Temperaturen mit mehreren DS1820.
Mit einem Python-Script kann ich inzwischen den Servo bedienen, auch per html auf dem Pi.
Was ich nun brauchen würde, wäre eine Erweiterung Deines track_temperature.py. Ich müsste noch eine Auswertung haben: ca. 30 min nach erreichen der Höchsttemperatur musste mein Script klappe_zu.py gestartet werden. Oder halt als if else Funktion.
Könntest Du dabei helfen?
Ich würde Dir auch gerne noch ein Video schicken, wo Du den Kessel mit dem Servo siehst.
Danke im voraus und viele Grüsse
Detlef
Hallo, bei Fragen rund um die Programmierung helfe ich dir gerne weiter.
Hallo,
ist schon ne weile her, aber kann mir jemand erklären, wie man die Werte (mehrere Sensoren) im Logfile nicht alle untereinander schreibt, sondern in einer Zeile nacheinander.
logfile.write(timestamp+“ „+value+“\n“)
meins schaut dann so aus:
logfile.write(f+“ ,“+timestamp+“ ,“+value+“ ,“ )
so:
28-000007c6a732 ,10.11.2018 ,16:38:57 ,21.012 ,28-01131t4khef9 ,10.11.2018 ,16:38:58 ,20.997 ,
das „\n“ raus brachte den Erfolg, aber jetzt schreibt es die neuen Daten immer in der gleichen Zeile weiter. Möchte aber jedes mal (alle 15 min) eine neue Zeile.?
Besten Dank
Hallo, ich prüfe jeden Kommentar vor der Veröffentlichung, weshalb dein erster nicht gleich öffentlich gezeigt wurde. Zu deiner Frage: du kannst nun jederzeit mit einem logfile.write(„\n“) eine neue Zeile beginnen. Du könntest beispielsweise die Zeilen mitschreiben und alle X Schreibvorgänge so eine neue Zeile beginnen oder wie du sagst über einen Timer alle 15 min. Hole dir die aktuelle Zeit in Minuten und prüfe in einem if auf 0, 15, 30 und 45.
Dankw, aber ich blickvgrad nicht mehr durch.
Würdest mir ein Beispiel haben?
Hab grad Ptobleme den cronjob (alle 15 min) zu erstellen, Datei ist ausführbar, aber geht irgendwie nicht.