Hướng dẫn kết nối cảm biến khí gas MQ-2 với ESP32, đọc giá trị analog (khói, LPG, butane…) và hiển thị lên màn hình OLED SSD1306 (I2C).
Mục lục
- Giới thiệu
- Cảnh báo & nguyên tắc đo MQ-2
- Phần cứng cần chuẩn bị
- Sơ đồ kết nối
- Ví dụ 1 – Đọc cảm biến MQ-2 (analog)
- Ví dụ 2 – Đọc cảm biến & hiển thị OLED
- Hiệu chuẩn & mẹo thực tế
- Lỗi thường gặp & cách khắc phục
- Gợi ý mở rộng
1) Giới thiệu
MQ-2 là cảm biến phát hiện khí gas/khói giá rẻ. Module thường có AO (analog) và DO (digital ngưỡng). ESP32 có ADC tích hợp, phù hợp đọc AO để theo dõi mức tương đối của nồng độ khí.


2) Cảnh báo & nguyên tắc đo MQ-2
- Heater & AO của MQ-2 thường là 5V. Ngõ AO trên nhiều module có biên độ 0–5V → không đưa trực tiếp vào ADC ESP32 (giới hạn 0–3.3V).
- Dùng mạch chia áp (ví dụ 100kΩ / 100kΩ), lấy tín hiệu giữa đưa vào chân ADC để hạ biên độ còn ~0–2.5V.
- MQ-2 cần làm nóng (burn-in) vài phút đến vài chục phút để ổn định.
- Giá trị ADC là tương đối; muốn suy ra ppm cần đường cong Rs/R0 theo datasheet và hiệu chuẩn môi trường.
3) Phần cứng cần chuẩn bị
| Linh kiện | Số lượng | Ghi chú |
|---|---|---|
| ESP32 DevKit V1 | 1 | |
| Cảm biến MQ-2 (module AO/DO) | 1 | Nguồn 5V cho heater |
| 2 điện trở 100kΩ | 2 | Tạo mạch chia áp AO → ADC |
| OLED SSD1306 I2C 0.96″ (128×64) | 1 | Địa chỉ thường 0x3C |
| Dây nối, breadboard | Vài sợi |
4) Sơ đồ kết nối (Connection Diagram)

- Nguồn
- ESP32 cấp USB 5V.
- MQ-2 VCC → 5V, GND → GND.
- Tín hiệu analog
- AO (MQ-2) → mạch chia áp 100k/100k → ESP32 ADC GPIO34.
- (Tuỳ chọn) DO (MQ-2) → GPIO26 để đọc mức ngưỡng.
- OLED (I2C)
- SDA → GPIO21, SCL → GPIO22, VCC → 3V3, GND → GND.
5) Ví dụ 1 – Đọc cảm biến MQ-2 (analog)
Mục tiêu
- Đọc ADC từ MQ-2 tại GPIO34 qua chia áp.
- In giá trị thô (0–4095) và điện áp xấp xỉ.
Code (Arduino IDE)
// ESP32 + MQ-2 (AO) -> Voltage Divider (100k/100k) -> GPIO34
#define MQ2_ADC_PIN 34
const float VREF = 3.3; // tham chiếu ADC ESP32
void setup() {
Serial.begin(115200);
delay(300);
Serial.println("ESP32 - MQ2 analog read (divider 100k/100k -> ADC34)");
analogReadResolution(12); // 0..4095
// analogSetAttenuation(ADC_11db); // tùy nhu cầu
}
void loop() {
int raw = analogRead(MQ2_ADC_PIN); // 0..4095
float vadc = raw * VREF / 4095.0; // điện áp tại CHÂN ADC (sau chia 1/2)
float vao = vadc * 2.0; // ước lượng điện áp tại AO của MQ-2
Serial.print("ADC="); Serial.print(raw);
Serial.print(" | Vadc="); Serial.print(vadc, 3);
Serial.print(" V | VAO~"); Serial.print(vao, 3);
Serial.println(" V");
delay(500);
}
Kết quả
- Serial hiển thị ADC, Vadc (sau chia), VAO (ước lượng).
- Đưa nguồn lửa/gas lại gần → giá trị tăng rõ rệt.
6) Ví dụ 2 – Đọc cảm biến & hiển thị OLED
Mục tiêu
- Đọc MQ-2 (AO) như Ví dụ 1.
- Hiển thị bar/giá trị trên OLED SSD1306 (I2C 0x3C).
Thư viện cần cài
- Adafruit SSD1306
- Adafruit GFX Library
Code (Arduino IDE)
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define MQ2_ADC_PIN 34
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
#define OLED_ADDR 0x3C
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
const float VREF = 3.3;
void setup() {
Serial.begin(115200);
analogReadResolution(12);
if (!display.begin(SSD1306_SWITCHCAPVCC, OLED_ADDR)) {
Serial.println(F("OLED init failed! Check I2C and address 0x3C/0x3D."));
for(;;);
}
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(0,0);
display.println(F("ESP32 + MQ-2 + OLED"));
display.println(F("AO via divider -> ADC34"));
display.display();
delay(800);
}
void drawBar(int value, int maxv) {
int w = map(value, 0, maxv, 0, 120);
display.drawRect(4, 38, 120, 18, SSD1306_WHITE);
display.fillRect(4, 38, w, 18, SSD1306_WHITE);
}
void loop() {
int raw = analogRead(MQ2_ADC_PIN);
float vadc = raw * VREF / 4095.0;
float vao = vadc * 2.0; // ước lượng trước chia áp
display.clearDisplay();
display.setTextSize(1);
display.setCursor(0, 0);
display.print(F("ADC: ")); display.println(raw);
display.print(F("Vadc: ")); display.print(vadc, 3); display.println(F("V"));
display.print(F("VAO~: ")); display.print(vao, 3); display.println(F("V"));
display.setCursor(0, 28);
display.print(F("Level:"));
drawBar(raw, 4095);
display.display();
// Log Serial
Serial.printf("ADC=%d, Vadc=%.3f V, VAO~%.3f V\n", raw, vadc, vao);
delay(300);
}
Kết quả
- OLED hiển thị ADC, Vadc (sau chia), VAO ước lượng và thanh mức.
- Khi có khói/khí gas, Level tăng nhanh.
7) Hiệu chuẩn & mẹo thực tế
- Burn-in vài chục phút lần đầu; chờ ổn định trước khi đo.
- Lấy giá trị nền (baseline) không khí sạch để so sánh tương đối.
- Nếu cần ppm, đọc datasheet để dùng đường cong Rs/R0 vs ppm và hiệu chuẩn R0 ở môi trường chuẩn.
- Giảm nhiễu: lấy trung bình trượt, thêm tụ 100nF gần AO, chắc GND chung.
8) Lỗi thường gặp & cách khắc phục
- ADC luôn cao/thấp: kiểm tra dây AO, mạch chia áp 100k/100k.
- OLED không hiển thị: sai địa chỉ (thử
0x3D), sai dây SDA/SCL. - Giá trị dao động mạnh: nguồn/ground yếu; cần lọc trung bình; để cảm biến ổn định sau burn-in.
- ESP32 nóng/treo: tuyệt đối không đưa 5V trực tiếp vào ADC!
9) Gợi ý mở rộng
- Cảnh báo buzzer/relay khi vượt ngưỡng; gửi dữ liệu MQTT/Web.
- Ghi log ra SPIFFS/SD Card; biểu đồ thời gian thực WebSocket.
- Kết hợp DHT22/BME280 để bù theo nhiệt độ/độ ẩm.


Để lại một bình luận