Raspberry Pi

Raspberry Pi Luftqualität messen mit BME680 und MQTT

Schließen Sie einen BME680 an einen Raspberry Pi an, kalibrieren Sie eine Gas-Basislinie, berechnen Sie einen einfachen Raumluftqualitätswert und streamen Sie alles an einen MQTT-Broker, den Sie von überall verfolgen können.

Raspberry Pi misst die Luftqualität mit einem BME680-Sensorboard und sendet Gas-, Feuchte- und Temperaturwerte an ein MQTT-Dashboard
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

Mit einem Raspberry Pi die Luftqualität zu messen – rund um den Bosch BME680 aufgebaut – ist eines der nützlichsten kleinen Sensorprojekte für Büro, Werkstatt oder Schlafzimmer. In diesem Tutorial schließen Sie den Sensor an, lesen Temperatur, Luftfeuchte, Luftdruck und Gaswiderstand in Python aus, machen aus diesen Rohwerten einen einfachen Schätzwert für die Raumluftqualität (IAQ) und veröffentlichen alles per MQTT, sodass jedes Dashboard oder Smartphone live mitlesen kann.

Was der BME680 tatsächlich misst

Der BME680 vereint vier Messungen in einem winzigen Gehäuse: Temperatur, relative Luftfeuchte, Luftdruck und den Widerstand einer beheizten Metalloxid-Gasschicht. Die ersten drei sind einfache physikalische Größen. Die vierte ist die interessante – und zugleich die am häufigsten missverstandene.

Der Gassensor meldet weder ein bestimmtes Gas noch eine Konzentration in ppm. Flüchtige organische Verbindungen (VOCs) aus Reinigungsmitteln, vom Kochen, aus Farbe, von Menschen und Möbeln reagieren mit der beheizten Sensorschicht und senken deren Widerstand. Saubere Luft ergibt einen hohen Widerstand, belastete Luft einen niedrigeren. Damit ist der Rohwert ein relativer Indikator: hervorragend, um Trends und Ereignisse zu erkennen („jemand hat gerade mit dem Kochen begonnen“, „der Raum muss gelüftet werden“), aber keine Labormessung.

Bosch liefert eine Closed-Source-Bibliothek namens BSEC, die diese Messwerte in einen kalibrierten IAQ-Index von 0 bis 500 und geschätzte CO2-Äquivalente umrechnet. Sie funktioniert gut, ist aber ein Binärblob mit eigener Lizenz und eigenem Integrationsaufwand. Für einen Hobby- oder Labormonitor genügt oft ein transparenter, basislinienbasierter Wert – und genau den bauen wir hier. Falls Sie später BSEC brauchen, bleibt die MQTT-Seite dieses Projekts exakt gleich.

Messwert Einheit Typischer Bereich in Innenräumen Aussage
Temperatur °C 18 bis 26 Komfort und Korrekturfaktor für die Gasschicht
Relative Luftfeuchte % 30 bis 60 Komfort, Schimmelrisiko, Teil des IAQ-Werts
Luftdruck hPa 950 bis 1050 Wettertrend, nicht Luftqualität
Gaswiderstand Ohm Zehn bis einige hundert kOhm Relatives VOC-Niveau; höher ist sauberer

Bauteile und Verdrahtung

Sie benötigen:

  1. Einen beliebigen Raspberry Pi mit 40-Pin-Leiste (Zero 2 W, 3, 4 oder 5) mit Raspberry Pi OS.
  2. Ein BME680-Breakout-Board. Adafruit, Pimoroni und viele generische Boards funktionieren; prüfen Sie, ob Ihres die I2C-Adresse 0x76 oder 0x77 verwendet.
  3. Vier Jumper-Kabel.

Verbinden Sie das Breakout-Board über I2C mit dem Pi:

BME680-Pin Raspberry-Pi-Pin
VIN / 3V3 Pin 1 (3,3 V)
GND Pin 6 (GND)
SDA / SDI Pin 3 (GPIO 2, SDA)
SCL / SCK Pin 5 (GPIO 3, SCL)

Montieren Sie den Sensor mit Abstand zum Pi. CPU und Spannungsregler erwärmen das Board, und ein Sensor direkt über dem SoC misst mehrere Grad zu viel und drückt die Luftfeuchte nach unten. Ein 10 bis 15 cm langes Kabel oder ein kleiner Abstandshalter macht einen spürbaren Unterschied.

Den Raspberry Pi vorbereiten

