Raspberry Pi

Raspberry Pi DHT22 MQTT: Temperatur und Luftfeuchte zuverlässig mit Python veröffentlichen

Schließen Sie einen DHT22 an einen Raspberry Pi an, lesen Sie ihn mit Python aus und veröffentlichen Sie validierte Temperatur- und Feuchtewerte als JSON per MQTT – mit Wiederholungen, Medianfilter und Fehlerzählern, die falsche Messwerte aus Ihren Dashboards fernhalten.

DHT22-Temperatur- und Feuchtesensor auf einem Steckbrett, verbunden mit einem Raspberry Pi, der Messwerte an einen Cloud-Broker sendet – ein Raspberry Pi DHT22 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 DHT22 MQTT Sensor ist ein klassisches erstes IoT-Projekt – und zugleich eine klassische Quelle für Frust: Der DHT22 ist günstig und für Räume und Gewächshäuser genau genug, aber durch sein zeitkritisches Protokoll schlagen auf einem Linux-Board manche Lesevorgänge fehl. In diesem Tutorial verdrahten Sie den Sensor, lesen ihn aus Python aus und veröffentlichen saubere Temperatur- und Feuchtewerte als JSON an einen MQTT-Broker – mit sauberer Behandlung von Lesefehlern, unplausiblen Werten und Netzwerkaussetzern.

Warum der DHT22 manchmal versagt

Der DHT22 (auch als AM2302 verkauft) nutzt weder I2C noch 1-Wire. Der Pi muss eine GPIO-Leitung umschalten und dann eine Folge von Impulsen messen, die nur einige zehn Mikrosekunden dauern. Raspberry Pi OS ist kein Echtzeitbetriebssystem; plant der Kernel im falschen Moment etwas anderes ein, geht ein Bit verloren und die Prüfsumme schlägt fehl. Das ist normales Verhalten, kein defekter Sensor. Die Lösung liegt in der Software:

  1. Warten Sie mindestens zwei Sekunden zwischen den Lesevorgängen; schneller kann der Sensor nicht messen.
  2. Fangen Sie den RuntimeError ab, den die Bibliothek auslöst, und versuchen Sie es erneut.
  3. Verwerfen Sie Werte außerhalb des physikalischen Messbereichs des Sensors.
  4. Nehmen Sie mehrere gültige Messwerte und veröffentlichen Sie den Median.
  5. Zählen Sie Fehler und veröffentlichen Sie sie, damit Sie merken, wenn ein Sensor wirklich ausfällt.

Verdrahtung

DHT22-Pin Raspberry Pi
VCC (Pin 1) 3,3 V (physischer Pin 1)
DATA (Pin 2) GPIO4 (physischer Pin 7)
NC (Pin 3) Nicht verbunden
GND (Pin 4) GND (physischer Pin 9)

Ein einzelner DHT22 braucht einen Pull-up-Widerstand von 4,7 k bis 10 k zwischen DATA und 3,3 V. Dreipolige Breakout-Module bringen ihn meist mit. Halten Sie das Kabel anfangs kurz; lange Leitungen funktionieren, sind aber störanfälliger, und ein kleinerer Pull-up-Wert kann bei längeren Kabeln helfen. Versorgen Sie ihn mit 3,3 V, nie mit 5 V, denn die Datenleitung geht direkt an einen GPIO-Pin, der nicht 5-V-tolerant ist.

Die Bibliotheken installieren

sudo apt update
sudo apt install -y python3-venv libgpiod2
mkdir -p ~/dht22-mqtt && cd ~/dht22-mqtt
python3 -m venv .venv
source .venv/bin/activate
pip install "paho-mqtt>=2.0" adafruit-circuitpython-dht

adafruit-circuitpython-dht zieht Adafruit Blinka nach, das das Modul board bereitstellt. Testen Sie den Sensor allein, bevor Sie MQTT hinzufügen:

