MCU.TEC Sensores Monitoramento de Gases com ESP32 e Sensor MQ-4: Projeto Prático com Cálculos, Códigos e Display OLED

Monitoramento de Gases com ESP32 e Sensor MQ-4: Projeto Prático com Cálculos, Códigos e Display OLED

Fundamentos do Sensor de Gás MQ-4: Funcionamento e Estrutura Elétrica

Sensores de gás da família MQ, como o MQ-4, são amplamente utilizados em aplicações embarcadas para detecção de gases inflamáveis e tóxicos no ambiente. Esses sensores funcionam com base em uma resistência interna sensível à presença de gases, que varia conforme a concentração do composto alvo — neste caso, gases como metano (CH₄), propano (C₃H₈), hidrogênio (H₂), monóxido de carbono (CO) e vapores de álcool. Essa resistência variável é o coração do sensor, responsável por fornecer uma leitura elétrica proporcional à concentração de gás.

O MQ-4 possui um elemento de aquecimento interno e dois conjuntos de terminais: os pares A e B, responsáveis pela medição da resistência sensora (RS), e os pares H, conectados ao aquecedor (heater). O aquecimento é essencial para garantir que a superfície do semicondutor sensível atinja a temperatura correta de operação, geralmente entre 300°C e 400°C, condição necessária para que as reações de oxidação dos gases ocorram de forma eficiente, alterando a condutividade do material sensível (tipicamente dióxido de estanho, SnO₂).

Para realizar a medição de concentração de gás, um resistor de carga externo (denominado RL) é conectado em série com o sensor. A tensão de saída (VRL), medida entre o ponto médio entre RS e RL, varia conforme a proporção da resistência do sensor, permitindo a leitura indireta da concentração de gás. A escolha do valor de RL (típico entre 2kΩ e 47kΩ) influencia a sensibilidade do circuito. Quanto maior RL, maior será a tensão de saída para pequenas variações de RS, o que aumenta a sensibilidade, porém pode comprometer a linearidade em concentrações mais elevadas.

O comportamento da resistência RS em relação à concentração de gás é não linear e geralmente é modelado com gráficos log-log fornecidos em folhas de dados (datasheets). Neles, é comum apresentar a razão RS/R₀, onde R₀ é a resistência medida em ar limpo. Essa razão é usada para estimar a concentração de gás em partes por milhão (ppm), por meio de interpolação logarítmica entre os dados experimentais fornecidos pelo fabricante.

A seguir, nas próximas seções, descreveremos como derivar as fórmulas para calcular RS, como calibrar o sensor e como implementar a leitura e cálculo da concentração usando o ESP32 com o framework ESP-IDF, substituindo o uso do Arduino tradicional.


Derivação Matemática da Resistência do Sensor (RS) e Leitura de Tensão com o ESP32

A resistência RS do sensor de gás MQ-4 representa o ponto central para se calcular a concentração de gás presente no ambiente. Para encontrá-la, partimos de um circuito onde o sensor funciona como um divisor de tensão com um resistor de carga RL. A tensão de alimentação (VC) é aplicada aos terminais e a tensão de saída (VRL) é lida no ponto entre RS e RL.

Sabemos pela Lei de Ohm que: \(V = I \cdot R\)

No circuito da figura abaixo, temos:

Como RS e RL estão em série, a corrente total é dada por: \(I = \frac{V_C}{RS + RL}\)

E a tensão sobre RL (isto é, a tensão de saída lida pelo ADC do ESP32): \[V_{RL} = I \cdot RL = \frac{V_C \cdot RL}{RS + RL}\]

Reorganizando a fórmula para isolar RS: \[RS = \left( \frac{V_C \cdot RL}{V_{RL}} \right) – RL\]

Essa fórmula nos permite calcular RS com base na leitura de tensão obtida pelo conversor analógico-digital (ADC) do ESP32. No ESP-IDF, essa leitura é feita por meio da função adc1_get_raw, que retorna um valor inteiro de 0 a 4095 (resolução de 12 bits por padrão), o qual deve ser convertido para tensão utilizando: VRL=raw⋅Vref4095V_{RL} = \frac{\text{raw} \cdot V_{ref}}{4095}

