Natural Gas leak/Air quality sensor, ESPhome and MQ2 sensor

This a simple gas leak/smoke sensor that will beep an alarm when triggered and send a notification to android based on ESP8266 nodeMCU. The alarm will sound every 2 seconds and its the same tone as microwave oven. I got a speaker from an old motherboard but any small speaker will do. I have one esp8266 in the basement between the furnace and the water heater and one esp8266 in the kitchen above the stove. Natural gas (mostly methane) is less dense than air.



image

I use the kitchen one for other things as well


I dont have a picture with the 3d printed case

esphome:
  name: esphome-web-0cd631
  friendly_name: Furnace gas detector

esp8266:
  board: nodemcuv2

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "xxxxxxxxxxxxxxxxxxxxxxxx"

ota:
  password: "xxxxxxxxxxxxxxxxxxxx"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password
  use_address: 192.168.2.xxx

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Esphome-Web-0Cd631"
    password: "xxxxxxxxxx"

captive_portal:
    
#Define sensors
sensor:
  - platform: adc
    pin: A0
    name: "Smoke sensor"
    id: smk
    update_interval: 1s
    filters:
      - multiply: 100
    unit_of_measurement: "%"
    icon: "mdi:percent"


#Speaker output
output:
  - platform: esp8266_pwm
    pin: D1
    id: buzzer_output

rtttl:
  output: buzzer_output

interval:                                                                               
  - interval: 2s                                                                        
    then:                                                                               
      if:                                                                               
        condition:
          and:
          - switch.is_on: buzzerswitch
          - sensor.in_range:                                                              
             id: smk
             above: 30                                                                   
        then:                                                                           
          - rtttl.play: 'siren:d=16,o=6,b=800:b'

switch:
  - platform: gpio
    pin: D4 #Internal LED switching
    name: "NodeMCU Internal LED"
    id: internal_led
    inverted: true
    restore_mode: ALWAYS_ON

  - platform: gpio
    pin: D2 #choose a free pin here, just to make ESPHome happy. we do not need it for anything
    name: "Buzzer"
    id: buzzerswitch
    restore_mode: ALWAYS_ON
4 Likes

Good project. Thanks for sharing the connections and the code. I am trying to implement similar one for my home as well, waiting for the parts.

Code to test speakers. I activate it once a month.

button:
  - platform: template
    name: Buzzer Test
    id: buzzer_test
    on_press:
      - rtttl.play: 'mario:d=4,o=5,b=100:16e6,16e6,32p,8e6,16c6,8e6,8g6,8p,8g,8p,8c6,16p,8g,16p,8e,16p,8a,8b,16a#,8a,16g.,16e6,16g6,8a6,16f6,8g6,8e6,16c6,16d6,8b,16p,8c6,16p,8g,16p,8e,16p,8a,8b,16a#,8a,16g.,16e6,16g6,8a6,16f6,8g6,8e6,16c6,16d6,8b,8p,16g6,16f#6,16f6,16d#6,16p,16e6,16p,16g#,16a,16c6,16p,16a,16c6,16d6,8p,16g6,16f#6,16f6,16d#6,16p,16e6,16p,16c7,16p,16c7,16c7,p,16g6,16f#6,16f6,16d#6,16p,16e6,16p,16g#,16a,16c6,16p,16a,16c6,16d6,8p,16d#6,8p,16d6,8p,16c6'
1 Like

Awesome info, thanks for sharing. I’m also curious what the adc platform is. Looking into it.

Thanks for the test code. Its really useful.

To save the internal LED being burnt out with extended power on, I have slightly modified the code you have shared as given below. I was testing this with esp32 based board, now I have moved this to d1 mini.

interval:                                                                               
  - interval: 2s                                                                        
    then:                                                                               
      if:                                                                               
        condition:
          and:
          - switch.is_on: buzzerswitch
          - sensor.in_range:                                                              
             id: gassensor
             above: 30                                                                   
        then:                                                                           
          - rtttl.play: 'siren:d=16,o=6,b=800:b'
          - switch.turn_on: internal_led
        else: 
          - switch.turn_off: internal_led 
2 Likes

Unfortunately this does not compile any more.
the first error is:

Then if you comment it out, even if you make sure that the mqunifiedsensor.h dependency is present:

I wrote to ananyevgv Β· GitHub for error of missing library, for your informations.

1 Like

It compiles, with minor adjustments I used MQ2 sensor


esphome:
  name: gas-detector-test
  friendly_name: Gas detector Test

esp8266:
  board: esp01_1m
  framework:
    version: recommended

external_components:
  source: github://ananyevgv/esphome-components
  components: [mq]
  refresh: 0s

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "G09cCeCnuy2Rb+nZkWQ6glKIsCJZca9vSwgj3//ie4g="

ota:
  - platform: esphome
    password: "d968e7f3e21c355805d30913c1b324fd"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Gas-Detector-Test"
    password: "123456789"

captive_portal:
    