python -c "import time, board, adafruit_dht; d = adafruit_dht.DHT22(board.D4); time.sleep(2); print(d.temperature, d.humidity); d.exit()"

Sehen Sie einen Fehler wie „A full buffer was not returned“, führen Sie den Befehl erneut aus; ein einzelner Fehlschlag ist zu erwarten. Schlägt jeder Versuch fehl, prüfen Sie Verdrahtung und Pull-up. Auf manchen Raspberry-Pi-Modellen und Betriebssystemversionen funktioniert der Pulse-Input-Helper nicht; legen Sie den Sensor dann mit adafruit_dht.DHT22(board.D4, use_pulseio=False) an, um den Bit-Banging-Fallback zu nutzen.

Payload und Topics

Das Skript veröffentlicht pro Intervall ein JSON-Dokument plus einen Retained-Status:

{
  "temperature": 22.4,
  "humidity": 48.1,
  "samples": 3,
  "read_errors": 2,
  "ts": 1792152000
}
Topic Inhalt Retained
connectmq/demo/c3f19a/greenhouse/dht22 JSON-Messwert alle 30 s Nein
connectmq/demo/c3f19a/greenhouse/status online / offline (Last Will) Ja

Ersetzen Sie c3f19a durch eine eigene Zufallszeichenfolge. read_errors in jeder Nachricht kostet ein paar Bytes und macht aus einem stillen Hardwareproblem etwas, das Sie grafisch darstellen und alarmieren können.

Das Raspberry Pi DHT22 MQTT Skript

Speichern Sie dies als dht22_mqtt.py:

#!/usr/bin/env python3
"""Read a DHT22 and publish validated readings to MQTT."""
import json
import os
import statistics
import time
import uuid

import adafruit_dht
import board
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"dht22-{uuid.uuid4().hex[:8]}")
PREFIX = os.getenv("MQTT_PREFIX", "connectmq/demo/c3f19a/greenhouse")
INTERVAL = int(os.getenv("PUBLISH_INTERVAL", "30"))
SAMPLES = 3
MAX_ATTEMPTS = 10

sensor = adafruit_dht.DHT22(board.D4)
total_errors = 0


def plausible(temp, hum):
    return (
        temp is not None and hum is not None
        and -40.0 <= temp <= 80.0
        and 0.0 <= hum <= 100.0
    )


def read_median():
    """Collect SAMPLES good readings and return their medians, or None."""
    global total_errors
    temps, hums = [], []
    attempts = 0
    while len(temps) < SAMPLES and attempts < MAX_ATTEMPTS:
        attempts += 1
        try:
            t, h = sensor.temperature, sensor.humidity
            if plausible(t, h):
                temps.append(t)
                hums.append(h)
            else:
                total_errors += 1
        except RuntimeError as err:
            # Prüfsummen- oder Timingfehler sind ab und zu zu erwarten.
            total_errors += 1
            print(f"Read failed ({err}); retrying")
        time.sleep(2.2)
    if not temps:
        return None
    return statistics.median(temps), statistics.median(hums), len(temps)


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()
        result = read_median()
        if result is None:
            payload = {"error": "no valid reading", "read_errors": total_errors,
                       "ts": int(time.time())}
        else:
            temp, hum, n = result
            payload = {
                "temperature": round(temp, 1),
                "humidity": round(hum, 1),
                "samples": n,
                "read_errors": total_errors,
                "ts": int(time.time()),
            }
        info = client.publish(f"{PREFIX}/dht22", json.dumps(payload), qos=1)
        if info.rc != mqtt.MQTT_ERR_SUCCESS:
            print(f"Publish queued while offline (rc={info.rc})")
        print(payload)
        elapsed = time.monotonic() - started
        time.sleep(max(0, INTERVAL - elapsed))
except KeyboardInterrupt:
    pass
finally:
    client.publish(f"{PREFIX}/status", "offline", qos=1, retain=True).wait_for_publish(2)
    client.loop_stop()
    client.disconnect()
    sensor.exit()