Aktivieren Sie I2C, prüfen Sie, ob der Sensor sichtbar ist, und legen Sie eine virtuelle Python-Umgebung an (ab Raspberry Pi OS Bookworm für pip-Installationen erforderlich):

sudo raspi-config nonint do_i2c 0
sudo apt update && sudo apt install -y i2c-tools python3-venv
i2cdetect -y 1          # 76 oder 77 im Raster erwartet

python3 -m venv ~/aq-env
source ~/aq-env/bin/activate
pip install adafruit-circuitpython-bme680 paho-mqtt

Zeigt i2cdetect ein leeres Raster, prüfen Sie SDA und SCL erneut (sie lassen sich leicht vertauschen) und stellen Sie sicher, dass das Board mit 3,3 V versorgt wird. Die offizielle Raspberry-Pi-Konfigurationsdokumentation beschreibt die I2C-Einrichtung ausführlicher, falls Sie ein nicht standardmäßiges Image verwenden.

Das Skript zum Messen der Luftqualität mit dem Raspberry Pi

Das folgende Skript erledigt vier Dinge: Es liest den Sensor alle zehn Sekunden aus, führt eine fünfminütige Einbrennphase durch, um eine Gas-Basislinie zu ermitteln, berechnet aus Gas und Luftfeuchte einen IAQ-Schätzwert und veröffentlicht eine JSON-Nachricht an den kostenlosen öffentlichen MQTT-Broker unter broker.connectmq.com. Außerdem setzt es einen Last Will, damit Abonnenten erfahren, wenn der Monitor offline geht.

#!/usr/bin/env python3
"""Raspberry Pi air quality monitor: BME680 -> MQTT."""
import json
import time
import uuid

import board
import adafruit_bme680
import paho.mqtt.client as mqtt

BROKER = "broker.connectmq.com"
PORT = 1883
DEVICE_ID = "pi-aq-" + uuid.uuid4().hex[:6]
BASE_TOPIC = f"connectmq/demo/{DEVICE_ID}/air"
I2C_ADDRESS = 0x77          # für Boards im Pimoroni-Stil auf 0x76 ändern
INTERVAL = 10               # Sekunden zwischen den Messungen
BURN_IN = 300               # Sekunden zum Erlernen der Basislinie für saubere Luft
HUM_BASELINE = 40.0         # ideale Raumluftfeuchte in Prozent
HUM_WEIGHT = 0.25           # Anteil der Luftfeuchte am Wert


def on_connect(client, userdata, flags, reason_code, properties):
    print("Connected:", reason_code)
    client.publish(f"{BASE_TOPIC}/status", "online", qos=1, retain=True)


def iaq_score(gas, hum, gas_baseline):
    """0-100, higher is better. Simple, transparent estimate, not Bosch BSEC."""
    hum_offset = hum - HUM_BASELINE
    if hum_offset > 0:
        hum_score = (100 - HUM_BASELINE - hum_offset) / (100 - HUM_BASELINE)
    else:
        hum_score = (HUM_BASELINE + hum_offset) / HUM_BASELINE
    hum_score *= HUM_WEIGHT * 100

    gas_offset = gas_baseline - gas
    if gas_offset > 0:
        gas_score = (gas / gas_baseline) * (100 - HUM_WEIGHT * 100)
    else:
        gas_score = 100 - HUM_WEIGHT * 100
    return round(max(0.0, min(100.0, hum_score + gas_score)), 1)


def main():
    i2c = board.I2C()
    sensor = adafruit_bme680.Adafruit_BME680_I2C(i2c, address=I2C_ADDRESS)
    sensor.sea_level_pressure = 1013.25

    client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id=DEVICE_ID)
    client.will_set(f"{BASE_TOPIC}/status", "offline", qos=1, retain=True)
    client.on_connect = on_connect
    client.connect(BROKER, PORT, keepalive=60)
    client.loop_start()

    print(f"Burn-in for {BURN_IN} s, publishing to {BASE_TOPIC}/#")
    samples = []
    start = time.time()
    while time.time() - start < BURN_IN:
        samples.append(sensor.gas)
        time.sleep(1)
    gas_baseline = sum(samples[-50:]) / len(samples[-50:])
    print(f"Gas baseline: {gas_baseline:.0f} Ohm")

    while True:
        gas = sensor.gas
        hum = sensor.relative_humidity
        payload = {
            "ts": int(time.time()),
            "temperature_c": round(sensor.temperature, 2),
            "humidity_pct": round(hum, 1),
            "pressure_hpa": round(sensor.pressure, 1),
            "gas_ohm": int(gas),
            "iaq_score": iaq_score(gas, hum, gas_baseline),
        }
        client.publish(f"{BASE_TOPIC}/telemetry", json.dumps(payload), qos=1)
        print(payload)
        time.sleep(INTERVAL)