Onde Vref geralmente é de 3.3V no ESP32, mas pode variar conforme a calibração.

Exemplo em C com ESP-IDF: Leitura e cálculo de RS

#include "driver/adc.h"
#include "esp_log.h"

#define RL_VALUE 10000.0 // 10k Ohms
#define VC       3.3      // Tensão de alimentação do sensor (Vref)
#define TAG "MQ4"

void app_main() {
    adc1_config_width(ADC_WIDTH_BIT_12);                    // Resolução 12 bits
    adc1_config_channel_atten(ADC1_CHANNEL_0, ADC_ATTEN_DB_11); // GPIO36, range até ~3.3V

    while (1) {
        int raw = adc1_get_raw(ADC1_CHANNEL_0); // Leitura ADC
        float vrl = (raw * VC) / 4095.0;         // Conversão para tensão
        float rs = ((VC * RL_VALUE) / vrl) - RL_VALUE;

        ESP_LOGI(TAG, "ADC: %d | VRL: %.2f V | RS: %.2f Ohms", raw, vrl, rs);
        vTaskDelay(pdMS_TO_TICKS(1000));
    }
}

Esse código realiza a leitura do canal ADC1 (GPIO36) e calcula a resistência RS em tempo real, exibindo os valores no terminal. A escolha de RL (10kΩ no exemplo) deve ser mantida constante, pois será necessária na próxima etapa para cálculo de R₀ (calibração em ar limpo) e, posteriormente, da concentração em ppm.


Cálculo de R₀ e Calibração Inicial do Sensor em Ar Limpo

Antes de podermos estimar a concentração de gás no ambiente, é necessário determinar uma referência chamada R₀, que representa a resistência RS medida em ar limpo, isto é, na ausência de gases-alvo como metano, GLP ou CO. Essa resistência é usada como base de comparação para calcular a razão RS/R₀, que por sua vez será aplicada em uma curva de calibração logarítmica, normalmente fornecida pelo fabricante, para determinar a concentração de gás em partes por milhão (ppm).

Segundo o datasheet do sensor MQ-4, a razão típica RS/R₀ em ar limpo é de 4.4, o que significa que: R0=RSair4.4R₀ = \frac{RS_{air}}{4.4}

O processo de calibração consiste em realizar múltiplas leituras da resistência RS enquanto o sensor estiver exposto ao ar ambiente por vários minutos, até que sua resposta estabilize. Essa resistência é então usada para calcular o valor de R₀.

Código de Calibração em C para ESP-IDF

#include "driver/adc.h"
#include "esp_log.h"

#define RL_VALUE 10000.0 // Resistor de carga em ohms
#define VC       3.3     // Tensão de alimentação do sensor
#define AIR_RS_RO_RATIO 4.4 // Valor típico RS/R0 em ar limpo

#define TAG "CALIBRACAO"

void app_main() {
    adc1_config_width(ADC_WIDTH_BIT_12);
    adc1_config_channel_atten(ADC1_CHANNEL_0, ADC_ATTEN_DB_11);

    float rs_total = 0;
    int samples = 500;

    for (int i = 0; i < samples; i++) {
        int raw = adc1_get_raw(ADC1_CHANNEL_0);
        float vrl = (raw * VC) / 4095.0;
        float rs = ((VC * RL_VALUE) / vrl) - RL_VALUE;
        rs_total += rs;
        vTaskDelay(pdMS_TO_TICKS(10));
    }

    float rs_avg = rs_total / samples;
    float r0 = rs_avg / AIR_RS_RO_RATIO;

    ESP_LOGI(TAG, "RS médio em ar limpo: %.2f Ohms", rs_avg);
    ESP_LOGI(TAG, "R0 estimado: %.2f Ohms", r0);
}

Neste exemplo, o sistema coleta 500 amostras da resistência RS, espaçadas em 10 milissegundos, calcula a média e então aplica a fórmula para obter R₀. Esse valor será utilizado posteriormente para determinar a concentração de gás a partir da razão RS/R₀.

