Python Strings und der DS18B20 Temperatursensor

Python Strings und der DS18B20 Temperatursensor Titelbild

Folgende Teile braucht ihr für die Anleitung

Jugend Programmiert Starterkit2.1 Produktbild

Jugend Programmiert Starterkit2.1 | 39.95€

Strings und DS18B20

Wir haben schon häufig mit Strings gearbeitet. Diese können wir einfach mit string = "Hello World" erzeugen. Alles was zwischen den " steht, wird gespeichert. Doch jetzt bieten uns Strings noch mehr Möglichkeiten, mit diesen gespeicherten Daten umzugehen. Denn wie bei einer Liste hat jedes Zeichen im String eine Nummerierung, die bei 0 anfängt. print(string[1]) würde in diesem Fall ein e ausgeben. Wir können auch Abschnitte in einem String markieren print(string[5:9]) gibt nur Wor aus. Das heißt, vor dem :schreiben wir den Anfangswert hin und dahinter den Endwert. Wenn wir den Anfangs- oder Endwert von dem ganzen String haben wollen, können wir auch einfach nichts hinter/vor dem : schreiben. print(string[5:]) gibt World aus.

Eine weitere Funktion, die wir schon kennengelernt haben, ist das Verbinden von zwei Strings mit +. print(string[:6]+"Welt") gibt nur noch Hello Welt aus. Das zeigt auch, dass sich die einzelnen Methoden kombinieren lassen.

Strings haben Funktionen

Bis jetzt haben wir nur Funktionen kennengelernt, die so aufgebaut sind: funktionsName(Parameter1, Parameter2) doch es gibt auch noch so genannte eingebaute Funktionen, die so aufgerufen werden objekt.funktionsName(Parameter1, Parameter2) . Ein String gehört zu diesen Objekten, die eingebaute Funktionen haben. Wenn wir diese aufrufen wollen, nehmen wir zuerst das Objekt oder die Variable, in der wir das Objekt gespeichert haben und rufen danach die Funktion auf. Weil es recht viele String-Funktionen gibt, haben wir eine Liste mit Beispielen.

Funktion Beispiel
.capitalize() print("hello".capitalize()) -> Hello
.count(string) print("hello".count("l")) -> l
.find(string) print("hello".find("o")) -> 4 print("hello".count("x")) -> -1
len(string) print(len("hello")) -> l
.lstrip() print(" hello".lstrip()) -> hello*
.replace(alt, neu) print("Hello World".replace("World", "Welt")) -> Hello Welt
.upper(alt, neu) print("hello world".upper()) -> HELLO WORLD

DS18B20 - Der Temperatur-Sensor

Puh, ganz schön kalt/lauwarm/heiß hier drinnen. Du möchtest wissen, wie kalt/lauwarm/heiß es genau ist? Mit dieser hoch technologischen Temperaturerkennungsapparatur ist das kein Problem.



show
Pin 1 Pin 2 Pin 3
GND Ground Data VCC - 3,3V

[Vorne ist die flache Seite]

Der DS18B20, wie wir unseren kleinen Temperatursensor liebevoll nennen, ist ein recht simpel aufgebauter Sensor. Eine Besonderheit an ihm ist, dass er zur Kommunikation das One Wire Protokoll benutzt. Dies ermöglicht uns beliebig viele Sensoren an einen GPIO-Pin des Raspberry Pi anzuschließen. Mehr dazu erfährst du in den nächsten Kapiteln.

Raspberry Pi einrichten

Bevor du diesen Sensor benutzen kannst, musst du an deinem Pi noch ein paar Konfigurationen durchführen. Da der Pi ein ganz schön fauler Computer ist, spart er sich einfach etwas Arbeit und lädt nicht alle für uns wichtigen Pakete nach. Um das zu ändern, müssen wir die configx.txt Datei bearbeiten.

sudo nano /boot/config.txt


Füge am Ende dieses Dokumentes einfach folgende Zeile hinzu:

dtoverlay=w1-gpio,gpiopin=4

