Raspberry Pi

Raspberry Pi DS18B20 MQTT: Mehrere 1-Wire-Temperaturfühler veröffentlichen

Aktivieren Sie 1-Wire auf einem Raspberry Pi, schließen Sie mehrere DS18B20-Temperaturfühler an einen GPIO-Pin an, lesen Sie sie ohne zusätzliche Bibliotheken aus Python aus und veröffentlichen Sie benannte, validierte Messwerte per MQTT.

Mehrere wasserdichte DS18B20-Temperaturfühler an einem 1-Wire-Bus eines Raspberry Pi, der Messwerte in die Cloud sendet – ein Raspberry Pi DS18B20 MQTT Projekt
Probieren Sie es auf Ihrem eigenen MQTT-Broker ausHolen Sie sich im Free-Tarif einen privaten, verwalteten MQTT-Broker und starten Sie mit fertigen Codebeispielen.
Kostenlos testen Codebeispiele Keine Kreditkarte erforderlich

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

  1. 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.
  2. w1_slave zeigt in der ersten Zeile NO: Die CRC-Prüfung ist wegen Störungen oder eines langen Kabels fehlgeschlagen. Das Skript versucht es bis zu dreimal.
  3. Fühler erscheinen und verschwinden im Verzeichnis: Wackelkontakte oder ein überlasteter Bus; prüfen Sie Lötstellen und den Pull-up-Wert.
  4. Überhaupt keine 28--Verzeichnisse: 1-Wire ist nicht aktiviert, die Datenleitung liegt nicht an GPIO4, oder der Pull-up fehlt.
  5. 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.

Verwandte Artikel

Raspberry Pi RFID MQTT: Zutrittsprotokollierung mit dem RC522-Leser

Schließen Sie einen RC522-RFID-Leser an einen Raspberry Pi an, lesen Sie Tags mit Python, prüfen Sie sie gegen eine lokale Allowlist und veröffentlichen Sie jeden Zutrittsversuch als MQTT-Ereignis, das Logger, Dashboards und Alarmwerkzeuge verarbeiten können.

7 Min. Lesezeit

Pico W vs. Pico 2 W für MQTT: RP2040 vs. RP2350 bei Leistung, Speicher und TLS

Der Pico 2 W behält Formfaktor und WLAN-Chip des Pico W, ersetzt aber den RP2040 durch den schnelleren RP2350. Dieser Vergleich zeigt, was das für MQTT-Geräte bedeutet: CPU, Speicher, TLS, Sicherheitsfunktionen, Softwareunterstützung und welches Board für welches Projekt.

8 Min. Lesezeit

Alle Artikel →

Ihr privater MQTT-Broker ist nur wenige Klicks entfernt

Konto anlegen, Broker-Zugangsdaten erhalten und das erste Gerät verbinden — ohne Server, die installiert, gepatcht oder skaliert werden müssen.