if __name__ == "__main__":
    main()

Starten Sie es mit python aq_monitor.py. Während der Einbrennphase stabilisiert sich die Heizung; ein fabrikneuer Sensor driftet in den ersten ein bis zwei Tagen, also vertrauen Sie der Basislinie aus dem allerersten Lauf nicht. Bewährt hat es sich, das Skript an frischer Luft zu starten (öffnen Sie in den ersten fünf Minuten ein Fenster), denn die Basislinie legt fest, was für den Rest der Sitzung als „sauber“ gilt.

Den IAQ-Schätzwert interpretieren

Der Wert ist im Vergleich zum Bosch-Index umgekehrt: 100 bedeutet Luft so sauber wie die Basislinie bei idealer Luftfeuchte, niedriger bedeutet schlechter. Eine grobe Orientierung:

Wert Bedeutung Typische Maßnahme
80 bis 100 Nahe der Basislinie Nichts zu tun
60 bis 80 Spürbare VOCs oder Luftfeuchte außerhalb des Zielbereichs Im Auge behalten
40 bis 60 Deutlich schlechter als die Basislinie Raum lüften
Unter 40 Starke Quelle in der Nähe Quelle suchen, sofort lüften

Da die Basislinie relativ ist, vergleichen Sie Werte über die Zeit im selben Raum statt zwischen verschiedenen Geräten.

Die Daten live verfolgen

Öffnen Sie ein zweites Terminal (auf dem Pi oder Ihrem Laptop) und abonnieren Sie mit dem Mosquitto-Client. Ersetzen Sie die Geräte-ID durch die, die Ihr Skript ausgegeben hat:

mosquitto_sub -h broker.connectmq.com -p 1883 -i aq-viewer-$RANDOM \
  -t "connectmq/demo/pi-aq-1a2b3c/air/#" -v

Sie sollten zuerst den Retained-Status online sehen und dann alle zehn Sekunden eine Telemetrienachricht. Beenden Sie das Python-Skript mit Strg+C, und nach Ablauf des Keepalive stellt der Broker den Last Will offline zu. Denken Sie daran, dass der öffentliche MQTT-Broker für jeden lesbar ist, der das Topic kennt – Raumluftdaten sind in Ordnung, aber nichts Persönliches gehört dorthin.

Den Monitor unbeaufsichtigt betreiben

Ein Sensor, der stoppt, sobald Sie die SSH-Sitzung schließen, ist kein richtiger Monitor. Legen Sie eine systemd-Unit an, damit das Skript beim Booten startet und nach Fehlern neu startet:

# /etc/systemd/system/aq-monitor.service
[Unit]
Description=BME680 air quality monitor
After=network-online.target
Wants=network-online.target

[Service]
User=pi
ExecStart=/home/pi/aq-env/bin/python /home/pi/aq_monitor.py
Restart=always
RestartSec=10

[Install]
WantedBy=multi-user.target
sudo systemctl daemon-reload
sudo systemctl enable --now aq-monitor
journalctl -u aq-monitor -f

Passen Sie Benutzernamen und Pfade an Ihre Installation an. Dasselbe Muster wird für andere Sensoren ausführlicher im DS18B20-Temperaturprojekt und im DHT22-Luftfeuchte-Tutorial erklärt, die Sie mit diesem Projekt auf einem einzigen Pi kombinieren können.

Wechsel auf einen privaten Broker

Für alles jenseits von Experimenten veröffentlichen Sie an Ihren eigenen Broker mit Zugangsdaten und TLS. Bei ConnectMQ registrieren Sie sich, erstellen einen Broker und erhalten generierte Werte für Benutzername, Passwort und Client ID. Ändern Sie dann den Verbindungsblock:

client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2, client_id="YOUR_CLIENT_ID")
client.username_pw_set("YOUR_USERNAME", "YOUR_PASSWORD")
client.tls_set()                       # der System-CA-Speicher validiert das Let's-Encrypt-Zertifikat
client.will_set(f"{BASE_TOPIC}/status", "offline", qos=1, retain=True)
client.connect("broker.connectmq.com", 8883, keepalive=60)