Einige Details verdienen Beachtung. Die Pause von gut zwei Sekunden zwischen den Lesevorgängen respektiert das Abtastlimit des Sensors. Der Median aus drei Messwerten entfernt gelegentliche einzelne Ausreißer, die die Prüfsumme bestehen, aber trotzdem falsch sind. Schlägt jeder Versuch fehl, veröffentlicht das Skript dennoch eine Nachricht mit einem Feld error, sodass Abonnenten „Sensor defekt“ von „Pi offline“ unterscheiden können – Letzteres deckt das Retained-Status-Topic ab. Schließlich gibt sensor.exit() die GPIO-Leitung frei; ohne diesen Aufruf kann der Pin beim nächsten Lauf belegt bleiben.

Die Daten verfolgen

Abonnieren Sie auf Ihrem Laptop, um zu prüfen, ob Nachrichten ankommen:

mosquitto_sub -h broker.connectmq.com -p 1883 -i laptop-c3f19a \
  -t 'connectmq/demo/c3f19a/greenhouse/#' -v

Sie sollten sofort status online sehen (es ist retained) und etwa alle 30 Sekunden einen JSON-Messwert. Trennen Sie den Pi für eine Minute vom Netzwerk und verbinden Sie ihn wieder: paho stellt die Verbindung automatisch wieder her. QoS-1-Nachrichten, die während der Unterbrechung veröffentlicht werden, liegen im Arbeitsspeicher und werden nach dem Reconnect gesendet, solange der Prozess weiterläuft. Sollen Messwerte einen Neustart während eines Ausfalls überstehen, sehen Sie sich an, wie Sie MQTT-Nachrichten in Python offline puffern – mit SQLite.

Das Sendeintervall wählen

Temperatur und Luftfeuchte in einem Raum oder Gewächshaus ändern sich langsam. Alle 30 bis 60 Sekunden zu veröffentlichen ergibt glatte Diagramme, ohne Broker oder Datenbank zu fluten. Häufiger als alle 10 Sekunden bringt bei einem DHT22 selten zusätzliche Information, und jeder Lesezyklus mit Wiederholungen dauert ohnehin mehrere Sekunden. Interessieren Sie nur Änderungen, veröffentlichen Sie, wenn sich der Wert um mehr als 0,2 °C oder 1 % Luftfeuchte ändert, plus einen Heartbeat alle paar Minuten.

Die Platzierung des Sensors ist so wichtig wie das Intervall. Montieren Sie den DHT22 mit Abstand zum Pi, außerhalb direkter Sonneneinstrahlung und fern von Heizkörpern oder Lüftungsauslässen, mit freier Luftzirkulation um die Öffnungen seines Gehäuses. Ein Sensor, der auf das Pi-Gehäuse geklebt ist, misst vor allem den Prozessor. Im Gewächshaus verhindert ein kleiner Strahlungsschutz aus gestapelten weißen Tellern, dass Sonnenlicht den Temperaturwert verfälscht.

DHT22 im Vergleich zu anderen Sensoren

Der DHT22 eignet sich gut zur Überwachung in Innenräumen, ist aber nicht die einzige Option. Ein wasserdichter DS18B20-Fühler ist für reine Temperaturmessung weit robuster und unterstützt viele Fühler an einer Leitung; siehe den Leitfaden Raspberry Pi DS18B20 MQTT. Wenn Sie denselben Sensor lieber an einem batteriebetriebenen Mikrocontroller betreiben, nutzt das Tutorial ESP32 DHT22 MQTT einen identischen Payload, sodass beide Geräte dasselbe Dashboard speisen können. Für den Gesamtüberblick zu Publish, Subscribe und dem Start von Skripten beim Booten beginnen Sie mit unserem Raspberry Pi MQTT Tutorial.

Wechsel auf einen privaten Broker

