Raspberry Pi DS18B20 Temperatur Sensor

Aus Laub-Home Wiki

Um an den Raspberry Pi einen Temperatur Sensor via one-wire Bus anzuschließen habe ich mich für den Sensor DS18B20 entschieden und diesen auch gleich fertig als Platine gekauft. Der Sensor kann nur die Temperatur auslesen.

Ich habe folgenden Sensor und Jumper Kabel gekauft:

Einen Vergleich verschiedener Temperatur Sensoren findet ihr hier:

Anschluss des Sensors am GPIO

hier die Belegung des GPIO Boards direkt von https://www.raspberrypi.org/documentation/usage/gpio/

Ihr bekommt die aktuelle Pin Belegung eines jeden Raspberry Pi mit dem Tool pinout:

Mein DS18B20 hat drei Anschlüsse VCC DQ GND , wir schließen nun folgendes zusammen:

Verkabelung
Raspberry Pi GPIO Pin DS18B20 Pin
1 (3v3 power) VCC
6 (Ground) GND
7 (GPIO4 / 1-wire) DQ

Es kann hier gerne was den 3v3 und den GND Anschluss angeht variert werden. Bitte keinen 5v Power Anschluss nehmen.

Aktivierung des 1-wire Interface

Um den Sensor zu verwenden müssen wir als erstes das 1-wire Interface aktivieren, dies geht ganz simple mittels raspi-config

raspi-config nonint do_onewire 0

dann müssen wir den Raspberry einmal Neustarten:

reboot

nun testen wir mit lsmod ob die Module geladen wurden:

lsmod

hier sollte in der Liste die folgenden Zeilen zu finden sein:

w1_therm               20480  0
w1_gpio                16384  0
wire                   36864  2 w1_gpio,w1_therm

Auslesen der Daten des Sensors

nun schauen wir ob der Sensor überhaupt erkannt wurde:

ls -la /sys/bus/w1/devices/

die Ausgabe bei mir sieht so aus:

total 0
drwxr-xr-x 2 root root 0 Dec 22 08:34 .
drwxr-xr-x 4 root root 0 Dec 22 08:34 ..
lrwxrwxrwx 1 root root 0 Dec 22 08:35 28-01142f7ba71a -> ../../../devices/w1_bus_master1/28-01142f7ba71a
lrwxrwxrwx 1 root root 0 Dec 22 08:35 w1_bus_master1 -> ../../../devices/w1_bus_master1

Mein Device ist somit die 28-01142f7ba71a

ein cat auf die Device ID und w1_slave

cat /sys/bus/w1/devices/28-01142f7ba71a/w1_slave

zeigt dann die Temperatur an.

61 01 4b 46 7f ff 0c 10 57 : crc=57 YES
61 01 4b 46 7f ff 0c 10 57 t=22062

Die Temperatur (t=22062) muss man dann noch durch 1000 dividieren also wäre meine Temperatur hier 22,062 °C

Dies kann man nun via Python oder Bash Script vereinfacht machen.

Auslesen des Sensors via Bash

zum Rechnen installieren wir uns bc.

apt install bc -y

der Folgende Einzeiler bringt uns dann das Ergebnis:

echo "scale=3; $(grep 't=' /sys/bus/w1/devices/w1_bus_master1/28-01142f7ba71a/w1_slave | awk -F't=' '{print $2}')/1000" | bc -l

passt hier bitte eure DeviceID an. Möchte man nur 2 Kommastellen oder weniger angezeigt bekommen, muss man einfach nur den scale Wert anpassen (0,1,2,3.....)

Die Ausgabe ist dann einfach:

22.062

Als Bash Script hier zum Download: https://github.com/alaub81/rpi_sensor_scripts/raw/main/ds18b20.sh

Auslesen der Sensors via Python Script

Mit diesem kleinen Script ist es möglich die Temperatur auszulesen:

Download hier möglich: https://github.com/alaub81/rpi_sensor_scripts/raw/main/ds18b20.py

/usr/local/sbin/ds18b20.py

#!/usr/bin/python3
import sys
 
# Path to the Sensor systempath
# 28-01142f7ba71a has to be changed to you sensor path!
sensor = '/sys/bus/w1/devices/28-01142f7ba71a/w1_slave'
 
def readTempSensor(sensorName) :
    f = open(sensorName, 'r')
    lines = f.readlines()
    f.close()
    return lines
 