⚠️ Importante: Durante o processo de calibração, o ambiente deve estar livre de gases como metano, propano ou vapores de álcool. Isso assegura que o valor de R₀ represente corretamente a condição de referência do sensor.

Após essa etapa, recomenda-se salvar R₀ em memória flash ou EEPROM, caso seu projeto requeira desligamento/reinicialização frequente, evitando nova calibração sempre que o sistema for energizado.

Ótimo! Agora que já temos o valor de referência R₀, podemos prosseguir com o cálculo da concentração de gás em ppm a partir da razão RS/R₀, utilizando a equação logarítmica derivada da curva de sensibilidade do sensor MQ-4.


Seção 4 – Cálculo da Concentração de Gás (ppm) com Base em Curva Logarítmica

O comportamento da resistência do sensor em função da concentração de gás não é linear. Por isso, os fabricantes fornecem curvas de calibração em escalas logarítmicas (log-log), nas quais a relação entre a razão RS/R₀ e a concentração em ppm segue uma equação da forma: log⁡10(y)=m⋅log⁡10(x)+b\log_{10}(y) = m \cdot \log_{10}(x) + b

Onde:

  • y=RS/R0y = RS/R_0 (razão de resistência),
  • xx é a concentração de gás em ppm,
  • mm é a inclinação (slope),
  • bb é o coeficiente linear (intercepto).

Derivando a concentração de gás (x):

Isolando xx: log⁡10(x)=log⁡10(y)−bm\log_{10}(x) = \frac{\log_{10}(y) – b}{m}

E então: x=10(log⁡10(y)−bm)x = 10^{\left(\frac{\log_{10}(y) – b}{m}\right)}

No caso do MQ-4, baseado em um exemplo extraído da curva para GLP (propano), foram utilizados os seguintes pontos para cálculo:

  • Ponto 1: (200 ppm, 2.6 RS/R₀)
  • Ponto 2: (10.000 ppm, 0.75 RS/R₀)

O cálculo da inclinação é feito por: m=log⁡10(0.75/2.6)log⁡10(10000/200)≈−0.318m = \frac{\log_{10}(0.75 / 2.6)}{\log_{10}(10000 / 200)} \approx -0.318

E o intercepto usando o ponto (5000 ppm, 0.9 RS/R₀): \[b = \log_{10}(0.9) – m \cdot \log_{10}(5000) \approx 1.133\]

Portanto, temos a equação para concentração de gás: \[ppm = 10^{\left(\frac{\log_{10}(RS/R_0) – 1.133}{-0.318}\right)}\]

Exemplo de Código ESP-IDF para Cálculo de ppm

#include <math.h>
#include "driver/adc.h"
#include "esp_log.h"

#define RL_VALUE 10000.0
#define VC 3.3
#define R0 11.82 // Valor obtido da calibração anterior

#define SLOPE     -0.318
#define INTERCEPT  1.133

#define TAG "MQ4_PPM"

void app_main() {
    adc1_config_width(ADC_WIDTH_BIT_12);
    adc1_config_channel_atten(ADC1_CHANNEL_0, ADC_ATTEN_DB_11);

    while (1) {
        int raw = adc1_get_raw(ADC1_CHANNEL_0);
        float vrl = (raw * VC) / 4095.0;
        float rs = ((VC * RL_VALUE) / vrl) - RL_VALUE;

        float ratio = rs / R0;
        float ppm_log = (log10f(ratio) - INTERCEPT) / SLOPE;
        float ppm = powf(10, ppm_log);

        ESP_LOGI(TAG, "RS: %.2f Ω | RS/R0: %.2f | ppm: %.2f", rs, ratio, ppm);
        vTaskDelay(pdMS_TO_TICKS(2000));
    }
}

Esse código realiza o cálculo em tempo real da concentração de gás em ppm, aplicando diretamente a fórmula logarítmica ajustada com os coeficientes da curva de sensibilidade. Note que o valor de R₀ deve ser previamente calibrado como mostrado na seção anterior.