Speichern musst du mit mit Strg + X, dann y und am Ende noch Enter. Was haben wir jetzt eigentlich verändert? Ganz einfach, beim Start deines Pi wird jetzt immer das One Wire Interface geladen. Außerdem legen wir mit gpiopin=4 fest, dass der GPIO Pin 4 der zuständige One Wire Pin ist.

Alle wichtigen Einstellungen sind jetzt gespeichert. Damit alles auch einwandfrei funktioniert, musst du deinen Pi kurz neu starten.

sudo reboot

DS18B20 anschließen

show
GPIO Pins am Pi Pins am Sensor
3,3V VCC
GPIO4 Data+ 4,7kΩ zu VCC
GND GND

Das Verbinden des Sensors mit deinem Pi ist simpler als einen Kaktus am Leben zu erhalten. Du solltest darauf achten, den Data Pin und den VCC Pin mit einem 4,7kΩ Widerstand zu verbinden UND das er richtig rum ist!

Daten auslesen

Um ganz einfach die ersten Daten auszulesen, musst du, wenn alles richtig angeschlossen ist, erstmal einen großen Berg versetzen. Da dieser Sensor ein One-Wire Sensor ist, kannst du alle Daten auch in dem Verzeichnis von den One-Wire Geräten lesen.

cd /sys/bus/w1/devices
ls

Alle One-Wire Geräte haben eine spezifische Adresse, die einzigartig ist. Beim DS18B20 fangen diese Adressen gewöhnlich mit 28-xxxxxxxxxxxxx an. Deswegen ersetzt du einfach die xxxxxxxxxxxxx durch deine Nummer in den nachfolgenden Beispielen.

show
cd 28-xxxxxxxxxxx
show

In diesem Ordner sehen wir verschiedene Dateien. Die einzige Datei, die für uns jetzt interessant ist, ist die w1_slave. In dieser steht auch die gemessene Temperatur, die wir aber zuerst auslesen müssen.

cat w1_slave
show

Mit cat nameDerDatei werden Inhalte von einer Datei im Terminal dargestellt. Damit könnt ihr euch auch die sonstigen Python Dateien anzeigen lassen. In der ersten Zeile ist vor allem das Ende wichtig, weil uns das YES anzeigt, dass alle Daten korrekt gelesen wurden. In der zweite Zeile steht am Ende die Temperatur. In diesem Fall beträgt die Zimmertemperatur gerade 21,625°C. Für mich persönlich eine sehr angenehme Temperatur. Ein Pinguin fände es wahrscheinlich etwas zu warm. So viel zur subjektiven Wahrnehmung einer objektivierten Einheit durch unterschiedliche Individuen.

Auch wenn viele Nachkommastellen angegeben werden, hat der Sensor eine Ungenauigkeit von ± 0,5°C. Das heißt, in diesem Fall liegt die echte Temperatur zwischen 21,1°C und 22,1°C

Jetzt hast du den kleinen DS18B20 schon manuell ausgelesen. Aber ein super praktischer Mini-PC wäre kein super praktischer Mini-PC, wenn er diese Aufgabe nicht auch automatisch erledigen könnte. Und das alles macht er mit den folgenden paar Zeilen Python Code. Das Programm können wir nicht in dem Verzeichnis mit den Sensor Daten erstellen sondern müssen dafür erstmal zurück in unser Homeverzeichnis. Dafür reicht es nur cd ohne etwas anderes einzugeben ;)

import glob
import time

pfad = "/sys/bus/w1/devices/"
sensor_ordner = glob.glob(pfad + "28*")[0]
sensor_daten_pfad = sensor_ordner + "/w1_slave"

def temperatur_lesen():
  datei = open(sensor_daten_pfad, "r")
  zeilen = datei.readlines()
  datei.close()
  return zeilen

def grad_lesen():
  zeilen = temperatur_lesen()
  while zeilen[0].strip()[-3:] != 'YES':
    time.sleep(0.2)
    zeilen = temperatur_lesen()
  equals_pos = zeilen[1].find('t=')
  if equals_pos != -1:
      temp_string = zeilen[1][equals_pos+2:]
      temp_c = float(temp_string) / 1000.0
      return temp_c
