ESP32 smoke detector

  • Author: Paraschiv Theodor-Vlad
  • Email: theodor.paraschiv@stud.acs.pub.ro
  • Master: SRIC

Introduction

This project implements a simple, low-cost smoke and gas detection system using an ESP32 microcontroller, an MQ-2 gas sensor, and an active buzzer. The system reads analog gas/smoke concentration values via the MQ-2 sensor and sends this data periodically to a Firebase Realtime Database.

When dangerous gas levels are detected (above a configurable threshold — 300 in this project), the system triggers an audible alarm using a connected buzzer and sends an immediate alert email via IFTTT Webhooks integration.

A web-based frontend fetches data from Firebase and visualizes it using a graph, with gas/smoke values on the Y-axis and timestamps (converted from UNIX time) on the X-axis, displayed at regular 3-minute intervals.

Hardware Implementation

🧩 Components

  • ESP32 development board
  • MQ-2 Smoke/Combustible Gas sensor
  • Active buzzer
  • Jumpers / wires

Software Implementation

🖥️ Frontend

  • TypeScript – The frontend is a TypeScript-based single-page web application designed to visualize real-time gas and smoke concentration data retrieved from a Firebase Realtime Database

☁️ Backend

  • Firebase – serving as a cloud-hosted NoSQL data store for logging gas/smoke sensor values from the ESP32 microcontroller, data being structured by timestamp-based paths — e.g. /logs/1716760000/value — ensuring clean chronological ordering and ease of querying for frontend consumption
  • IFTTT - acting as an automation service, receiving webhook triggers from the ESP32 whenever gas/smoke levels exceed a defined threshold, instantly dispatching email alerts to notify the user in real time

📟 Embedded Software (ESP32)

Developed using the Arduino Framework, with the following libraries:

  • mobizt/Firebase Arduino Client Library for ESP8266 and ESP32@^4.4.17 – Interface for Firebase Realtime Database

📝 Code snippet

#include <Arduino.h>
#include <WiFi.h>
#include <Firebase_ESP_Client.h>
#include "addons/TokenHelper.h"
#include "addons/RTDBHelper.h"
#include <HTTPClient.h>

#define IFTTT_URL ""

#define WIFI_SSID ""
#define WIFI_PASSWORD ""

#define API_KEY ""
#define DATABASE_URL ""


#define MQ2_PIN 23
#define BUZZER_PIN 22

// Firebase objects
FirebaseData fbdo;
FirebaseAuth auth;
FirebaseConfig config;

unsigned long sendDataPrevMillis = 0;
bool signupOK = false;

void triggerIFTTT() {
  if (WiFi.status() == WL_CONNECTED) {
    HTTPClient http;
    http.begin(IFTTT_URL);
    int httpResponseCode = http.GET();

    if (httpResponseCode > 0) {
      Serial.print("IFTTT triggered, code: ");
      Serial.println(httpResponseCode);
    } else {
      Serial.print("IFTTT trigger failed: ");
      Serial.println(http.errorToString(httpResponseCode).c_str());
    }
    http.end();
  }
}

void setup() {
  Serial.begin(115200);
  pinMode(MQ2_PIN, INPUT);
  pinMode(BUZZER_PIN, OUTPUT);
  digitalWrite(BUZZER_PIN, LOW);

  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  Serial.print("Connecting to Wi-Fi");
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(300);
  }
  Serial.println();
  Serial.print("Connected with IP: ");
  Serial.println(WiFi.localIP());

  config.api_key = API_KEY;
  config.database_url = DATABASE_URL;

  if (Firebase.signUp(&config, &auth, "", "")) {
    Serial.println("Firebase signup OK");
    signupOK = true;
  } else {
    Serial.printf("Signup failed: %s\n", config.signer.signupError.message.c_str());
  }

  config.token_status_callback = tokenStatusCallback;
  Firebase.begin(&config, &auth);
  Firebase.reconnectWiFi(true);
}

void loop() {
  if (Firebase.ready() && signupOK && (millis() - sendDataPrevMillis > 5000)) {
    sendDataPrevMillis = millis();

    int smokeValue = analogRead(MQ2_PIN);
    Serial.print("MQ-2 Sensor value: ");
    Serial.println(smokeValue);

    // Control buzzer
    if (smokeValue > 300) {
      digitalWrite(BUZZER_PIN, HIGH);
      triggerIFTTT();
    } else {
      digitalWrite(BUZZER_PIN, LOW);
    }

    unsigned long currentTimestamp = Firebase.getCurrentTime();
    String path = "/logs/" + String(currentTimestamp) + "/value";

    if (Firebase.RTDB.setInt(&fbdo, path.c_str(), smokeValue)) {
      Serial.print("Data sent: ");
      Serial.print(smokeValue);
      Serial.print(" at ");
      Serial.println(currentTimestamp);
    } else {
      Serial.print("Send failed: ");
      Serial.println(fbdo.errorReason());
    }
  }
}

📱 Web

References

iothings/proiecte/2025sric/smokedetector.txt · Last modified: 2025/05/29 15:38 by theodor.paraschiv
CC Attribution-Share Alike 3.0 Unported
www.chimeric.de Valid CSS Driven by DokuWiki do yourself a favour and use a real browser - get firefox!! Recent changes RSS feed Valid XHTML 1.0