💡 Dica prática: os sensores MQ precisam de um tempo de “aquecimento” (burn-in) de alguns minutos após energização para fornecer leituras estáveis.

Projeto Prático com ESP32: Alerta Visual e Exibição em Display OLED

Com os valores de RS, R₀ e a curva logarítmica corretamente implementados, podemos agora desenvolver um sistema embarcado funcional capaz de exibir, em tempo real, a concentração de gás detectada e emitir alertas visuais e sonoros quando os níveis ultrapassarem um limiar de segurança.

Este projeto utiliza os seguintes componentes:

  • ESP32 DevKit
  • Sensor de gás MQ-4
  • Display OLED 0.96” (I2C, SSD1306)
  • LED vermelho (alerta visual)
  • Buzzer piezoelétrico (alerta sonoro)
  • Resistores: 10kΩ (RL), 330Ω (LED)
  • Protoboard e jumpers

Esquema de ligação

  • MQ-4:
    • A → VCC (3V3)
    • B → GPIO36 (ADC1_CHANNEL_0)
    • H → VCC e GND (alimentação do aquecedor)
    • RL entre GPIO36 e GND
  • Display OLED (SSD1306, I2C):
    • SDA → GPIO21
    • SCL → GPIO22
    • VCC → 3V3
    • GND → GND
  • LED:
    • Anodo → GPIO25
    • Catodo → resistor de 330Ω → GND
  • Buzzer:
    • Positivo → GPIO26
    • Negativo → GND

Código completo com alertas e display

#include <math.h>
#include "driver/adc.h"
#include "driver/gpio.h"
#include "esp_log.h"
#include "ssd1306.h" // biblioteca externa para OLED I2C

#define RL_VALUE 10000.0
#define VC 3.3
#define R0 11.82

#define SLOPE     -0.318
#define INTERCEPT  1.133

#define ALERT_THRESHOLD_PPM 2000

#define TAG "MQ4_APP"

// Pinos
#define PIN_ADC     ADC1_CHANNEL_0  // GPIO36
#define PIN_LED     GPIO_NUM_25
#define PIN_BUZZER  GPIO_NUM_26
#define I2C_SDA     GPIO_NUM_21
#define I2C_SCL     GPIO_NUM_22

void app_main() {
    // Inicializa ADC
    adc1_config_width(ADC_WIDTH_BIT_12);
    adc1_config_channel_atten(PIN_ADC, ADC_ATTEN_DB_11);

    // Inicializa GPIOs
    gpio_set_direction(PIN_LED, GPIO_MODE_OUTPUT);
    gpio_set_direction(PIN_BUZZER, GPIO_MODE_OUTPUT);

    // Inicializa OLED
    ssd1306_init(I2C_NUM_0, I2C_SDA, I2C_SCL);
    ssd1306_clear_screen();
    ssd1306_contrast(0xFF);

    while (1) {
        int raw = adc1_get_raw(PIN_ADC);
        float vrl = (raw * VC) / 4095.0;
        float rs = ((VC * RL_VALUE) / vrl) - RL_VALUE;

        float ratio = rs / R0;
        float ppm_log = (log10f(ratio) - INTERCEPT) / SLOPE;
        float ppm = powf(10, ppm_log);
        float pct = ppm / 10000.0 * 100;

        // Exibe no OLED
        ssd1306_clear_screen();
        char buffer[32];
        snprintf(buffer, sizeof(buffer), "Gas: %.0f ppm", ppm);
        ssd1306_display_text(buffer, 0, 0);
        snprintf(buffer, sizeof(buffer), "%.1f%%", pct);
        ssd1306_display_text(buffer, 0, 2);

        // Alertas
        if (ppm > ALERT_THRESHOLD_PPM) {
            gpio_set_level(PIN_LED, 1);
            gpio_set_level(PIN_BUZZER, 1);
        } else {
            gpio_set_level(PIN_LED, 0);
            gpio_set_level(PIN_BUZZER, 0);
        }

        ESP_LOGI(TAG, "RS=%.2f Ω | Ratio=%.2f | ppm=%.1f", rs, ratio, ppm);
        vTaskDelay(pdMS_TO_TICKS(2000));
    }
}

