Construa um Sensor de Qualidade do Ar com Sensor MQ135 para detectar fumaça e outros gases nocivos para Alexa

Nesta seção, vamos orientá-lo na criação de um sensor de qualidade do ar usando ESP32 ou ESP8266. Você então poderá visualizar a qualidade do ar via Amazon Alexa e receber uma notificação push via aplicativo Sinric Pro quando a qualidade do ar ficar abaixo de um certo nível limite.

Pré-requisitos:

  1. ESP32, ESP8266 x 1.
  2. MQ135 x 1.
  3. Cabos Jumper.

Sinric Pro MQ135 air quality

Introdução rápida ao MQ135

O MQ135 é um sensor de gás semicondutor que é comumente usado em equipamentos de controle de qualidade do ar. É sensível a uma ampla gama de gases, incluindo amônia, sulfeto, benzeno e fumaça. O sensor tem duas saídas: uma saída digital que fica alta quando a concentração de gás excede um certo limite, e uma saída analógica que fornece uma tensão proporcional à concentração de gás.

O sensor MQ135 requer uma fonte de alimentação de 5V e consome cerca de 150mA de corrente. A saída digital pode ser conectada a um ESP32, ESP8266 ou Pico W para medir a concentração de gás.

Como calibrar o sensor? Coloque seu sensor do lado de fora onde há ar fresco suficiente (idealmente a 20°C e 33% de umidade de acordo com a folha de dados) e deixe-o ligado por 12-24 horas para queimá-lo e estabilizar.

Folha de especificação: SNS-MQ135

Como calibrar o sensor MQ135 passo a passo

O MQ135 não fornece ppm diretamente. A resistência dele (Rs) muda com a concentração de gás, e o valor em ppm é calculado pela razão entre Rs e R0, a resistência do sensor em ar limpo. O R0 é diferente em cada sensor, então cada um precisa ser calibrado.

1. Burn-in (uma vez): deixe o sensor ligado por 12 a 24 horas em ar fresco para estabilizar.

2. Aquecimento (a cada vez que ligar): o sensor tem um aquecedor. As leituras ficam altas demais nos primeiros minutos após ligar, então espere estabilizarem antes de usá-las.

3. Meça o R0 em ar limpo: com o sensor ainda em ar fresco, deixe a biblioteca TroykaMQ usada neste tutorial calcular o R0 e imprimi-lo:

#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. Reutilize o valor: anote o R0 impresso e passe-o para calibrate(). Assim o sensor não precisa de ar fresco toda vez que reinicia:

mq135.calibrate(YOUR_RO_VALUE);

Temperatura e umidade alteram a leitura, então calibre em condições próximas às do local de uso. O MQ135 é bom para detectar que a qualidade do ar mudou, mas não é um instrumento de precisão.

Leitura do MQ135 travada em valor alto (entre 3800 e 4095)?

No ESP32, analogRead() retorna de 0 a 4095. Uma leitura que fica no topo dessa faixa geralmente tem uma destas causas:

Fiação

Sinric Pro ESP32 ESP8266 MQ135 air quality sensor wiring diagram

MCU Pino A0 Pino VCC
ESP32 34 (Analog ADC1_CH6) 5V
ESP8266 A0 5V/VIN
Pico W GP26 (ADC0) 5V

Nota: no ESP32, ADC2 (GPIO04, GPIO02, GPIO15) é instável quando Wi-Fi está sendo usado.

Vamos verificar se o sensor de movimento está conectado corretamente e funcionando.

#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);
}

View this code on GitHub Gist

O Monitor Serial do Arduino IDE mostrará as detecções de movimento assim:

Sinric Pro mq135 test reading

Detectando Qualidade do Ar Ruim

#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);
}

View this code on GitHub Gist

Passo 1: Conectar ao Sinric Pro

Passo 1.1: Criando um tipo de dispositivo personalizado para Sensor de Qualidade do Ar.

Sinric Pro não tem um tipo de dispositivo integrado para Sensor de Qualidade do Ar com PPM, então vamos criar um tipo de dispositivo personalizado para Sensor de Água usando o recurso Device Template para conseguir.

  1. Valor PPM

  2. Qualidade do Ar é Severa, Muito Ruim, Ruim, Moderada ou Boa.

Nota: Você pode usar o recurso de importação de template de dispositivo mencionado abaixo para pular a criação do template completo.

Sinric Pro air quality ensor device template

Aqui devemos selecionar as características do nosso Sensor de Qualidade do Ar. Queremos saber se a Qualidade do Ar é Severa, Muito Ruim, Ruim, Moderada ou Boa. Então vamos arrastar uma capacidade Range, Mode e Push Notification.

Sinric Pro custom device type for MQ135 air quality sensor with range and mode capabilities

Clique no botão Configure e configure as duas capacidades como abaixo.

Sinric Pro moisture sensor template mode and range settings

Clique em Save para salvar.

Sinric Pro moisture sensor template mode and range settings

Clique em Save para salvar o template.

Agora você pode ver o template que acabamos de criar.

Importar um template existente?

Se você está com preguiça de configurar todos os Modos e valores Range, você pode usar o recurso de importação.

Sinric Pro capacitive soil moisture sensor import template

Cole este 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"
    }
  ]
}

View this code on GitHub Gist

Sinric Pro create device alexa

Sinric Pro create device alexa

Sinric Pro copy device id

Sinric Pro copy device id

Passo 2: Conectar ao Sinric Pro

Passo 2.1 Instalar a Biblioteca Sinric Pro

Sinric Pro install SinricPro library

Passo 2.2 Instalar TroykaMQ

TroykaMQ não está disponível no Arduino Library Manager. Então você deve baixá-lo de https://github.com/amperka/TroykaMQ e copiá-lo para C:\Users\<seu nome de usuário>\Documents\Arduino\libraries

2.2 Código 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();
}

View this code on GitHub Gist

Agora você deve conseguir ver o status de inundação e nível de água via Alexa, App Sinric Pro

Alexa, Qual é a qualidade do ar (nome do modo) no sensor de qualidade do ar(nome do dispositivo)

Alexa, Qual é o ppm (nome do range) no sensor de qualidade do ar(nome do dispositivo)

Sinric Pro MQ135 air quality sensor in the Alexa app

Sinric Pro MQ135 air quality sensor in the Portal

Solução de Problemas

  1. Google Home ou SmartThings não são suportados.

  2. Consulte nossa página de Solução de Problemas para mais detalhes.

Este documento é código aberto. Viu um erro de digitação? Por favor, crie uma issue