while True:
  print(grad_lesen())
  time.sleep(1)

Wenn du alles richtig angeschlossen hast und das Programm ausführst, wird jede Sekunde die Temperatur ausgelesen und im Terminal ausgegeben.

Was macht das Programm?

Wie in der vorherigen Einheit schreibt der Sensor seine gesamten gemessenen Daten in eine Textdatei, die in /sys/bus/w1/devices/28-xxxxxxxxxxxxxxxxxxxx/w1_slave steht. Das heißt, die einzige Herausforderung ist es, die Textdatei mit dem Pythonprogramm auszulesen und dann die richtige Temperaturwerte aus der gesamten Datei herauszuschneiden.

Schritt für Schritt

In Zeile 1 und 2 importieren wir zuerst die nötigen Bibliotheken. Mit der glob Bibliothek können wir uns im Dateisystem des Raspberry Pi bewegen. In der 4. Zeile geben wir den Pfad an, in dem die One-Wire Sensoren ihre Daten speichern. Jetzt haben wir nur ein Problem, da wir nicht genau wissen, wie die ID des Sensors lautet. Das können wir aber ganz leicht mit der glob.glob() Funktion herausfinden. Alles, was diese Funktion macht, ist nachzusehen, ob es unter diesem Pfad einen Ordner gibt, der mit 28 anfängt und dann den Pfad des Ordner in der Variable sensor_ordner speichert.

Wenn du mehrere Sensoren eingebunden hast, wirst du mit dieser Funktion immer nur den ersten Sensor auslesen

In Zeile 6 fügen wir jetzt einfach nur die Datei hinzu und haben damit den kompletten Pfad zu der Datei, in der die Temperaturen stehen.

Damit der Code ein wenig aufgeräumter ist, erzeugen wir in Zeile 8 unsere eigene Funktion und nenne diese temperatur_lesen(). Diese Funktion liest dann in den Zeilen 9 bis 11 die Datei und gibt dann in einer Liste die einzelnen Zeilen in der Liste zurück. Funktionen können einfach Werte wie strings oder integer zurückgeben. Das machen sie zum Beispiel mit return variable oder return "Hallo".

In Zeile 14 erzeugen wir die zweite Funktion mit dem Namen grad_lesen. Der Name ist Programm. Damit wird die Gradzahl der Temperatur ausgelesen. Die ganze Erklärung findest du online, aber kurz gesagt geht das Programm in Zeile 16 die gesamte Liste durch, welche in der Variablen zeilen gespeichert wurde, und sucht nach dem "YES". Wenn das nicht der Fall ist, wartet das Programm in Zeile 17 für 0.2 Sekunden und liest dann mit dem erneuten Aufrufen der Funktion temperatur_lesen() in Zeile 16 den gesamten Inhalt solange erneut auf, bis es ein "YES" gefunden hat, was bedeutet, dass der Sensor Daten ausgelesen hat.

In Zeile 19 sucht das Programm nach dem t=, hinter dem die Temperatur steht, um diese dann auszuschneiden und von einem String in ein Float, also eine Kommazahl umzuwandeln. Et voilà!

Diese Funktion rufen wir dann in Zeile 25 auf. Da die while Schleife auf true gesetzt ist, läuft sie solange, bis das Programm beendet wird. Damit aber nicht alles viel zu schnell abläuft, wartet die while Schleife immer für eine Sekunde, bis sie sich wiederholt. Du wirst feststellen, dass sich meistens die Temperatur in deinem Zimmer innerhalb einer Sekunde nicht großartig verändert. Wenn du trotzdem mal den Sensor "testen" möchtest, kannst du ihn zum Beispiel anhauchen oder einfach mal anfassen.

Noch Fragen oder Feedback?

Bevor du eine Frage stellen kannst musst du dich zuerst Anmelden oder Regestrieren!