🛠️ Observação: Para compilar este projeto, será necessário integrar uma biblioteca SSD1306 compatível com o ESP-IDF. Sugiro utilizar uma baseada em I2C, como esp-idf-ssd1306 ou adaptar conforme necessário.

Esse projeto cria uma estação de monitoramento de gás que:

  • Calcula a concentração de gás a cada 2 segundos,
  • Exibe a leitura no display OLED,
  • Dispara um alerta visual (LED) e sonoro (buzzer) se o valor ultrapassar 2000 ppm.

Esse tipo de aplicação pode ser adaptado para uso residencial, industrial, ou em sistemas embarcados conectados à nuvem (via MQTT, por exemplo).

Considerações Finais, Limitações do Sensor MQ-4 e Integração com IoT

Embora os sensores da família MQ, como o MQ-4, sejam acessíveis e fáceis de integrar com microcontroladores como o ESP32, é importante compreender suas limitações e características técnicas para não comprometer a confiabilidade do projeto.

Sensibilidade e Ruído

Sensores MQ operam com um aquecedor interno e possuem tempo de estabilização prolongado — podem levar entre 3 a 5 minutos para fornecer leituras confiáveis após energização. Além disso, são sensíveis a umidade, temperatura ambiente e gases interferentes, o que pode afetar significativamente os resultados.

Como utilizam um princípio de detecção baseado em variação de condutividade, são fortemente influenciados por ruído elétrico e flutuações de tensão de alimentação. Portanto, recomenda-se:

  • Usar reguladores de tensão dedicados de 5V ou 3.3V com baixo ripple;
  • Realizar média de múltiplas amostras (como mostrado nas seções anteriores);
  • Implementar calibração periódica, especialmente em ambientes expostos a variações de gases não monitorados.

Faixa de Medição e Curvas Logarítmicas

A faixa útil do MQ-4 para detecção de gás metano, por exemplo, varia entre 200 ppm e 10.000 ppm. Fora dessa faixa, a curva log-log se torna extrapolada, podendo gerar leituras distorcidas. Para aplicações críticas (como detecção de vazamentos em indústrias ou motores a gás), recomenda-se o uso de sensores com saída linear calibrada ou sensores de referência certificados, como:

  • NDIR (Infravermelho não dispersivo)
  • MOS (Metal-Oxide Semiconductor de precisão)
  • sensores eletroquímicos

Integração com IoT e Expansão do Projeto

Graças à capacidade do ESP32 de operar com Wi-Fi e Bluetooth, esse projeto pode ser facilmente expandido para aplicações de monitoramento remoto e alerta em tempo real, utilizando protocolos como:

  • MQTT para envio de dados a um broker (como Mosquitto, HiveMQ ou AWS IoT);
  • HTTP/REST para integração com dashboards web;
  • Bluetooth LE (BLE) para comunicação local com apps mobile.

Além disso, é possível:

  • Armazenar leituras em cartão SD ou SPIFFS;
  • Registrar eventos críticos (como detecção acima do limiar) com timestamp e localização GPS;
  • Enviar notificações por Telegram, e-mail ou WhatsApp em tempo real.

Essas possibilidades tornam o sistema ideal para aplicações de monitoramento ambiental, automação residencial, sistemas de segurança, cidades inteligentes, usinas de biogás, e muito mais.

5 1 voto
Classificação do artigo
Inscrever-se
Notificar de
guest
0 Comentários
mais antigos
mais recentes Mais votado
Feedbacks embutidos
Ver todos os comentários

Related Post

Sensores de gases da série A2 da Alphasense: uma introdução aos riscos ambientais e à saúde humanaSensores de gases da série A2 da Alphasense: uma introdução aos riscos ambientais e à saúde humana

Aprenda como integrar sensores eletroquímicos da série A2 da Alphasense com o microcontrolador ESP32 utilizando o front-end analógico LMP91000. Um guia didático com exemplos de código, riscos ambientais dos gases

0
Adoraria saber sua opinião, comente.x