Luftqualitätssensor mit MQ135 bauen, der Rauch und andere schädliche Gase für Alexa erkennt
In diesem Abschnitt zeigen wir dir Schritt für Schritt, wie du mit einem ESP32 oder ESP8266 einen Luftqualitätssensor baust. Danach kannst du die Luftqualität über Amazon Alexa abfragen und eine Push-Benachrichtigung über die Sinric Pro App erhalten, wenn die Luftqualität unter einen bestimmten Schwellenwert fällt.
Voraussetzungen :
- ESP32, ESP8266 x 1.
- MQ135 x 1.
- Jumperkabel.

Kurze Einführung in den MQ135
Der MQ135 ist ein Halbleiter-Gassensor, der häufig in Geräten zur Überwachung der Luftqualität eingesetzt wird. Er reagiert auf eine Vielzahl von Gasen, darunter Ammoniak, Sulfide, Benzol und Rauch. Der Sensor hat zwei Ausgänge: einen digitalen Ausgang, der auf High geht, wenn die Gaskonzentration einen bestimmten Schwellenwert überschreitet, und einen analogen Ausgang, der eine zur Gaskonzentration proportionale Spannung liefert.
Der MQ135 benötigt eine Versorgungsspannung von 5V und nimmt etwa 150mA Strom auf. Der digitale Ausgang kann an einen ESP32, ESP8266 oder Pico W angeschlossen werden, um die Gaskonzentration zu messen.
So kalibrierst du den MQ135
Der MQ135 gibt nicht direkt ppm aus. Sein Widerstand (Rs) ändert sich mit der Gaskonzentration, und der ppm-Wert wird aus dem Verhältnis zwischen Rs und R0 berechnet, dem Widerstand des Sensors in sauberer Luft. R0 ist bei jedem Sensor anders, deshalb muss jeder einzeln kalibriert werden.
1. Einbrennen (einmalig): Bring deinen Sensor nach draußen, wo es genug frische Luft gibt (laut Datenblatt idealerweise bei 20°C und 33% Luftfeuchtigkeit), und lass ihn 12-24 Stunden eingeschaltet, damit er einbrennt und sich stabilisiert.
2. Aufwärmen (bei jedem Einschalten): Der Sensor hat ein Heizelement. In den ersten Minuten nach dem Einschalten sind die Messwerte zu hoch. Warte also, bis sie sich eingependelt haben, bevor du sie verwendest.
3. R0 in sauberer Luft messen: Lass den Sensor weiter an der frischen Luft und die in diesem Tutorial verwendete Bibliothek TroykaMQ R0 berechnen und ausgeben:
#include <TroykaMQ.h>
#define PIN_MQ135 34 // ESP32. Use A0 on ESP8266
MQ135 mq135(PIN_MQ135);
void setup() {
Serial.begin(115200);
mq135.calibrate(); // run this in clean air
Serial.print("Ro = ");
Serial.println(mq135.getRo());
}
4. Wert wiederverwenden: Notiere den ausgegebenen R0-Wert und übergib ihn an calibrate(). Dann braucht der Sensor nicht bei jedem Neustart frische Luft:
mq135.calibrate(YOUR_RO_VALUE);
Temperatur und Luftfeuchtigkeit beeinflussen den Messwert. Kalibriere deshalb unter Bedingungen, die dem späteren Einsatzort möglichst nahekommen. Der MQ135 eignet sich gut, um zu erkennen, dass sich die Luftqualität verändert hat, er ist aber kein Präzisionsmessgerät.
MQ135 Messwert hängt oben fest (etwa 3800 bis 4095)?
Auf einem ESP32 liefert analogRead() Werte von 0 bis 4095. Bleibt ein Messwert am oberen Ende dieses Bereichs oder in dessen Nähe, hat das meist eine dieser Ursachen:
- Die Ausgangsspannung liegt über dem ADC-Bereich. Das Modul wird mit 5V versorgt, sodass sein A0-Ausgang über die 3,3-V-Grenze des ESP32 ADC steigen kann und der Messwert in die Sättigung geht. Setze einen Spannungsteiler zwischen A0 und den GPIO.
- Der Sensor wärmt sich noch auf, oder ein neuer Sensor wurde noch nicht eingebrannt.
- Ein ADC2-Pin wird verwendet, während WLAN aktiv ist. Verwende einen ADC1-Pin wie GPIO 34.
- Der Sensor wurde in verschmutzter Luft kalibriert, sodass R0 falsch ist. Kalibriere erneut an frischer Luft.
Datenblatt: SNS-MQ135
Verdrahtung

