Costruisci un sensore di qualità dell'aria con un MQ135 per rilevare fumo e altri gas nocivi con Alexa
In questa sezione ti guideremo nella creazione di un sensore di qualità dell’aria con ESP32 o ESP8266. Potrai poi consultare la qualità dell’aria tramite Amazon Alexa e ricevere una notifica push tramite l’app Sinric Pro quando la qualità dell’aria scende sotto una determinata soglia.
Prerequisiti :
- ESP32, ESP8266 x 1.
- MQ135 x 1.
- Cavetti jumper.

Breve introduzione all’MQ135
L’MQ135 è un sensore di gas a semiconduttore comunemente usato nelle apparecchiature per il controllo della qualità dell’aria. È sensibile a un’ampia gamma di gas, tra cui ammoniaca, solfuri, benzene e fumo. Il sensore ha due uscite: un’uscita digitale che va a livello alto quando la concentrazione di gas supera una certa soglia e un’uscita analogica che fornisce una tensione proporzionale alla concentrazione di gas.
Il sensore MQ135 richiede un’alimentazione a 5V e assorbe circa 150mA di corrente. L’uscita digitale può essere collegata a un ESP32, ESP8266 o Pico W per misurare la concentrazione di gas.
Come calibrare il sensore MQ135
L’MQ135 non fornisce direttamente i ppm. La sua resistenza (Rs) varia con la concentrazione di gas, e il valore in ppm si calcola dal rapporto tra Rs e R0, la resistenza del sensore in aria pulita. R0 è diversa per ogni sensore, quindi ciascuno va calibrato.
1. Burn-in (una sola volta): metti il sensore all’aperto, dove c’è abbastanza aria fresca (idealmente a 20°C e 33% di umidità secondo il datasheet), e lascialo alimentato per 12-24 ore per eseguire il burn-in e stabilizzarlo.
2. Riscaldamento (a ogni accensione): il sensore ha un riscaldatore. Nei primi minuti dopo l’accensione le letture sono troppo alte, quindi aspetta che si stabilizzino prima di usarle.
3. Misura R0 in aria pulita: con il sensore ancora all’aria fresca, lascia che la libreria TroykaMQ usata in questo tutorial calcoli R0 e la stampi:
#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. Riutilizza il valore: annota la R0 stampata e passala a calibrate(). In questo modo il sensore non ha bisogno di aria fresca a ogni riavvio:
mq135.calibrate(YOUR_RO_VALUE);
Temperatura e umidità influenzano la lettura, quindi esegui la calibrazione in condizioni simili a quelle in cui il sensore verrà usato. L’MQ135 va bene per rilevare che la qualità dell’aria è cambiata, ma non è uno strumento di precisione.
Lettura dell’MQ135 bloccata su valori alti (circa da 3800 a 4095)?
Su un ESP32, analogRead() restituisce valori da 0 a 4095. Una lettura che resta al limite superiore di questo intervallo, o lì vicino, di solito ha una di queste cause:
- La tensione di uscita supera l’intervallo dell’ADC. Il modulo è alimentato a 5V, quindi la sua uscita A0 può superare il limite di 3.3 V dell’ADC dell’ESP32 e la lettura va in saturazione. Aggiungi un partitore di tensione tra A0 e il GPIO.
- Il sensore si sta ancora riscaldando, oppure un sensore nuovo non ha ancora fatto il burn-in.
- Viene usato un pin ADC2 mentre il Wi-Fi è attivo. Usa un pin ADC1, ad esempio GPIO 34.
- Il sensore è stato calibrato in aria inquinata, quindi R0 è sbagliata. Ripeti la calibrazione in aria fresca.
Scheda tecnica: SNS-MQ135
Cablaggio

| MCU | Pin A0 | Pin VCC |
|---|---|---|
| ESP32 | 34 (Analogico ADC1_CH6) | 5V |
| ESP8266 | A0 | 5V/VIN |
| Pico W | GP26 (ADC0) | 5V |
Nota: su ESP32, l’ADC2 (GPIO04, GPIO02, GPIO15) è instabile quando il Wi-Fi è in uso.
Verifichiamo che il sensore sia collegato correttamente e funzioni.
#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);
}
Vedi questo codice su GitHub Gist
Il Monitor seriale di Arduino IDE mostrerà le letture in questo modo:

Rilevare una cattiva qualità dell’aria
#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);
}
Vedi questo codice su GitHub Gist
Passo 1 : Collegati a Sinric Pro
Passo 1.1 : Creare un tipo di dispositivo personalizzato per il sensore di qualità dell’aria.
Sinric Pro non ha un tipo di dispositivo integrato per un sensore di qualità dell’aria con PPM, quindi creeremo un tipo di dispositivo personalizzato per il sensore di qualità dell’aria usando la funzione Device Template, per ottenere:
-
Il valore in PPM
-
La qualità dell’aria: Severe, Very Poor, Poor, Moderate o Good.
Nota: puoi usare la funzione di importazione dei device template descritta più sotto per evitare di creare l’intero template.
-
Accedi al tuo account Sinric Pro e vai su Device Templates
-
Fai clic su Add Device Template. Inserisci Air Quality Sensor come nome e descrizione e seleziona Air Quality Sensor come tipo di dispositivo

- Fai clic su Capabilities.
Qui dobbiamo selezionare le funzionalità del nostro sensore di qualità dell’aria. Vogliamo sapere se la qualità dell’aria è Severe, Very Poor, Poor, Moderate o Good. Trasciniamo quindi una capability Range, una Mode e una Push Notification.

-
Che cos’è la capability Range?
La capability Range si può usare per rappresentare un numero. Ad esempio: la velocità attuale di un frullatore.
-
Che cos’è la capability Mode?
La capability Mode si può usare per rappresentare un valore scelto da un elenco di valori predefiniti. Ad esempio: il programma di lavaggio attuale di una lavatrice.
-
Che cos’è la capability Push Notification?
La capability Notification permette di inviare un messaggio di notifica push dal codice.
Fai clic sul pulsante Configure e imposta le due capability come mostrato sotto.

Fai clic su Save per salvare.

Fai clic su Save per salvare il template.
Ora puoi vedere il template che abbiamo appena creato.
Importare un template esistente?
Se non hai voglia di impostare tutti i valori di Mode e Range, puoi usare la funzione di importazione.

Incolla questo template:
{
"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"
}
]
}
Vedi questo codice su GitHub Gist
-
Accedi al tuo account Sinric Pro, vai al menu Devices sulla sinistra e fai clic sul pulsante Add Device (in alto a sinistra).
-
Inserisci il nome del dispositivo Air Quality Sensor, la descrizione Air Quality Sensor e seleziona Air Quality Sensor come tipo di dispositivo da Your Device Templates.


-
Fai clic sulla scheda Others e poi su Save
-
La schermata successiva mostra le credenziali necessarie per collegare il dispositivo che hai appena creato.

-
Copia Device Id, App Key e App Secret Tieni al sicuro questi valori. NON CONDIVIDERLI SUI FORUM PUBBLICI !
-
Fai clic su Code Generator per generare il codice. Fai clic su Download per scaricarlo.

Passo 2 : Collegati a Sinric Pro
Passo 2.1 Installa la libreria Sinric Pro

Passo 2.2 Installa TroykaMQ
TroykaMQ non è disponibile nel Library Manager di Arduino. Devi quindi scaricarla da https://github.com/amperka/TroykaMQ e copiarla in C:\Users\<your username>\Documents\Arduino\libraries
2.2 Codice completo
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();
}
Vedi questo codice su GitHub Gist
Ora dovresti poter vedere lo stato della qualità dell’aria e il valore in ppm tramite Alexa e l’app Sinric Pro
Alexa, qual è la qualità dell’aria (nome della mode) di air quality sensor (nome del dispositivo)
Alexa, quali sono i ppm (nome del range) di air quality sensor (nome del dispositivo)


Passo 3 : Annunci vocali!
✅ Come funziona:
1️⃣ Aggiungi uno Switch in SinricPro (il tuo trigger segreto!)
2️⃣ Crea una routine Alexa che pronunci il tuo messaggio, ad esempio “La qualità dell’aria è pessima!”, quando lo Switch viene acceso
3️⃣ Invia dal tuo codice un evento di stato di accensione per ACCENDERE quello switch
void triggerVoiceAnnouncement() {
SinricProSwitch& mySwitch = SinricPro[SWITCH_ID];
mySwitch.sendPowerStateEvent(true);
}
Risoluzione dei problemi
-
Google Home e SmartThings non sono supportati.
-
Consulta la nostra pagina Troubleshooting per maggiori dettagli.
Tutorial correlati
- Come controllare un ESP32 o ESP8266 con Alexa e Google Home
- Sensore di alcol e gas MQ-3
- Sensore capacitivo di umidità del terreno (HW-390)
- Sensore di perdite d’acqua, allagamento e pioggia
Questo documento è open source. Hai trovato un errore di battitura? Crea una issue