Der kostenlose öffentliche MQTT-Broker unter broker.connectmq.com ist perfekt zum Testen, aber jedes Topic dort ist für jeden lesbar. Für ein echtes Gewächshaus oder einen Serverraum erstellen Sie einen privaten Broker bei ConnectMQ, setzen dann die Umgebungsvariablen und starten neu:

export MQTT_PORT=8883
export MQTT_USERNAME=YOUR_USERNAME
export MQTT_PASSWORD=YOUR_PASSWORD
export MQTT_CLIENT_ID=YOUR_CLIENT_ID
export MQTT_PREFIX=site1/greenhouse/zone1
python dht22_mqtt.py

Im ConnectMQ-Portal können Sie die Messwerte im Live-Topic-Explorer verfolgen und eine Schwellwert-Alarmregel anlegen, etwa für eine Luftfeuchte über 85 %, ohne einen zusätzlichen Subscriber zu schreiben.

Checkliste zur Fehlerbehebung

  1. Jeder Lesevorgang schlägt fehl: Prüfen Sie, ob DATA an GPIO4 liegt, der Pull-up vorhanden ist und VCC 3,3 V beträgt.
  2. „Unable to set line to input“ oder GPIO belegt: Ein anderer Prozess hält den Pin; beenden Sie alte Skripte und stellen Sie sicher, dass sensor.exit() ausgeführt wird.
  3. Werte wirken plausibel, springen aber gelegentlich: Lassen Sie den Medianfilter aktiv und erhöhen Sie SAMPLES auf 5.
  4. Luftfeuchte hängt bei 99,9: Kondensat auf dem Sensor; DHT22-Sensoren vertragen dauerhafte Sättigung schlecht.
  5. Messwerte bleiben aus, aber der Status steht auf online: Das Skript hängt beim Lesen; ergänzen Sie einen Watchdog oder starten Sie über systemd mit Restart=always neu.
  6. Verbindung abgelehnt, nicht autorisiert: Zugangsdaten oder Client ID passen nicht zum Broker.

Jetzt mit ConnectMQ starten

Bringen Sie Ihren Sensor vom Labortisch in einen echten Einsatz auf einem Cloud-MQTT-Broker. Erstellen Sie einen kostenlosen Serverless-Broker ohne Kreditkarte, übernehmen Sie die generierten Zugangsdaten in Ihre Umgebung und verbinden Sie sich über TLS auf Port 8883. Ihre DHT22-Messwerte stehen innerhalb weniger Minuten Dashboards, Node-RED-Flows und Alarmregeln zur Verfügung.

Häufig gestellte Fragen

Warum meldet mein DHT22 auf dem Raspberry Pi „Checksum did not validate“?

Linux unterbricht gelegentlich das präzise Timing, das der DHT22 braucht, daher schlagen manche Lesevorgänge fehl. Fangen Sie den Fehler ab, warten Sie zwei Sekunden und versuchen Sie es erneut; einige Fehlschläge pro Stunde sind normal.

Wie oft kann ich einen DHT22 auslesen?

Höchstens einmal alle zwei Sekunden. Für das Veröffentlichen per MQTT reicht ein Intervall von 30 bis 60 Sekunden für die Raum- und Gewächshausüberwachung völlig aus.

Sollte ich für Sensorwerte QoS 0 oder QoS 1 verwenden?

QoS 1 ist ein guter Standard, weil es die Zustellung bei geringem Overhead garantiert. QoS 0 ist für sehr häufige Messwerte akzeptabel, bei denen der Verlust eines Werts keine Rolle spielt.

Kann ich mehrere DHT22-Sensoren an einen Raspberry Pi anschließen?

Ja. Geben Sie jedem einen eigenen GPIO-Pin und legen Sie pro Pin ein DHT22-Objekt an. Lesen Sie sie nacheinander statt gleichzeitig aus und veröffentlichen Sie jeden auf einem eigenen Topic.

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.