| MCU | A0 Pin | VCC Pin |
|---|---|---|
| ESP32 | 34 (Analog ADC1_CH6) | 5V |
| ESP8266 | A0 | 5V/VIN |
| Pico W | GP26 (ADC0) | 5V |
Hinweis: Auf dem ESP32 ist ADC2 (GPIO04, GPIO02, GPIO15) instabil, wenn WLAN verwendet wird.
Prüfen wir, ob der Sensor richtig verdrahtet ist und funktioniert.
#include <TroykaMQ.h> // https://github.com/amperka/TroykaMQ
#if defined(ESP8266)
#define SENSOR_PIN A0
#elif defined(ESP32)
#define SENSOR_PIN 34
#endif
MQ135 mq135(SENSOR_PIN);
void setup() {
Serial.begin(9600);
// before calibrating the sensor, warm it up for 60 seconds calibrate the sensor in clean air
mq135.calibrate();
// if you know the resistance of the sensor in clean air
// you can specify it manually, eg: 160 mq135.calibrate(160);
Serial.print("Ro = ");
Serial.println(mq135.getRo());
}
void loop() {
// display gas values in ppm
Serial.print(mq135.readCO2());
Serial.println("ppm");
delay(1000);
}
Diesen Code auf GitHub Gist ansehen
Der Serielle Monitor der Arduino IDE zeigt die Messwerte so an:

Schlechte Luftqualität erkennen
#include <TroykaMQ.h> // https://github.com/amperka/TroykaMQ
#if defined(ESP8266)
#define SENSOR_PIN A0
#elif defined(ESP32)
#define SENSOR_PIN 34
#endif
MQ135 mq135(SENSOR_PIN);
const int AQI_THRESHOLD_SEVERE = 700;
const int AQI_THRESHOLD_VERY_POOR = 600;
const int AQI_THRESHOLD_POOR = 500;
const int AQI_THRESHOLD_MODERATE = 400;
int ppm = 0;
void setup() {
Serial.begin(9600);
// before calibrating the sensor, warm it up for 60 seconds calibrate the sensor in clean air
mq135.calibrate();
// if you know the resistance of the sensor in clean air
// you can specify it manually, eg: 160 mq135.calibrate(160);
Serial.print("Ro = ");
Serial.println(mq135.getRo());
}
void loop() {
ppm = mq135.readCO2();
if (ppm > AQI_THRESHOLD_SEVERE) {
Serial.print("Air quality is SEVERE!");
} else if (ppm > AQI_THRESHOLD_VERY_POOR) {
Serial.print("Air quality is VERY POOR!");
} else if (ppm > AQI_THRESHOLD_POOR) {
Serial.print("Air quality is VERY POOR!");
} else if (ppm > AQI_THRESHOLD_MODERATE) {
Serial.print("Air quality is MODERATE");
} else {
Serial.print("Air quality is GOOD");
}
delay(1000);
}
Diesen Code auf GitHub Gist ansehen
Schritt 1 : Mit Sinric Pro verbinden
Schritt 1.1 : Einen eigenen Gerätetyp für den Luftqualitätssensor erstellen.
Sinric Pro hat keinen eingebauten Gerätetyp für einen Luftqualitätssensor mit PPM. Deshalb erstellen wir mit der Funktion Device Template einen eigenen Gerätetyp für den Luftqualitätssensor, der Folgendes abbildet:
-
PPM-Wert
-
Luftqualität ist Severe, Very Poor, Poor, Moderate oder Good.
Hinweis: Mit der weiter unten beschriebenen Importfunktion für Gerätevorlagen kannst du dir das Anlegen der kompletten Vorlage sparen.
-
Melde dich bei deinem Sinric Pro Konto an und gehe zu Device Templates
-
Klicke auf Add Device Template. Gib als Name und Beschreibung Air Quality Sensor ein und wähle als Gerätetyp Air Quality Sensor

