ESP32 Air Quality

  • Author: Toader Ion Andrei
  • Email: ion_andrei.toader@stud.acs.upb.ro
  • Master: SRIC

Project Description

This project is an air quality monitoring system built using an ESP32 microcontroller, an MQ-135 gas sensor, and a buzzer for audible alerts. The main goal of the system is to continuously monitor the air quality, detect harmful gas levels (such as NH3, NOx, benzene, CO2, and smoke), and:

  • Alert the user in real-time using a buzzer when air quality drops below a safe threshold.
  • Upload collected air quality data to a web server where it can be visualized and analyzed over time.
  • Logs data to a Firebase database and display it on a web dashboard.

System Architecture

The following schematic illustrates the core components and their connections in the air quality monitoring system:

This schematic includes:

  • The ESP32 as the central microcontroller
  • The MQ-135 sensor connected to an analog input pin for air quality detection
  • A buzzer connected to a digital output pin for alerts

Components Used

  • ESP32 DevKit – Microcontroller with built-in Wi-Fi, used to read sensor data and upload it online.
  • MQ-135 Gas Sensor – Measures air quality by detecting harmful gases and pollutants.
  • Resistors (Voltage Divider for MQ-135 Analog Output): Two resistors (e.g., 110kΩ and 220kΩ) used to step down the MQ-135 analog output voltage from 5V to a safe 3.3V level for the ESP32 ADC input.
  • Buzzer – Emits a sound when the air quality exceeds predefined danger thresholds.
  • Wi-Fi Access – To connect the ESP32 to the internet and send data to the server.

Hardware Specifications

ESP32 Development Board

Description: The ESP32 is a low-cost, low-power microcontroller with integrated Wi-Fi and Bluetooth. It is ideal for IoT projects due to its wireless capabilities and sufficient computing power.

Key Features:

  • Dual-core Xtensa® 32-bit LX6 microprocessor, up to 240 MHz
  • 520 KB SRAM
  • Integrated 802.11 b/g/n Wi-Fi
  • Bluetooth 4.2 (BLE + classic)
  • 12-bit ADC (18 channels), 3.3V logic
  • Multiple GPIO pins (capacitive touch, SPI, I2C, UART, PWM)
  • USB-powered

Use in Project:

  • Collects analog data from the MQ-135 sensor.
  • Triggers a buzzer if pollution exceeds a threshold.
  • Sends data to Firebase for live monitoring.

Important Pins Used:

  • GPIO34 (Analog input from MQ-135)
  • GPIO25 (Digital output to buzzer)
  • 3.3V (Power for sensor)
  • GND

MQ-135 Gas Sensor

Description: The MQ-135 is a chemical gas sensor capable of detecting a wide range of gases, including ammonia, nitrogen oxides, benzene, smoke, and carbon dioxide. It is commonly used in air quality monitoring.

Key Features:

  • Operating Voltage: 5V
  • Analog and Digital Output
  • Detectable Gases: NH₃, NOₓ, alcohol, benzene, smoke, CO₂
  • Preheat time: 24–48 hours (best accuracy after initial burn-in)

Use in Project: Provides an analog voltage proportional to air pollution levels. Connected to the ESP32’s analog input (GPIO34) through a voltage divider or level shifter, since it outputs 5V and ESP32 is 3.3V-tolerant.

Pinout:

Pin Function Description
VCC Power Input Connect to 5V
GND Ground Connect to GND
AOUT Analog Output Analog signal to ESP32 (via voltage divider)
DOUT Digital Output Not used in this project

Active Buzzer Module

Description: An active buzzer is a simple sound-emitting component that generates a tone when voltage is applied. Unlike passive buzzers, it does not require PWM control — just a HIGH/LOW signal.

Key Features:

  • Operating Voltage: 3.3V – 5V
  • Sound Level: ~85 dB at 10 cm
  • Built-in oscillation circuit

Use in Project:

  • Connected to a digital GPIO pin (e.g., GPIO25) on the ESP32.
  • Activates (beeps) when the air quality exceeds a defined threshold.

Pinout:

Pin Function Description
+ VCC Connect to 3.3V or 5V
- GND Connect to Ground
SIG Signal Input Connect to ESP32 digital pin (e.g., GPIO25)

Voltage Divider Resistors