def readTempLines(sensorName) :
    lines = readTempSensor(sensorName)
    while lines[0].strip()[-3:] != 'YES':
        time.sleep(0.2)
        lines = readTempSensor(sensorName)
    temperaturStr = lines[1].find('t=')
    if temperaturStr != -1 :
        tempData = lines[1][temperaturStr+2:]
        tempCelsius = float(tempData) / 1000.0
        tempKelvin = 273 + float(tempData) / 1000
        tempFahrenheit = float(tempData) / 1000 * 9.0 / 5.0 + 32.0
        return [tempCelsius, tempKelvin, tempFahrenheit]
print("Temperature: " + str(readTempLines(sensor)[0]) + " °C")

Möchtet ihr in Kelvin oder Fahrenheit den Wert ausgeben, ändert die Letzte Zeile einfach ab:

print("Temperature: " + str(readTempLines(sensor)[0]) + " °C")
print("Temperature: " + str(readTempLines(sensor)[1]) + " K")
print("Temperature: " + str(readTempLines(sensor)[2]) + " °F")

dann noch dem Script das Execute Recht geben:

chmod +x /usr/local/sbin/ds18b20.py

und einfach starten:

ds18b20.py

der Output sollte dann so aussehen:

Temperature: 22.062 °C

Senden der Daten an MQTT Broker

Möchte man die Temperatur des DS18B20 Sensors an einen MQTT Broker senden um sie dann zum Beispiel mit openHAB auszulesen, kann man dies mit einem Python Script machen Dafür muss man zu allererst noch die paho-mqtt library nach installieren:

apt install -y python3-paho-mqtt

# oder via pip3
pip3 install --user paho-mqtt

Das folgende Script liest dann die Sensor Daten aus und sendet sie einmalig an den MQTT Broker.

Download hier möglich: https://github.com/alaub81/rpi_sensor_scripts/raw/main/ds18b20-mqtt.py

/usr/local/sbin/ds18b20-mqtt.py

#!/usr/bin/python3
import sys
import paho.mqtt.client as mqtt
import ssl
 
# set the variables
# Path to the Sensor systempath
# 28-01142f7ba71a has to be changed to you sensor path!
sensor = '/sys/bus/w1/devices/28-01142f7ba71a/w1_slave'
broker='FQDN / IP ADDRESS'
port=8883
publish_topic="house/pi-ds18b20"
clientid='python-mqtt-ds18b20'
username='mosquitto'
password='password'
insecure=True
qos=1
retain_message=True

# do the stuff
def readTempSensor(sensorName) :
    f = open(sensorName, 'r')
    lines = f.readlines()
    f.close()
    return lines
 
def readTempLines(sensorName) :
    lines = readTempSensor(sensorName)
    while lines[0].strip()[-3:] != 'YES':
        time.sleep(0.2)
        lines = readTempSensor(sensorName)
    temperaturStr = lines[1].find('t=')
    if temperaturStr != -1 :
        tempData = lines[1][temperaturStr+2:]
        tempCelsius = float(tempData) / 1000.0
        tempKelvin = 273 + float(tempData) / 1000
        tempFahrenheit = float(tempData) / 1000 * 9.0 / 5.0 + 32.0
        return [tempCelsius, tempKelvin, tempFahrenheit]

#MQTT Connection
client=mqtt.Client(clientid)
client.username_pw_set(username, password)
client.tls_set(cert_reqs=ssl.CERT_NONE) #no client certificate needed
client.tls_insecure_set(insecure)
client.connect(broker, port)
client.loop_start()

client.publish("{}/temperature".format(publish_topic),"{:.2f}".format(readTempLines(sensor)[0]),qos,retain_message)

client.disconnect()
client.loop_stop()

dann noch dem Script das Execute Recht geben:

chmod +x /usr/local/sbin/ds18b20-mqtt.py

Möchte man das Ganze zum Beispiel alle Minute haben, kann man das Script einfach als cronjob laufen lassen.

/etc/cron.d/mqtt

# sends data from DS18B20 Sensor to MQTT Broker
* * * * * root /usr/local/sbin/ds18b20-mqtt.py >/dev/null 2>&1

Git Repository

Alle Skripte die zu den Raspberry Pi Sensoren gehören findet ihr in diesem Repository:

Quellen