- Klicke auf Capabilities.
Hier wählen wir die Funktionen unseres Luftqualitätssensors aus. Wir wollen wissen, ob die Luftqualität Severe, Very Poor, Poor, Moderate oder Good ist. Ziehen wir also je eine Capability Range, Mode und Push Notification hinein.

-
Was ist die Range Capability?
Mit der Range Capability lässt sich eine Zahl darstellen, z. B. die aktuelle Drehzahl eines Mixers.
-
Was ist die Mode Capability?
Mit der Mode Capability lässt sich ein Wert aus einer Liste vordefinierter Werte darstellen, z. B. das aktuelle Waschprogramm einer Waschmaschine.
-
Was ist die Push Notification Capability?
Mit der Notification Capability kannst du aus dem Code heraus eine Push-Benachrichtigung senden.
Klicke auf die Schaltfläche Configure und richte die beiden Capabilities wie unten gezeigt ein.

Klicke zum Speichern auf Save.

Klicke auf Save, um die Vorlage zu speichern.
Jetzt siehst du die Vorlage, die wir gerade erstellt haben.
Eine vorhandene Vorlage importieren?
Wenn du keine Lust hast, alle Mode- und Range-Werte von Hand einzurichten, kannst du die Importfunktion verwenden.

Füge diese Vorlage ein:
{
"name": "Air Quality Sensor",
"description": "Air Quality Sensor",
"deviceTypeId": "5ff0b112994fd31b7d5e8065",
"capabilities": [
{
"id": "5ff0b41b994fd31b7d5e8961",
"mode": {
"instanceId": "modeInstance1",
"locale": "en-US",
"modeName": "Air Quality",
"nonControllable": true,
"modeValues": [
"SEVERE",
"VERY POOR",
"POOR",
"MODERATE",
"GOOD"
]
}
},
{
"id": "5ff0b45f994fd31b7d5e89c2",
"range": {
"instanceId": "rangeInstance1",
"locale": "en-US",
"rangeName": "ppm",
"minimumValue": 1,
"maximumValue": 1024,
"precision": 1,
"unitOfMeasure": "600e7986a7a09c3f3230f8fb",
"presets": [],
"nonControllable": true
}
},
{
"id": "62a707bd9e2f39090569e2d3"
}
]
}
Diesen Code auf GitHub Gist ansehen
-
Melde dich bei deinem Sinric Pro Konto an, öffne links das Menü Devices und klicke auf die Schaltfläche Add Device (oben links).
-
Gib als Gerätenamen Air Quality Sensor und als Beschreibung Air Quality Sensor ein und wähle unter Your Device Templates den Gerätetyp Air Quality Sensor.


-
Klicke auf den Tab Others und dann auf Save
-
Die nächste Seite zeigt die Zugangsdaten, die das eben angelegte Gerät für die Verbindung braucht.

-
Kopiere Device Id, App Key und App Secret. Halte diese Werte geheim. TEILE SIE NICHT IN ÖFFENTLICHEN FOREN !
-
Klicke auf Code Generator, um den Code zu erzeugen. Klicke auf Download, um den Code herunterzuladen.

Schritt 2 : Mit Sinric Pro verbinden
Schritt 2.1 Sinric Pro Bibliothek installieren