Description:

  • This divides the sensor’s 5V analog output down to approximately 3.3V, protecting the ESP32 ADC pin from damage.

Use in Project:

  • Two resistors (e.g., 110kΩ and 220kΩ) are used in series between the sensor output and ground.
  • The junction between the two resistors connects to the ESP32 analog input pin.

Breadboard and Jumper Wires

Description:

  • Used for prototyping and temporary connections between components without soldering.

Use in Project:

  • All components are connected on a breadboard using jumper wires for testing and layout flexibility.

Power Supply

Description:

  • Unordered List ItemThe ESP32 is powered via USB (5V), and its onboard regulator provides 3.3V. The MQ-135 needs 5V to operate correctly.

Use in Project:

  • USB cable or battery pack used to power ESP32.
  • ESP32 powers other components directly or through regulated output pins.

How It Works

  • The MQ-135 sensor is powered with 5V and continuously measures the gas concentration in the air.
  • The sensor’s analog output (AOUT) is connected to one of the ESP32’s analog input pins (e.g., GPIO34), through a voltage divider to ensure safe 0–3.3V levels.
  • The ESP32 reads the analog values, processes them, and calculates an Air Quality Index (AQI) approximation based on predefined thresholds.
  • If the AQI is above a critical threshold, indicating poor air quality, the buzzer is triggered through a digital output pin (e.g., GPIO25) to warn the user.
  • The ESP32 then sends the air quality data via Wi-Fi to Firebase
  • The web app displays the data in real-time on a web interface, allowing users to monitor air conditions from any device.

Software Description

The Air Quality is a web application created to monitor and display air quality data in real time. It retrieves sensor readings such as PPM values from an air quality sensor—and presents them through a clean, user-friendly interface. The application is designed for development and educational use, offering a simple way to test, view, and analyze environmental data either locally or through connection with cloud-based platforms. Its structure is modular and flexible, making it easy to adapt to different use cases and hardware setups.

Code Snippet

  • Wi-Fi & Firebase Initialization

This part connects to Wi-Fi and initializes Firebase for anonymous sign-in and Realtime Database communication.

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

#define WIFI_SSID "********"
#define WIFI_PASSWORD "**********"
#define API_KEY "********"
#define DATABASE_URL "**********"

FirebaseData fbdo;
FirebaseAuth auth;
FirebaseConfig config;

void setup() {
  Serial.begin(115200);

  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  while (WiFi.status() != WL_CONNECTED) {
    delay(300);
  }

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

  if (Firebase.signUp(&config, &auth, "", "")) {
    Serial.println("Firebase signUp succeeded");
  }

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

Reads the analog value from the MQ-135 sensor, calculates Rs, and then converts that to a PPM (parts per million) estimate using a logarithmic formula.

#define MQ135_PIN 34
#define RZERO 116404.0
#define RL_VALUE 10000.0
#define PARA 116.6020682
#define PARB -2.769034857

void loop() {
  int adcValue = analogRead(MQ135_PIN);
  float sensor_voltage = adcValue * (3.3 / 4095.0);
  float rs = (3.3 - sensor_voltage) * RL_VALUE / sensor_voltage;
  float ratio = rs / RZERO;
  float ppm = PARA * pow(ratio, PARB);
}
  • Buzzer Alert Logic

Activates a buzzer if the air quality degrades beyond a certain threshold (800 PPM in this case).

#define BUZZER_PIN 25

void setup() {
  pinMode(BUZZER_PIN, OUTPUT);
  digitalWrite(BUZZER_PIN, HIGH); // buzzer off
}

void loop() {
  // ...
  if (ppm > 800) {
    digitalWrite(BUZZER_PIN, LOW); // buzzer on
  } else {
    digitalWrite(BUZZER_PIN, HIGH); // buzzer off
  }
}
  • Sending Data to Firebase

Uploads the latest calculated PPM value to Firebase Realtime Database under the path /air_quality/ppm.

if (Firebase.RTDB.setFloat(&fbdo, "/air_quality/ppm", ppm)) {
  Serial.println("Data sent to Firebase");
} else {
  Serial.print("Failed to send data: ");
  Serial.println(fbdo.errorReason());
}

}

Web Application

References

iothings/proiecte/2025sric/airquality.txt · Last modified: 2025/05/28 22:29 by ion_andrei.toader
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