Smart Air Quality & Gas Leakage Monitor Using ESP32, MQ-135, and OLED Display
For home and workplace safety, real-time detection of hazardous gas leaks and air quality monitoring are crucial. In this project, we construct a small air monitoring node that uses an ESP32 microcontroller-powered 0.96-inch I2C OLED screen to show real-time status updates and identify dangerous airborne gasses using a MQ-135 sensor.

Components Used
- ESP32 Development Board
- MQ-135 Air Sensor Module
- 0.96″ SSD1306 I2C OLED Display (128×64 pixels)
- Breadbaord

Circuit Wiring
| ESP32 | MQ-135 | OLED |
| VIN | VCC | |
| GND | GND | GND |
| GPIO 34 | AO | |
| GPIO 21 | SDA | |
| GPIO 22 | SCL | |

Required Libraries
Adafruit SSD1306
Hardware driver for monochrome SSD1306 OLED displays

Adafruit GFX
Core graphics engine for rendering text, fonts, and shapes

Arduino Code
#include <Adafruit_GFX.h> // Include the Adafruit GFX library for graphics functions
#include <Adafruit_SSD1306.h> // Include the Adafruit SSD1306 library for the OLED display
// OLED display configuration
#define SCREEN_WIDTH 128 // Define the OLED display width in pixels
#define SCREEN_HEIGHT 64 // Define the OLED display height in pixels
#define OLED_RESET -1 // Define reset pin (-1 if sharing microcontroller reset pin)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT); // Create display instance
const int Gas34 = 34; // Analog pin connected to MQ-135 AO pin
// Wi-Fi safe analog input pins on ADC1:
// analogRead(39);
// analogRead(34);
// analogRead(35);
// analogRead(32);
// analogRead(33);
int data;
void setup() {
Serial.begin(9600);
pinMode(Gas34, INPUT);
// Initialize OLED display with I2C address 0x3C
if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
while (true); // Loop indefinitely if initialization fails
}
display.clearDisplay();
display.setTextSize(2); // Adjusted size for clean screen layout
display.setTextColor(SSD1306_WHITE);
display.setCursor(0, 10);
display.println(F("Initializing..."));
display.display();
delay(2000);
}
void loop() {
data = analogRead(Gas34); // Read raw 12-bit ADC value (0 - 4095)
Serial.print("MQ-135 Value: ");
Serial.println(data);
// Evaluate gas threshold
if (data > 300) {
display.clearDisplay();
display.setTextSize(2);
display.setCursor(42, 0);
display.println(F("GAS"));
display.setCursor(15, 20);
display.println(F("has been"));
display.setCursor(15, 45);
display.println(F("Detected."));
display.display();
} else {
display.clearDisplay();
display.setTextSize(2);
display.setCursor(26, 15);
display.println(F("No GAS"));
display.setCursor(15, 45);
display.println(F("Detected."));
display.display();
}
delay(1000);
}
How the project works
When exposed to airborne pollutants such as smoke, ammonia, benzene, and carbon dioxide, the electrical conductivity of the MQ-135 air quality sensor’s internal Tin Dioxide (SnO2) heating element changes dynamically. The sensor produces a greater analog voltage signal when the concentration of the targeted gasses rises. The ESP32 uses its integrated 12-bit Analog-to-Digital Converter (ADC) on GPIO 34 to sample the signal and provide raw digital values between 0 and 4095.

Every second, the ESP32 examines these analog values within the main execution loop and compares them to a predetermined safety threshold of 300. The ESP32 instructs the SSD1306 OLED screen to display a “No GAS Detected” status message over the I2C bus (GPIO 21 SDA and GPIO 22 SCL) if the reading falls below or remains at the threshold.

The micro-controller provides live telemetry to the Serial Monitor and updates the display with a high-priority “GAS has been Detected” warning if the gas concentration causes the reading to surge above 300.