Schritt 2.2 TroykaMQ installieren
TroykaMQ ist im Bibliotheksverwalter der Arduino IDE nicht verfügbar. Du musst die Bibliothek daher von https://github.com/amperka/TroykaMQ herunterladen und nach C:\Users\<your username>\Documents\Arduino\libraries kopieren
2.2 Vollständiger Code
AirQualitySensor.h
#ifndef _AIRQUALITYSENSOR_H_
#define _AIRQUALITYSENSOR_H_
#include <SinricProDevice.h>
#include <Capabilities/ModeController.h>
#include <Capabilities/RangeController.h>
#include <Capabilities/PushNotification.h>
class AirQualitySensor
: public SinricProDevice
, public ModeController<AirQualitySensor>
, public RangeController<AirQualitySensor>
, public PushNotification<AirQualitySensor> {
friend class ModeController<AirQualitySensor>;
friend class RangeController<AirQualitySensor>;
friend class PushNotification<AirQualitySensor>;
public:
AirQualitySensor(const String &deviceId) : SinricProDevice(deviceId, "AirQualitySensor") {};
};
#endif
sinricpro-air-quality-sensor.ino
// Uncomment the following line to enable serial debug output
//#define ENABLE_DEBUG
#ifdef ENABLE_DEBUG
#define DEBUG_ESP_PORT Serial
#define NODEBUG_WEBSOCKETS
#define NDEBUG
#endif
#include <Arduino.h>
#ifdef ESP8266
#include <ESP8266WiFi.h>
#endif
#ifdef ESP32
#include <WiFi.h>
#endif
#include <TroykaMQ.h> // https://github.com/amperka/TroykaMQ
#include <SinricPro.h>
#include "AirQualitySensor.h"
#define WIFI_SSID "" // Your WiFI SSID name
#define WIFI_PASS "" // Your WiFi Password.
#define APP_KEY "" // Should look like "de0bxxxx-1x3x-4x3x-ax2x-5dabxxxxxxxx" (Get it from Portal -> Secrets)
#define APP_SECRET "" // Should look like "5f36xxxx-x3x7-4x3x-xexe-e86724a9xxxx-4c4axxxx-3x3x-x5xe-x9x3-333d65xxxxxx" (Get it from Portal -> Secrets)
#define DEVICE_ID "" // Should look like "5dc1564130xxxxxxxxxxxxxx" (Get it from Portal -> Devices)
#define BAUD_RATE 115200 // Change baudrate to your need (used for serial monitor)
#define EVENT_WAIT_TIME 60000 // send event every 60 seconds
#define BAUD_RATE 115200
#define EVENT_WAIT_TIME 60000 // send event every 60 seconds
#if defined(ESP8266)
#define SENSOR_PIN A0
#elif defined(ESP32)
#define SENSOR_PIN 34
#endif
MQ135 mq135(SENSOR_PIN);
const int AQI_THRESHOLD_SEVERE = 700;
const int AQI_THRESHOLD_VERY_POOR = 600;
const int AQI_THRESHOLD_POOR = 500;
const int AQI_THRESHOLD_MODERATE = 400;
int ppm = 0;
int lastPPM = 0;
String lastAirQualityLevelStr = "";
AirQualitySensor &airQualitySensor = SinricPro[DEVICE_ID];
// ModeController
void updateMode(String mode) {
airQualitySensor.sendModeEvent("modeInstance1", mode, "PHYSICAL_INTERACTION");
}
// RangeController
void updateRangeValue(int value) {
airQualitySensor.sendRangeValueEvent("rangeInstance1", value);
}
// PushNotificationController
void sendPushNotification(String notification) {
airQualitySensor.sendPushNotification(notification);
}
/*********
* Setup *
*********/
void setupAirQualitySensor() {
// before calibrating the sensor, warm it up for 60 seconds calibrate the sensor in clean air
mq135.calibrate();
// if you know the resistance of the sensor in clean air
// you can specify it manually, eg: 160 mq135.calibrate(160);
Serial.print("Ro = ");
Serial.println(mq135.getRo());
}
void setupSinricPro() {
SinricPro.onConnected([]{ Serial.printf("[SinricPro]: Connected\r\n"); });
SinricPro.onDisconnected([]{ Serial.printf("[SinricPro]: Disconnected\r\n"); });
SinricPro.begin(APP_KEY, APP_SECRET);
};
void setupWiFi() {
#if defined(ESP8266)
WiFi.setSleepMode(WIFI_NONE_SLEEP);
WiFi.setAutoReconnect(true);
#elif defined(ESP32)
WiFi.setSleep(false);
WiFi.setAutoReconnect(true);
#endif
WiFi.begin(SSID, PASS);
Serial.printf("[WiFi]: Connecting to %s", SSID);
while (WiFi.status() != WL_CONNECTED) {
Serial.printf(".");
delay(250);
}
Serial.printf("connected\r\n");
}
void setup() {
Serial.begin(BAUD_RATE);
setupAirQualitySensor();
setupWiFi();
setupSinricPro();
}
/********
* Loop *
********/
void handleAirQualitySensor() {
if (SinricPro.isConnected() == false) {
return;
}
static unsigned long last_millis;
unsigned long current_millis = millis();
if (last_millis && current_millis - last_millis < EVENT_WAIT_TIME) return;
last_millis = current_millis;
ppm = mq135.readCO2();
Serial.printf("Present ppm: %d\r\n", ppm);
if (ppm == lastPPM) {
Serial.printf("PPM did not changed. do nothing...!\r\n");
return;
}
/* determine air quality level */
String airQualityLevelStr = "";
if (ppm > AQI_THRESHOLD_SEVERE) {
airQualityLevelStr = "SEVERE";
} else if (ppm > AQI_THRESHOLD_VERY_POOR) {
airQualityLevelStr = "VERY POOR";
} else if (ppm > AQI_THRESHOLD_POOR) {
airQualityLevelStr = "POOR";
} else if (ppm > AQI_THRESHOLD_MODERATE) {
airQualityLevelStr = "MODERATE";
} else {
airQualityLevelStr = "GOOD";
}
/* Update air quality level label if changed */
if(lastAirQualityLevelStr != airQualityLevelStr) {
lastAirQualityLevelStr = airQualityLevelStr;
updateMode(lastAirQualityLevelStr);
}
delay(500);
/* update PPM label */
updateRangeValue(ppm);
/* send a push notification when air quality level is bad! */
if (ppm > AQI_THRESHOLD_SEVERE) {
sendPushNotification("Air quality is SEVERE!");
} else if (ppm > AQI_THRESHOLD_VERY_POOR) {
sendPushNotification("Air quality is VERY POOR!");
} else if (ppm > AQI_THRESHOLD_POOR) {
sendPushNotification("Air quality is VERY POOR!");
}
lastPPM = ppm; // save to compare next time.
}
void loop() {
handleAirQualitySensor();
SinricPro.handle();
}
Diesen Code auf GitHub Gist ansehen
Jetzt solltest du den Status der Luftqualität und den ppm-Wert über Alexa und die Sinric Pro App sehen können
Alexa, wie ist die air quality (Name des Modus) von Air Quality Sensor (Gerätename)
Alexa, wie hoch ist ppm (Name des Bereichs) von Air Quality Sensor (Gerätename)


Schritt 3 : Sprachansagen!
✅ So funktioniert es:
1️⃣ Lege in SinricPro einen Switch an (dein geheimer Auslöser!)
2️⃣ Erstelle eine Alexa Routine, die deine Nachricht, z. B. „Die Luftqualität ist schlecht!“, ansagt, wenn der Switch eingeschaltet wird
3️⃣ Sende aus deinem Code ein Power-State-Ereignis, um diesen Switch einzuschalten
void triggerVoiceAnnouncement() {
SinricProSwitch& mySwitch = SinricPro[SWITCH_ID];
mySwitch.sendPowerStateEvent(true);
}
Fehlerbehebung
-
Google Home und SmartThings werden nicht unterstützt.
-
Weitere Details findest du auf unserer Seite Troubleshooting.
Verwandte Tutorials
- ESP32 oder ESP8266 mit Alexa und Google Home steuern
- MQ-3 Alkohol- und Gassensor
- Kapazitiver Bodenfeuchtesensor (HW-390)
- Wasserleck-, Überschwemmungs- und Regensensor
Dieses Dokument ist Open Source. Tippfehler entdeckt? Bitte erstelle ein Issue