sensor:
  - platform: mq
    model: MQ2
    r0: 9.83 # Π½Π΅ ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ, значСния ΠΈΠ· спСцификации вашСго Π΄Π°Ρ‚Ρ‡ΠΈΠΊΠ°) RS/R0 (Чистый Π²ΠΎΠ·Π΄ΡƒΡ…) ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ значСния ΡƒΠΊΠ°Π·Π°Π½Ρ‹Π΅ Π½ΠΈΠΆΠ΅
    rl: 10 # ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ (!!!!!!!! Π½Π° Π΄Π²ΡƒΡ… ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²Ρ‹Ρ… Π΄Π°Ρ‚Ρ‡ΠΈΠΊΠ°Ρ… Π½ΠΎΠΌΠΈΠ½Π°Π»Ρ‹ рСзисторов ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ Ρ€Π°Π·Π½Ρ‹Π΅ 1кОм-120кОм !!!!!!!!),
    # Π½ΠΎΠΌΠΈΠ½Π°Π» R2 (RL) Π² кОм ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ 10 кОм
    vr: 3.3 # МаксимальноС измСряСмоС напряТСниС ESP ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ 3.3Π’ (WEMOS D1 mini)
    # зависит ΠΎΡ‚ настроСк ADC ESPHOME ΠΈ Π½ΠΎΠΌΠΈΠ½Π°Π»ΠΎΠ² рСзисторов дСлитСля смотри https://esphome.io/components/sensor/adc.html
    # ΠΏΡ€ΠΈ ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠΉ схСмС дСлитСля Π½Π° Π²Ρ‹Ρ…ΠΎΠ΄Π΅ Π΄Π°Ρ‚Ρ‡ΠΈΠΊΠ° Vmax 3.3V,
    # vr Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π±Ρ‹Ρ‚ΡŒ Ρ€Π°Π²Π½ΠΎ Vmax
    # vr: 1.1 Vmax 1.1V Π½ΠΎΠΌΠΈΠ½Π°Π» рСзисторов 1.1кОм ΠΈ 3.9 кОм
    # vr: 3.1 Vmax 3.1V Π½ΠΎΠΌΠΈΠ½Π°Π» рСзисторов 3.1кОм ΠΈ 1.9 кОм
   # attenuation: auto # Для ESP32 vr: 3.1 Vmax 3.1V Π½ΠΎΠΌΠΈΠ½Π°Π» рСзисторов 3.1кОм ΠΈ 1.9 кОм
    # ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ 0db 1.1V vr: 1.1 Vmax 1.1V Π½ΠΎΠΌΠΈΠ½Π°Π» рСзисторов 1.1кОм ΠΈ 3.9 кОм
    pin: A0
    update_interval: 2s
    sensor_lpg:
      name: Sensor LPG
    sensor_h2:
      name: Sensor H2
    sensor_co:
      name: Sensor CO
    sensor_propane:
      name: Sensor Propane
    sensor_alcohol:
      name: Sensor Alcohol


  - platform: wifi_signal
    name: Signal
    

button:
  - platform: restart
    name: "Reboot"

text_sensor:
  - platform: version
    name: ESP HOME version   
  - platform: wifi_info
    ssid: 
      name: "SSID"
    ip_address: 
      name: "IP adresa"
    mac_address: 
      name: "MAC"

Another one with MQ135

esphome:
  name: gas-detector-mq135
  friendly_name: Gas detector MQ135

esp8266:
  board: esp01_1m
  framework:
    version: recommended

external_components:
  source: github://ananyevgv/esphome-components
  components: [mq]
  refresh: 0s

# Enable logging
logger:

# Enable Home Assistant API
api:
  encryption:
    key: "QCpD1GRhUUrnCcS48Be7RcHV8rPn8L8+nDdB4lWvrBQ="

ota:
  - platform: esphome
    password: "8fe1eccf44f204a7a77da034f9291f5c"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Gas-Detector-Mq135"
    password: "k9G4mrKRfuGV"

captive_portal:
    