Mit einem verwalteten MQTT-Broker müssen Sie keine Mosquitto-Instanz selbst patchen und erreichbar halten, und der Live-Topic-Explorer im Portal zeigt die eintreffende Telemetrie ohne zusätzliche Werkzeuge. Sie können außerdem eine Schwellwert-Alarmregel auf iaq_score oder humidity_pct anlegen, sodass das Alarmprotokoll im Portal jede Grenzwertüberschreitung im Raum festhält.

Fehlerbehebung

  1. ValueError: No I2C device at address: Die Adresse ist falsch. Verwenden Sie, was i2cdetect anzeigt (0x76 oder 0x77).
  2. Gaswiderstand bleibt sehr niedrig und steigt nie: Der Sensor konditioniert sich noch. Lassen Sie ihn mehrere Stunden eingeschaltet; Drift bei der ersten Nutzung ist normal.
  3. Temperatur mehrere Grad zu hoch: Wärme vom Pi oder von der sensoreigenen Heizung. Setzen Sie den Sensor vom Board ab oder wenden Sie nach einem Vergleich mit einem Referenzthermometer einen festen Offset an.
  4. Verbindung zum privaten Broker abgelehnt: Prüfen Sie, ob die Client ID exakt zu den ausgegebenen Zugangsdaten passt; ConnectMQ bindet Client IDs an Zugangsdaten.
  5. Nachrichten bleiben nach einem Netzwerkaussetzer aus: paho verbindet sich automatisch neu, solange loop_start() läuft, aber QoS-1-Nachrichten, die offline veröffentlicht werden, liegen nur im Arbeitsspeicher. Für längere Ausfälle ergänzen Sie einen lokalen Puffer.

Ideen zur Erweiterung des Projekts

Sobald die Daten fließen, ist der Rest reines MQTT. Node-RED kann abonnieren und über ein Relais einen Lüfter ansteuern. Telegraf kann das JSON für Langzeitdiagramme in InfluxDB schreiben. Ein zweiter Pi in einem anderen Raum kann unter seiner eigenen Geräte-ID veröffentlichen, sodass Sie Räume direkt vergleichen. Wenn die Plattform neu für Sie ist, behandelt das Raspberry Pi MQTT Tutorial die Grundlagen zu Clients, Topics und QoS, auf denen dieses Projekt aufbaut.

Jetzt mit ConnectMQ starten

Bringen Sie Ihr Projekt zum Messen der Luftqualität mit dem Raspberry Pi in wenigen Minuten vom öffentlichen MQTT-Broker auf einen privaten, TLS-gesicherten Broker. ConnectMQ bietet Ihnen einen verwalteten MQTT-Broker mit MQTT-Client im Browser, Live-Topic-Explorer und Schwellwert-Alarmen. Erstellen Sie einen kostenlosen Serverless-Broker ohne Kreditkarte und richten Sie Ihr Skript darauf aus.

Häufig gestellte Fragen

Ist der IAQ-Wert des BME680 identisch mit dem Bosch-BSEC-Index?

Nein. Der Wert in diesem Tutorial ist ein transparenter Schätzwert auf Basis einer Gas-Basislinie und der Luftfeuchte. Die BSEC-Bibliothek von Bosch liefert einen kalibrierten Index von 0 bis 500 mit automatischer Basislinienanpassung und lässt sich später einsetzen, ohne die MQTT-Topics zu ändern.

Wie lange muss sich der BME680 aufwärmen?

Die Heizung stabilisiert sich innerhalb weniger Minuten, weshalb das Skript eine fünfminütige Einbrennphase nutzt. Ein fabrikneuer Sensor driftet in den ersten ein bis zwei Betriebstagen weiter; danach werden die Messwerte konsistenter.

Kann ich mit einem BME680 CO2 messen?

Nicht direkt. Der BME680 reagiert auf VOCs, und jeder daraus abgeleitete CO2-Wert ist eine Schätzung. Für eine echte CO2-Messung nutzen Sie einen NDIR-Sensor wie den SCD40 oder SCD41 und veröffentlichen ihn zusammen mit den BME680-Daten.

Welchen MQTT-Broker sollte ich für einen Luftqualitätsmonitor zu Hause verwenden?

Der öffentliche MQTT-Broker eignet sich zum Ausprobieren, ist aber für alle lesbar. Für den Dauerbetrieb hält ein privater Broker mit Zugangsdaten und TLS, etwa ein kostenloser ConnectMQ-Serverless-Broker, Ihre Daten privat.

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.