{"id":1819,"date":"2025-09-18T14:03:35","date_gmt":"2025-09-18T08:33:35","guid":{"rendered":"https:\/\/vihaaniotgateway.in\/?p=1819"},"modified":"2025-10-14T15:40:44","modified_gmt":"2025-10-14T10:10:44","slug":"how-to-detect-gas-with-esp32-and-mq-2-sensor-and-send-real-time-mobile-alerts","status":"publish","type":"post","link":"https:\/\/vihaaniotgateway.in\/index.php\/2025\/09\/18\/how-to-detect-gas-with-esp32-and-mq-2-sensor-and-send-real-time-mobile-alerts\/","title":{"rendered":"How to Detect Gas with ESP32 and MQ-2 Sensor and Send Real-Time Mobile Alerts"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\">Introduction:<\/h2>\n\n\n\n<p>In our previous blog, we demonstrated how to set up an <strong>AWS IoT Core account<\/strong> and control a <strong>relay<\/strong> using an <strong>ESP32<\/strong>. That project was a great starting point for cloud-connected home automation.<\/p>\n\n\n\n<p>In this tutorial, we will take it a step further by integrating an <strong>MQ-2 gas sensor<\/strong> with the ESP32 to detect harmful gases like <strong>LPG, methane, and smoke<\/strong>. The ESP32 will send these readings to <strong>AWS IoT Core<\/strong>, and our <strong>custom mobile application<\/strong> will provide <strong>real-time alerts<\/strong>, ensuring you are immediately notified of any potential hazards.<\/p>\n\n\n\n<p>By the end of this blog, you\u2019ll have a working system that not only automates devices but also <strong>enhances home safety with instant mobile notifications<\/strong>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\">About MQ-2 Sensor:<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">What gases it detects:<\/h3>\n\n\n\n<p>The <strong>MQ-2 gas sensor<\/strong> is a low-cost and easy-to-use sensor that can detect a variety of gases commonly found in homes and workplaces. It is widely used for <strong>home safety and DIY IoT projects<\/strong>.<\/p>\n\n\n\n<p>What Gases the MQ-2 Sensor Can Detect:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>LPG (Liquefied Petroleum Gas)<\/strong> \u2013 commonly used for cooking<\/li>\n\n\n\n<li><strong>Methane (CH\u2084)<\/strong> \u2013 found in natural gas and biogas<\/li>\n\n\n\n<li><strong>Butane (C\u2084H\u2081\u2080)<\/strong> \u2013 another fuel gas often found in lighters<\/li>\n\n\n\n<li><strong>Smoke<\/strong> \u2013 from combustion or fire sources<\/li>\n\n\n\n<li><strong>Hydrogen (H\u2082)<\/strong> \u2013 produced in some industrial processes<\/li>\n\n\n\n<li><strong>Alcohol vapors<\/strong> \u2013 volatile organic compounds<\/li>\n\n\n\n<li><strong>Propane (C\u2083H\u2088)<\/strong> \u2013 used in some household fuel systems<\/li>\n<\/ul>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" width=\"1024\" height=\"628\" src=\"https:\/\/vihaaniotgateway.in\/wordpress\/wp-content\/uploads\/2025\/09\/mq2-sensitivity-characterstics-1024x628.jpg\" alt=\"\" class=\"wp-image-1821\" srcset=\"https:\/\/vihaaniotgateway.in\/wordpress\/wp-content\/uploads\/2025\/09\/mq2-sensitivity-characterstics-1024x628.jpg 1024w, https:\/\/vihaaniotgateway.in\/wordpress\/wp-content\/uploads\/2025\/09\/mq2-sensitivity-characterstics-300x184.jpg 300w, https:\/\/vihaaniotgateway.in\/wordpress\/wp-content\/uploads\/2025\/09\/mq2-sensitivity-characterstics-768x471.jpg 768w, https:\/\/vihaaniotgateway.in\/wordpress\/wp-content\/uploads\/2025\/09\/mq2-sensitivity-characterstics-600x368.jpg 600w, https:\/\/vihaaniotgateway.in\/wordpress\/wp-content\/uploads\/2025\/09\/mq2-sensitivity-characterstics.jpg 1096w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" width=\"1024\" height=\"312\" src=\"https:\/\/vihaaniotgateway.in\/wordpress\/wp-content\/uploads\/2025\/09\/mq2-temperature-humidity-dependence-1024x312.jpg\" alt=\"\" class=\"wp-image-1822\" srcset=\"https:\/\/vihaaniotgateway.in\/wordpress\/wp-content\/uploads\/2025\/09\/mq2-temperature-humidity-dependence-1024x312.jpg 1024w, https:\/\/vihaaniotgateway.in\/wordpress\/wp-content\/uploads\/2025\/09\/mq2-temperature-humidity-dependence-300x91.jpg 300w, https:\/\/vihaaniotgateway.in\/wordpress\/wp-content\/uploads\/2025\/09\/mq2-temperature-humidity-dependence-768x234.jpg 768w, https:\/\/vihaaniotgateway.in\/wordpress\/wp-content\/uploads\/2025\/09\/mq2-temperature-humidity-dependence-600x183.jpg 600w, https:\/\/vihaaniotgateway.in\/wordpress\/wp-content\/uploads\/2025\/09\/mq2-temperature-humidity-dependence.jpg 1048w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p><strong>\u26a0\ufe0f Note:<\/strong><br>The MQ-2 sensor <strong>detects the presence of combustible gases<\/strong> like LPG, methane, smoke, and alcohol vapors, <strong>but it cannot tell which gas it is<\/strong>. It only gives a voltage output proportional to the overall gas concentration in the air. Perfect for DIY projects and experimentation, but not for precise gas identification.<\/p>\n<\/blockquote>\n\n\n\n<h2 class=\"wp-block-heading\">Hardware Requirements:<\/h2>\n\n\n\n<p>o build this project, you will need the following components:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><thead><tr><th>Component<\/th><th>Purpose<\/th><\/tr><\/thead><tbody><tr><td><strong>ESP32 Development Board<\/strong><\/td><td>Acts as the main controller and connects to AWS IoT Core<\/td><\/tr><tr><td><strong>MQ-2 Gas Sensor Module<\/strong><\/td><td>Detects gases like LPG, methane, and smoke<\/td><\/tr><tr><td><strong>Relay Module<\/strong><\/td><td>Used to control appliances remotely via AWS IoT<\/td><\/tr><tr><td><strong>Jumper Wires<\/strong><\/td><td>For making connections between ESP32, sensor, and relay<\/td><\/tr><tr><td><strong>Power Supply<\/strong><\/td><td>5V for MQ-2 and relay, 3.3V logic for ESP32<\/td><\/tr><tr><td><strong>Breadboard (optional)<\/strong><\/td><td>For easy prototyping without soldering<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Circuit Connections:<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">MQ-2 Gas Sensor \u2192 ESP32<\/h3>\n\n\n\n<h3 class=\"wp-block-heading\"><strong>\ud83d\udccc Safety Note for MQ\u20112 Gas Sensor<\/strong><\/h3>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>In many hobby projects, the MQ\u20112 gas sensor is connected directly to the ESP32 analog input pin for simplicity.<br>While this works in many cases, it is <strong>not technically safe long-term<\/strong> because the MQ\u20112 outputs up to <strong>5V analog signals<\/strong>, and ESP32 ADC pins are designed for <strong>maximum 3.3V input<\/strong>.<br>Direct connection can lead to:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Gradual damage to ESP32 input pins.<\/li>\n\n\n\n<li>Inaccurate sensor readings.<\/li>\n\n\n\n<li>Reduced reliability over time.<\/li>\n<\/ul>\n\n\n\n<p>\u2705 <strong>Recommended:<\/strong> Use a simple voltage divider or logic level shifter to scale the MQ\u20112 analog output down to safe levels for the ESP32.<\/p>\n<\/blockquote>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>VCC \u2192 5V<\/strong> (power for heating element)<\/li>\n\n\n\n<li><strong>GND \u2192 GND<\/strong><\/li>\n\n\n\n<li><strong>A0 \u2192 GPIO34<\/strong> (analog input for reading gas level, use a 5v to 3.3 level shifter)<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Relay Module \u2192 ESP32 (from previous blog)<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>VCC \u2192 5V<\/strong><\/li>\n\n\n\n<li><strong>GND \u2192 GND<\/strong><\/li>\n\n\n\n<li><strong>IN \u2192 GPIOXX<\/strong> (same GPIO as used previously for relay control)<\/li>\n<\/ul>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p><strong>Tip:<\/strong> Keep the MQ-2 sensor powered for a few minutes before taking readings to allow it to warm up for accurate measurements.<\/p>\n<\/blockquote>\n\n\n\n<h2 class=\"wp-block-heading\">Firmware Logic:<\/h2>\n\n\n\n<p>We take the <strong>average of 50 ADC samples<\/strong> from the MQ-2 sensor to ensure stable and reliable readings. This averaged sensor data is then published to <strong>AWS IoT Core<\/strong> on the topic:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$aws\/things\/esp32\/sensor\/mq2sensor\n<\/code><\/pre>\n\n\n\n<p>Alongside this, light control messages are also published to:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>$aws\/things\/esp32\/devices\/light\n<\/code><\/pre>\n\n\n\n<p>For details on how to configure <strong>AWS IoT Core<\/strong> and set up publishing and subscribing to topics, please refer to our <strong>previous article<\/strong>.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>#include &lt;WiFi.h>\n#include &lt;WiFiClientSecure.h>\n#include &lt;PubSubClient.h>\n#include &lt;ArduinoJson.h>\n\n#define MQ2_PIN 34  \/\/ ADC pin\n#define LIGHT 13\n\n\/\/ -------- WiFi ----------\nconst char* WIFI_SSID = \"CHANGE_ME\";\nconst char* WIFI_PASSWORD = \"CHANGE_ME\";\n\n\/\/ -------- AWS IoT ----------\nconst char* AWS_IOT_ENDPOINT = \"CHANGE_ME\";  \/\/ your AWS IoT Core endpoint\nconst int AWS_IOT_PORT = 8883;\n\n\/\/ Certificates (download from AWS IoT Core)\nconst char* AWS_CERT_CA = R\"EOF(\n-----BEGIN CERTIFICATE-----\nReplace with your CA content\n-----END CERTIFICATE-----\n)EOF\";\n\nconst char* AWS_CERT_CRT = R\"EOF(\n-----BEGIN CERTIFICATE-----\nReplace with your Certificate content\n-----END CERTIFICATE-----\n)EOF\";\n\nconst char* AWS_CERT_PRIVATE = R\"EOF(\n-----BEGIN RSA PRIVATE KEY-----\nReplace with your Private Key\n-----END RSA PRIVATE KEY-----\n)EOF\";\n\n\/\/ -------- Global Variables ----------\nWiFiClientSecure net;\nPubSubClient client(net);\nint mq2Threshold = 200;\n\n\/\/ -------- Functions ----------\n\n\/\/ Read MQ2 sensor with averaging\nint getMQ2Reading(int samples = 50) {\n    long sum = 0;\n    for (int i = 0; i &lt; samples; i++) {\n        sum += analogRead(MQ2_PIN);\n        delay(2);\n    }\n    return sum \/ samples;\n}\n\n\/\/ Handle incoming JSON threshold update\nvoid handleThresholdMessage(char* message) {\n    StaticJsonDocument&lt;200> doc;\n    DeserializationError error = deserializeJson(doc, message);\n\n    if (error) {\n        Serial.print(\"JSON parse failed: \");\n        Serial.println(error.f_str());\n        return;\n    }\n\n    if (doc.containsKey(\"threshold\")) {\n        mq2Threshold = doc&#91;\"threshold\"];\n        Serial.print(\"Threshold updated: \");\n        Serial.println(mq2Threshold);\n    }\n}\n\n\/\/ Publish JSON payload to MQTT\nvoid publishMessage(const char* topic, const String&amp; payload) {\n    client.publish(topic, payload.c_str());\n    Serial.printf(\"Published &#91; %s ] %s\\n\", topic, payload.c_str());\n}\n\n\/\/ Handle device commands from MQTT\nvoid handle_mqtt_msg(char* topic, byte* payload, unsigned int length) {\n    if (strstr(topic, \"$aws\/things\/esp32\/devices\/light\")) {\n        if (strstr((const char*)payload, \"light-on\")) {\n            digitalWrite(LIGHT, LOW);\n            Serial.println(\"LIGHT ON\");\n        } else if (strstr((const char*)payload, \"light-off\")) {\n            digitalWrite(LIGHT, HIGH);\n            Serial.println(\"LIGHT OFF\");\n        } else {\n            Serial.println(\"LIGHT INVALID COMMAND\");\n        }\n    } else if (strstr(topic, \"$aws\/things\/esp32\/sensor\/mq2sensor\")) {\n        handleThresholdMessage((char*)payload);\n    }\n}\n\n\/\/ Prepare sensor data as JSON string\nString prepareSensorData(int value) {\n    StaticJsonDocument&lt;200> doc;\n    doc&#91;\"value\"] = value;\n    String payload;\n    serializeJson(doc, payload);\n    return payload;\n}\n\n\/\/ MQTT callback\nvoid messageHandler(char* topic, byte* payload, unsigned int length) {\n    Serial.print(\"&lt;&lt; \");\n    Serial.print(topic);\n    Serial.print(\" \");\n    for (unsigned int i = 0; i &lt; length; i++) {\n        Serial.print((char)payload&#91;i]);\n    }\n    Serial.println();\n    handle_mqtt_msg(topic, payload, length);\n}\n\n\/\/ Connect to AWS IoT Core\nvoid connectAWS() {\n    net.setCACert(AWS_CERT_CA);\n    net.setCertificate(AWS_CERT_CRT);\n    net.setPrivateKey(AWS_CERT_PRIVATE);\n\n    client.setServer(AWS_IOT_ENDPOINT, AWS_IOT_PORT);\n    client.setCallback(messageHandler);\n    client.setBufferSize(4096);\n\n    Serial.print(\"Connecting to AWS IoT Core...\");\n    while (!client.connected()) {\n        client.connect(\"esp32-gas-sensor\");\n        Serial.print(\".\");\n        delay(1000);\n    }\n    client.subscribe(\"$aws\/things\/esp32\/sensor\/mq2sensor\");\n    Serial.println(\" connected!\");\n}\n\nvoid setup() {\n    Serial.begin(115200);\n    pinMode(LIGHT, OUTPUT);\n    \n    \/\/ Connect to WiFi\n    WiFi.begin(WIFI_SSID, WIFI_PASSWORD);\n    Serial.print(\"Connecting to WiFi...\");\n    while (WiFi.status() != WL_CONNECTED) {\n        Serial.print(\".\");\n        delay(1000);\n    }\n    Serial.println(\" connected!\");\n\n    \/\/ Sensor warm-up\n    Serial.println(\"Warming up sensor...\");\n    for (int i = 120; i > 0; i--) {\n        Serial.printf(\"Time left: %ds\\r\", i);\n        delay(1000);\n    }\n    Serial.println(\"\\nSensor is ready!\");\n\n    connectAWS();\n}\n\nvoid loop() {\n    int sensorValue = getMQ2Reading();\n    int mappedValue = map(sensorValue, 0, 4095, 0, 1024);\n\n    static unsigned long lastTime = 0;\n    unsigned long currentTime = millis();\n\n    if (currentTime - lastTime > 5000) {  \/\/ every 5 seconds\n        lastTime = currentTime;\n        Serial.printf(\"MQ2 ADC Reading: %d\\n\", mappedValue);\n        publishMessage(\"$aws\/things\/esp32\/sensor\/mq2sensor\", prepareSensorData(mappedValue));\n    }\n\n    if (!client.connected()) {\n        connectAWS();\n    }\n\n    client.loop();\n}\n<\/code><\/pre>\n\n\n\n<h2 class=\"wp-block-heading\">Hands-on Testing with AWS IoT Core Client:<\/h2>\n\n\n\n<p><strong>Hardware Setup<\/strong><br>Connect the MQ-2 sensor as shown in the above circuit diagram.<\/p>\n\n\n\n<p><strong>Upload Firmware<\/strong><br>Flash the ESP32 firmware after updating your <strong>Wi-Fi credentials<\/strong>, <strong>AWS endpoint<\/strong>, and <strong>certificates<\/strong>.<\/p>\n\n\n\n<p><strong>Monitor Output<\/strong><br>Open the <strong>Serial Monitor<\/strong> or <strong>Serial Plotter<\/strong> in Arduino IDE.<\/p>\n\n\n\n<p>In normal conditions, you should see ADC readings in the range of <strong>100\u2013200<\/strong>.<\/p>\n\n\n\n<p>Now bring a <strong>gas lighter<\/strong> close to the sensor and press the button. You will notice the ADC readings rise sharply.<\/p>\n\n\n\n<p><strong>Threshold &amp; AWS Publish<\/strong><br>Once the reading crosses the <strong>default threshold<\/strong>, the ESP32 will <strong>publish a message to AWS IoT Core<\/strong>.<br>(Refer to the figure below for the AWS IoT Core dashboard output).<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" width=\"1024\" height=\"456\" src=\"https:\/\/vihaaniotgateway.in\/wordpress\/wp-content\/uploads\/2025\/09\/screenshot-working-1024x456.jpg\" alt=\"\" class=\"wp-image-1829\" srcset=\"https:\/\/vihaaniotgateway.in\/wordpress\/wp-content\/uploads\/2025\/09\/screenshot-working-1024x456.jpg 1024w, https:\/\/vihaaniotgateway.in\/wordpress\/wp-content\/uploads\/2025\/09\/screenshot-working-300x134.jpg 300w, https:\/\/vihaaniotgateway.in\/wordpress\/wp-content\/uploads\/2025\/09\/screenshot-working-768x342.jpg 768w, https:\/\/vihaaniotgateway.in\/wordpress\/wp-content\/uploads\/2025\/09\/screenshot-working-1536x684.jpg 1536w, https:\/\/vihaaniotgateway.in\/wordpress\/wp-content\/uploads\/2025\/09\/screenshot-working-600x267.jpg 600w, https:\/\/vihaaniotgateway.in\/wordpress\/wp-content\/uploads\/2025\/09\/screenshot-working.jpg 1919w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-9-16 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"\ud83d\udd25 Gas Detection with ESP32 + MQ-2 | AWS IoT Core Demo \ud83d\ude80\" width=\"422\" height=\"750\" src=\"https:\/\/www.youtube.com\/embed\/UsOmr34qUpo?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n\n<figure class=\"wp-block-embed is-type-video is-provider-youtube wp-block-embed-youtube wp-embed-aspect-16-9 wp-has-aspect-ratio\"><div class=\"wp-block-embed__wrapper\">\n<iframe loading=\"lazy\" title=\"ESP32 + MQ2 Gas Sensor | Arduino Sketch, Connections &amp; Android App Demo\" width=\"500\" height=\"281\" src=\"https:\/\/www.youtube.com\/embed\/rLnwPUnKOHs?feature=oembed\" frameborder=\"0\" allow=\"accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share\" referrerpolicy=\"strict-origin-when-cross-origin\" allowfullscreen><\/iframe>\n<\/div><\/figure>\n\n\n\n<p>\ud83d\udc49 For AWS IoT Core <strong>certificate and policy setup<\/strong>, please refer to our <strong>previous blog<\/strong>.<br>\ud83d\udc49 In the <strong>next part<\/strong>, we will cover <strong>Android App configuration and implementation<\/strong> for receiving notifications.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Introduction: In our previous blog, we demonstrated how to set up an AWS IoT Core account and control a relay using an ESP32. That project was a great starting point for cloud-connected home automation. In this tutorial, we will take it a step further by integrating an MQ-2 gas sensor with the ESP32 to detect [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[66],"tags":[],"class_list":["post-1819","post","type-post","status-publish","format-standard","hentry","category-iot"],"acf":[],"aioseo_notices":[],"_links":{"self":[{"href":"https:\/\/vihaaniotgateway.in\/index.php\/wp-json\/wp\/v2\/posts\/1819","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/vihaaniotgateway.in\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/vihaaniotgateway.in\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/vihaaniotgateway.in\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/vihaaniotgateway.in\/index.php\/wp-json\/wp\/v2\/comments?post=1819"}],"version-history":[{"count":8,"href":"https:\/\/vihaaniotgateway.in\/index.php\/wp-json\/wp\/v2\/posts\/1819\/revisions"}],"predecessor-version":[{"id":2218,"href":"https:\/\/vihaaniotgateway.in\/index.php\/wp-json\/wp\/v2\/posts\/1819\/revisions\/2218"}],"wp:attachment":[{"href":"https:\/\/vihaaniotgateway.in\/index.php\/wp-json\/wp\/v2\/media?parent=1819"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/vihaaniotgateway.in\/index.php\/wp-json\/wp\/v2\/categories?post=1819"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/vihaaniotgateway.in\/index.php\/wp-json\/wp\/v2\/tags?post=1819"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}