sensor:
  - platform: mq
    model: MQ135
    r0: 3.6 # Π½Π΅ ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ, значСния ΠΈΠ· спСцификации вашСго Π΄Π°Ρ‚Ρ‡ΠΈΠΊΠ°) RS/R0 (Чистый Π²ΠΎΠ·Π΄ΡƒΡ…) ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ значСния ΡƒΠΊΠ°Π·Π°Π½Ρ‹Π΅ Π½ΠΈΠΆΠ΅
    rl: 10 # ΠΎΠ±ΡΠ·Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎ (!!!!!!!! Π½Π° Π΄Π²ΡƒΡ… ΠΎΠ΄ΠΈΠ½Π°ΠΊΠΎΠ²Ρ‹Ρ… Π΄Π°Ρ‚Ρ‡ΠΈΠΊΠ°Ρ… Π½ΠΎΠΌΠΈΠ½Π°Π»Ρ‹ рСзисторов ΠΌΠΎΠ³ΡƒΡ‚ Π±Ρ‹Ρ‚ΡŒ Ρ€Π°Π·Π½Ρ‹Π΅ 1кОм-120кОм !!!!!!!!),
    # Π½ΠΎΠΌΠΈΠ½Π°Π» R2 (RL) Π² кОм ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ 10 кОм
    vr: 3.3 # МаксимальноС измСряСмоС напряТСниС ESP ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ 3.3Π’ (WEMOS D1 mini)
    # зависит ΠΎΡ‚ настроСк ADC ESPHOME ΠΈ Π½ΠΎΠΌΠΈΠ½Π°Π»ΠΎΠ² рСзисторов дСлитСля смотри https://esphome.io/components/sensor/adc.html
    # ΠΏΡ€ΠΈ ΡƒΠΊΠ°Π·Π°Π½Π½ΠΎΠΉ схСмС дСлитСля Π½Π° Π²Ρ‹Ρ…ΠΎΠ΄Π΅ Π΄Π°Ρ‚Ρ‡ΠΈΠΊΠ° Vmax 3.3V,
    # vr Π΄ΠΎΠ»ΠΆΠ½ΠΎ Π±Ρ‹Ρ‚ΡŒ Ρ€Π°Π²Π½ΠΎ Vmax
    # vr: 1.1 Vmax 1.1V Π½ΠΎΠΌΠΈΠ½Π°Π» рСзисторов 1.1кОм ΠΈ 3.9 кОм
    # vr: 3.1 Vmax 3.1V Π½ΠΎΠΌΠΈΠ½Π°Π» рСзисторов 3.1кОм ΠΈ 1.9 кОм
   # attenuation: auto # Для ESP32 vr: 3.1 Vmax 3.1V Π½ΠΎΠΌΠΈΠ½Π°Π» рСзисторов 3.1кОм ΠΈ 1.9 кОм
    # ΠΏΠΎ ΡƒΠΌΠΎΠ»Ρ‡Π°Π½ΠΈΡŽ 0db 1.1V vr: 1.1 Vmax 1.1V Π½ΠΎΠΌΠΈΠ½Π°Π» рСзисторов 1.1кОм ΠΈ 3.9 кОм
    pin: A0
    update_interval: 2s
    sensor_co:
      name: Sensor CO
    sensor_co2:
      name: Sensor CO2
    sensor_nh4:
      name: Sensor NH4
    sensor_tolueno:
      name: Sensor Toluen 
    sensor_alcohol:
      name: Sensor Alcohol
    sensor_acetona:
      name: Sensor Acetone


  - platform: wifi_signal
    name: Gas sensor wifi
    

button:
  - platform: restart
    name: "Reboot"

text_sensor:
  - platform: version
    name: ESP HOME version   
  - platform: wifi_info
    ssid: 
      name: "SSID"
    ip_address: 
      name: "IP adresa"
    mac_address: 
      name: "MAC" 

Δ°t’s true, you’re right, I tested on ESP32-C3 and ESP32-C6, witch uses esp-idf framework like

esp32:
  board: esp32-c6-devkitc-1
  framework:
    type: esp-idf

and NOT ACCEPT arduino framework or version: recommended :frowning: adresses arduiono framework.

But accepts with on ESP32-C3 this settings :

esp32:
  board: esp32-c3-devkitm-1
  framework:
    version: recommended

BUT soon, ESPHome 2026.1.0. will not work !

INFO ESPHome 2025.12.1
INFO Reading configuration /config/esphome/gas-detector-mq2.yaml...
INFO Updating https://github.com/ananyevgv/esphome-components.git@None
WARNING πŸ’‘ IMPORTANT: This device doesn't have a framework specified!

Currently, ESP32C3 defaults to the Arduino framework.
This will change to ESP-IDF in ESPHome 2026.1.0.

Note: Newer ESP32 variants (C6, H2, P4, etc.) already use ESP-IDF by default.

But NOT ACCEPTS with on ESP32-C6, becuse default framework is ESP-IDF :frowning: , maybe Espressif will handle this type of incompatibility.

AND
I add sensor to my esp32 c3, and worked BUT

in yours image 2, ppm values are so small, like mine 0.23 ppm, Earth’s average CO2 ppm values are 450 ppm? Do you know whats is going on ?

Have no clue, to be honest, I haven’t investigated thoroughly. Anyway these sensors are not meant to be precise detectors, I use SCD40 for Co2 detection. In other hand MQ2 reliably detect rise of levels in propane / lpg, and that was my primary use, just to be mounted near tank and monitor levels. No need for precision count of ppm. Just to set alarm if levels rise in certain time frame.

I’ll try to rewrite it on the idf.

1 Like

How does this seperate all the differnt gases from a singular A0 input? is it measuring the slope of A0 change and assigning a gas based on the value?

Also, why the additional 2 resistors? I thought the MQ2 board output is about 0-1V? right?

Thank you so much