Ein Raspberry Pi DS18B20 MQTT Aufbau ist der robusteste Weg, Temperaturen an mehreren Stellen gleichzeitig zu messen: Gefrier- und Kühlschrank, Vor- und Rücklauf, Aquarium, Gärbehälter oder Serverschrank. In diesem Tutorial aktivieren Sie den 1-Wire-Bus, schließen mehrere wasserdichte Fühler an einen einzigen GPIO-Pin an, lesen sie aus Python allein über den Kernel-Treiber aus und veröffentlichen benannte, validierte Messwerte per MQTT.
Warum der DS18B20 eine hervorragende Wahl ist
Der DS18B20 ist ein digitaler Sensor, daher beeinflussen Kabellänge und elektrische Störungen ihn weit weniger als analoge Sensoren. Jeder Fühler hat eine eindeutige, ab Werk eingebrannte 64-Bit-Seriennummer, sodass sich viele Fühler eine Datenleitung teilen können. Wasserdichte Versionen stecken in einer Edelstahlhülse an einem langen Kabel und sind bereit für Flüssigkeiten oder den Außeneinsatz. Die Genauigkeit liegt im üblichen Bereich bei etwa einem halben Grad, die Auflösung lässt sich auf bis zu 0,0625 °C einstellen.
Das Beste: Raspberry Pi OS enthält einen Kernel-Treiber dafür. Sie brauchen keine Python-Bibliothek, um die Sensoren auszulesen; sie erscheinen als Dateien.
Einen oder viele Fühler verdrahten
Alle Fühler werden parallel an dieselben drei Leitungen angeschlossen:
| DS18B20-Ader (wasserdichter Fühler) | Raspberry Pi |
|---|---|
| Rot: VDD | 3,3 V (physischer Pin 1) |
| Schwarz: GND | GND (physischer Pin 6) |
| Gelb: DATA | GPIO4 (physischer Pin 7) |
Setzen Sie einen 4,7-k-Widerstand zwischen DATA und 3,3 V. Dieser eine Pull-up versorgt den gesamten Bus; fügen Sie nicht pro Fühler einen hinzu. Nutzen Sie wie gezeigt den Dreidrahtbetrieb (mit Versorgung) statt parasitärer Speisung, die bei mehreren Fühlern weniger zuverlässig ist. Bei langen Kabelwegen ist eine Sternverkabelung mit vielen Abzweigen die schwierigste Topologie für 1-Wire; eine einzelne Linie mit kurzen Stichleitungen funktioniert am besten, und ein kleinerer Pull-up wie 2,2 k kann bei langen Bussen helfen.
1-Wire aktivieren
Aktivieren Sie den Bus mit raspi-config oder fügen Sie das Overlay selbst hinzu:
sudo raspi-config nonint do_onewire 0
# oder gleichwertig diese Zeile in /boot/firmware/config.txt ergänzen:
# dtoverlay=w1-gpio,gpiopin=4
sudo reboot
Listen Sie nach dem Neustart die erkannten Fühler auf:
ls /sys/bus/w1/devices/
cat /sys/bus/w1/devices/28-*/w1_slave
Jeder Fühler erscheint als Verzeichnis, das mit 28- beginnt. Die Datei w1_slave enthält zwei Zeilen: Die erste endet auf YES, wenn die CRC-Prüfung bestanden wurde, und die zweite endet mit t= gefolgt von der Temperatur in Tausendstelgrad, zum Beispiel t=21375 für 21,375 °C. Die Raspberry-Pi-Konfigurationsdokumentation beschreibt die Optionen des 1-Wire-Overlays.
Ihre Fühler benennen
Seriennummern wie 28-3c01d0752a8b sagen auf einem Dashboard nichts aus. Legen Sie eine Datei probes.json an, die jeder Seriennummer einen kurzen Namen zuordnet, der Teil des MQTT-Topics wird:
{
"28-3c01d0752a8b": "freezer",
"28-3c01d075f1e2": "fridge",
"28-0316a2794bff": "outdoor"
}
Um herauszufinden, welcher Fühler welcher ist, wärmen Sie einen in der Hand und beobachten, welcher Messwert steigt. Fühler, die nicht in der Datei stehen, werden weiterhin unter ihrer Seriennummer veröffentlicht, sodass ein neu hinzugefügter Fühler nie stillschweigend verschwindet.
Topic-Struktur
| Topic | Payload | Retained |
|---|---|---|
connectmq/demo/b81f2d/house/temp/<name> |
{"celsius": 4.2, "ts": ...} |
Nein |
connectmq/demo/b81f2d/house/temp/all |
Alle Fühler in einem JSON-Objekt | Nein |
connectmq/demo/b81f2d/house/status |
online / offline |
Ja |
Topics pro Fühler eignen sich für Dashboards und Alarmregeln auf einen einzelnen Wert; die kombinierte Nachricht ist praktisch für Logger, die pro Intervall eine Zeile schreiben. Ersetzen Sie b81f2d durch eine eigene Zufallszeichenfolge.
Das Raspberry Pi DS18B20 MQTT Skript
Speichern Sie es als ds18b20_mqtt.py:
#!/usr/bin/env python3
"""Read all DS18B20 probes on the 1-Wire bus and publish them to MQTT."""
import json
import os
import time
import uuid
from pathlib import Path
import paho.mqtt.client as mqtt
BROKER = os.getenv("MQTT_HOST", "broker.connectmq.com")
PORT = int(os.getenv("MQTT_PORT", "1883"))
USERNAME = os.getenv("MQTT_USERNAME")
PASSWORD = os.getenv("MQTT_PASSWORD")
CLIENT_ID = os.getenv("MQTT_CLIENT_ID", f"ds18b20-{uuid.uuid4().hex[:8]}")
PREFIX = os.getenv("MQTT_PREFIX", "connectmq/demo/b81f2d/house")
INTERVAL = int(os.getenv("PUBLISH_INTERVAL", "60"))
W1_DIR = Path("/sys/bus/w1/devices")
NAMES_FILE = Path(os.getenv("PROBES_FILE", "probes.json"))
def load_names():
try:
return json.loads(NAMES_FILE.read_text())
except (OSError, json.JSONDecodeError):
return {}
def read_probe(device: Path, retries: int = 3):
"""Return degrees Celsius, or None if the probe gives no valid reading."""
for _ in range(retries):
try:
lines = (device / "w1_slave").read_text().strip().splitlines()
except OSError:
return None # Fühler abgesteckt
if len(lines) == 2 and lines[0].endswith("YES") and "t=" in lines[1]:
millis = int(lines[1].split("t=")[1])
if millis != 85000: # 85,0 °C ist der Power-on-Reset-Wert
celsius = millis / 1000.0
if -55.0 <= celsius <= 125.0:
return celsius
time.sleep(0.2)
return None
def on_connect(client, userdata, flags, reason_code, properties):
if reason_code.is_failure:
print(f"Connection refused: {reason_code}")
return
print(f"Connected as {CLIENT_ID}")
client.publish(f"{PREFIX}/status", "online", qos=1, retain=True)
client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id=CLIENT_ID)
client.on_connect = on_connect
client.will_set(f"{PREFIX}/status", "offline", qos=1, retain=True)
client.reconnect_delay_set(min_delay=1, max_delay=60)
if USERNAME:
client.username_pw_set(USERNAME, PASSWORD)
if PORT == 8883:
client.tls_set()
client.connect(BROKER, PORT, keepalive=60)
client.loop_start()
try:
while True:
started = time.monotonic()
names = load_names()
now = int(time.time())
combined = {}
for device in sorted(W1_DIR.glob("28-*")):
name = names.get(device.name, device.name)
celsius = read_probe(device)
if celsius is None:
combined[name] = None
print(f"{name}: no valid reading")
continue
combined[name] = round(celsius, 2)
payload = {"celsius": round(celsius, 2), "ts": now}
client.publish(f"{PREFIX}/temp/{name}", json.dumps(payload), qos=1)
client.publish(
f"{PREFIX}/temp/all", json.dumps({"probes": combined, "ts": now}), qos=1
)
print(combined)
time.sleep(max(0, INTERVAL - (time.monotonic() - started)))
except KeyboardInterrupt:
pass
finally:
client.publish(f"{PREFIX}/status", "offline", qos=1, retain=True).wait_for_publish(2)
client.loop_stop()
client.disconnect()
Es ist keine Sensorbibliothek nötig; paho-mqtt ist die einzige Abhängigkeit:
mkdir -p ~/ds18b20-mqtt && cd ~/ds18b20-mqtt
python3 -m venv .venv && source .venv/bin/activate
pip install "paho-mqtt>=2.0"
python ds18b20_mqtt.py
Das Skript liest probes.json in jedem Zyklus neu ein, sodass Sie einen Fühler umbenennen können, ohne neu zu starten. Fehlende oder fehlerhafte Fühler werden in der kombinierten Nachricht als null gemeldet statt weggelassen, wodurch ein defektes Kabel auf dem Dashboard sichtbar wird.
Die klassischen Stolperfallen
- Ein Messwert von genau 85,0 °C: Der Fühler hat seinen Einschalt-Standardwert geliefert, bevor eine Wandlung abgeschlossen war – typischerweise durch eine schwache Versorgung oder parasitäre Speisung. Das Skript verwirft ihn.
w1_slavezeigt in der ersten ZeileNO: Die CRC-Prüfung ist wegen Störungen oder eines langen Kabels fehlgeschlagen. Das Skript versucht es bis zu dreimal.- Fühler erscheinen und verschwinden im Verzeichnis: Wackelkontakte oder ein überlasteter Bus; prüfen Sie Lötstellen und den Pull-up-Wert.
- Überhaupt keine
28--Verzeichnisse: 1-Wire ist nicht aktiviert, die Datenleitung liegt nicht an GPIO4, oder der Pull-up fehlt. - Langsame Zyklen bei vielen Fühlern: Jede 12-Bit-Wandlung dauert bis zu etwa drei Viertel einer Sekunde, und der Kernel liest die Fühler nacheinander. Zehn Fühler brauchen daher mehrere Sekunden pro Zyklus, was bei einem 60-Sekunden-Intervall unproblematisch ist.
Auflösung gegen Geschwindigkeit tauschen
Die meisten Anwendungen brauchen keine Schritte von 0,0625 °C. Aktuelle Kernel stellen für jeden Fühler eine Datei resolution bereit, über die Sie die Auflösung senken und die Wandlungszeit verkürzen können:
cat /sys/bus/w1/devices/28-3c01d0752a8b/resolution
echo 10 | sudo tee /sys/bus/w1/devices/28-3c01d0752a8b/resolution
Bei 10 Bit beträgt die Schrittweite 0,25 °C, und jede Wandlung ist in einem Bruchteil der 12-Bit-Zeit fertig. Das hilft, wenn ein Bus viele Fühler trägt oder Sie schnellere Aktualisierungen möchten. Die Einstellung liegt im flüchtigen Speicher des Fühlers und wird nach einem Stromausfall zurückgesetzt, sofern Sie sie nicht zusätzlich im EEPROM des Fühlers speichern; prüfen Sie vor dem Schreiben ins EEPROM die w1_therm-Dokumentation des Kernels für Ihre Version.
Denken Sie außerdem daran, wo der Fühler sitzt, nicht nur, wie präzise er ist. Ein Fühler an einem Rohr misst das Rohr genauer, wenn er mit einer Metallschelle fest angedrückt und mit Dämmung abgedeckt ist. Ein Fühler im Gefrierschrank sollte frei in der Luft hängen und keine gefrorene Packung berühren – es sei denn, Sie wollen die Temperatur des Lebensmittels wissen.
Die Messwerte verfolgen
mosquitto_sub -h broker.connectmq.com -p 1883 -i watch-b81f2d \
-t 'connectmq/demo/b81f2d/house/#' -v
Sie sehen jede Minute eine Nachricht pro Fühler und danach die kombinierte Nachricht. Auf dem öffentlichen MQTT-Broker sind diese Topics für jeden sichtbar, bleiben Sie also bei Testdaten und einem zufälligen Präfix.
Wie es weitergeht
Ein 1-Wire-Bus passt perfekt zu einem kompakten Knoten; das Skript läuft unverändert auf einem Raspberry Pi Zero 2 W als MQTT-Sensorknoten. Wenn Sie zusätzlich die Luftfeuchte messen möchten, kombinieren Sie es mit dem Leitfaden Raspberry Pi DHT22 MQTT, der denselben Topic-Stil verwendet. Für Langzeitdiagramme abonniert der Stack aus Grafana und InfluxDB auf dem Raspberry Pi diese Topics über Telegraf und speichert Monate an Historie.
Einrichtung für den Produktivbetrieb
Gefrierschrankalarme und Heizungsüberwachung verdienen eine private, verschlüsselte Verbindung. ConnectMQ ist ein vollständig verwalteter MQTT-Broker: Erstellen Sie einen Broker im Portal und starten Sie das Skript dann mit TLS:
export MQTT_PORT=8883
export MQTT_USERNAME=YOUR_USERNAME
export MQTT_PASSWORD=YOUR_PASSWORD
export MQTT_CLIENT_ID=YOUR_CLIENT_ID
export MQTT_PREFIX=home/kitchen
python ds18b20_mqtt.py
Im ConnectMQ-Portal erfasst eine Schwellwert-Alarmregel auf home/kitchen/temp/freezer, zum Beispiel über -12 °C, einen Alarm, den Sie im Alarmprotokoll einsehen können. Betreiben Sie das Skript als systemd-Dienst, damit es nach Stromausfällen neu startet; das Raspberry Pi MQTT Tutorial enthält die Vorlage.
Jetzt mit ConnectMQ starten
Senden Sie Ihre Fühlerwerte an einen MQTT-Broker in der Cloud, den Dashboards, Logger und Alarmregeln von überall erreichen. Erstellen Sie einen kostenlosen ConnectMQ-Broker im Serverless-Tarif ohne Kreditkarte, übernehmen Sie die generierten Zugangsdaten in Ihre Umgebung und verbinden Sie sich über TLS auf Port 8883.
Häufig gestellte Fragen
Wie viele DS18B20-Fühler kann ich an einen Pin des Raspberry Pi anschließen?
Dank ihrer eindeutigen Seriennummern können sich viele Fühler einen Bus teilen. In der Praxis begrenzen Kabellänge und Topologie früher als der Adressraum; eine Handvoll bis einige Dutzend an einem gut verdrahteten Bus sind realistisch.
Warum zeigt mein DS18B20 85 Grad an?
85,0 °C ist der Wert, den der Sensor nach dem Einschalten vor seiner ersten Wandlung hält. Er deutet meist auf ein Versorgungsproblem oder einen zu frühen Lesevorgang hin; verwerfen Sie ihn und prüfen Sie die Verdrahtung.
Brauche ich eine Python-Bibliothek, um einen DS18B20 auszulesen?
Nein. Die Kernel-Treiber w1-gpio und w1-therm stellen jeden Fühler als Datei in /sys/bus/w1/devices bereit, die einfaches Python lesen kann.
Kann ich einen anderen GPIO-Pin für 1-Wire verwenden?
Ja. Setzen Sie dtoverlay=w1-gpio,gpiopin=17 (oder einen anderen Pin) in /boot/firmware/config.txt und starten Sie neu.



