介绍
MQ-2半导体烟雾/可燃气体传感器,对液化气(LPG)、丙烷、氢气、甲烷、酒精、烟雾等敏感,双路输出(模拟量+数字TTL),灵敏度可调,加热电压5V,广泛用于家庭燃气泄漏报警、工业气体检测、火灾预警等
MQ-2半导体烟雾/可燃气体传感器,对液化气(LPG)、丙烷、氢气、甲烷、酒精、烟雾等敏感,双路输出(模拟量+数字TTL),灵敏度可调,加热电压5V,广泛用于家庭燃气泄漏报警、工业气体检测、火灾预警等
| 参数 | 值 |
|---|---|
| 加热功耗 | 约800mW(150mA@5V) |
| 加热电压 | 5V ±0.1V |
| 响应时间 | <10s(典型) |
| 工作温度 | -20°C ~ +50°C |
| 工作电压 | 5V DC |
| 恢复时间 | <30s |
| 检测气体 | LPG、丙烷、甲烷、氢气、酒精、烟雾 |
| 模块尺寸 | 约35×22mm |
| 测量范围 | 300-10000ppm(可燃气体) |
| 输出方式 | 模拟量(0-5V) + 数字量(TTL电平) |
| 预热时间 | 建议>60秒(充分预热>24小时) |
| 灵敏度调节 | 板上电位器(调节数字输出阈值) |
# MQ2 气体传感器驱动代码例程
## 一、Arduino - 模拟量读取 + 浓度换算
```cpp
// MQ-2 模拟量读取,计算PPM浓度
#define MQ2_AO_PIN A0
#define MQ2_DO_PIN 2
// 校准参数(需根据实际环境标定)
#define R0 10.0 // 传感器在洁净空气中的电阻(kΩ)
#define RL 10.0 // 负载电阻(kΩ)
#define VCC 5.0
void setup() {
Serial.begin(115200);
pinMode(MQ2_DO_PIN, INPUT);
Serial.println("MQ-2 传感器预热中...");
Serial.println("请等待60秒预热完成");
delay(60000); // 预热60秒
Serial.println("预热完成,开始检测");
}
void loop() {
// === 模拟量读取 ===
int raw = analogRead(MQ2_AO_PIN);
float voltage = (raw / 1024.0) * VCC;
// 计算传感器电阻 Rs
// Rs = (VCC - Vout) * RL / Vout
float rs = 0;
if (voltage > 0.01) { // 防止除零
rs = (VCC - voltage) * RL / voltage;
}
// 计算 Rs/R0 比值
float ratio = rs / R0;
// 根据MQ-2灵敏度曲线估算不同气体浓度(ppm)
// 公式: ppm = a * (Rs/R0)^b (a,b为拟合系数)
float lpg_ppm = 1000.0 * pow(ratio / 3.5, -1.5); // LPG
float smoke_ppm = 1000.0 * pow(ratio / 4.0, -1.5); // 烟雾
float ch4_ppm = 1000.0 * pow(ratio / 4.5, -1.5); // 甲烷
// === 数字量读取 ===
bool alarm = !digitalRead(MQ2_DO_PIN); // DO低电平触发
// === 输出 ===
Serial.println("=== MQ-2 检测结果 ===");
Serial.print("ADC: "); Serial.print(raw);
Serial.print(" | 电压: "); Serial.print(voltage, 3);
Serial.println("V");
Serial.print("Rs: "); Serial.print(rs, 2);
Serial.print("kΩ | Rs/R0: "); Serial.println(ratio, 2);
Serial.print("LPG预估: "); Serial.print(lpg_ppm, 1);
Serial.println(" ppm");
Serial.print("烟雾预估: "); Serial.print(smoke_ppm, 1);
Serial.println(" ppm");
if (alarm) {
Serial.println("🔴 数字报警! 气体浓度超过阈值!");
} else {
Serial.println("🟢 气体浓度正常");
}
Serial.println("------------------------");
delay(1000);
}
```
## 二、Arduino - 自动校准R0
```cpp
// 在洁净空气中运行此程序,自动标定R0值
#define MQ2_PIN A0
#define RL 10.0
#define VCC 5.0
// 假定洁净空气中 Rs/R0 ≈ 9.8 (MQ-2 datasheet)
#define CLEAN_AIR_RATIO 9.8
float calibrateR0(int samples = 100) {
float sum_rs = 0;
for (int i = 0; i < samples; i++) {
int raw = analogRead(MQ2_PIN);
float voltage = (raw / 1024.0) * VCC;
if (voltage > 0.01) {
float rs = (VCC - voltage) * RL / voltage;
sum_rs += rs;
}
delay(100);
}
float rs_avg = sum_rs / samples;
float r0 = rs_avg / CLEAN_AIR_RATIO;
return r0;
}
void setup() {
Serial.begin(115200);
Serial.println("MQ-2 R0 自动校准程序");
Serial.println("请确保传感器处于洁净空气中!");
Serial.println("预热60秒...");
delay(60000);
float r0 = calibrateR0(200);
Serial.println("======== 校准完成 ========");
Serial.print("R0 = "); Serial.print(r0, 3);
Serial.println(" kΩ");
Serial.print("请在代码中设置: #define R0 ");
Serial.println(r0, 3);
}
void loop() { }
```
## 三、ESP-IDF - 完整气体检测任务
```c
// mq2_task.c - ESP32 MQ-2 气体检测
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_adc/adc_oneshot.h"
#include "esp_log.h"
#include <math.h>
static const char *TAG = "MQ2";
#define MQ2_ADC_CHANNEL ADC_CHANNEL_6 // GPIO34
#define MQ2_DO_GPIO 25 // 数字输出引脚
#define RL 10.0f
#define R0 10.0f // 需实际标定
#define VCC 5.0f
static adc_oneshot_unit_handle_t adc_handle;
void mq2_init(void) {
// GPIO初始化(数字输出)
gpio_config_t io_conf = {
.pin_bit_mask = (1ULL << MQ2_DO_GPIO),
.mode = GPIO_MODE_INPUT,
.pull_up_en = GPIO_PULLUP_ENABLE,
};
gpio_config(&io_conf);
// ADC初始化
adc_oneshot_unit_init_cfg_t init_cfg = {
.unit_id = ADC_UNIT_1,
.ulp_mode = ADC_ULP_MODE_DISABLE,
};
adc_oneshot_new_unit(&init_cfg, &adc_handle);
adc_oneshot_chan_cfg_t chan_cfg = {
.atten = ADC_ATTEN_DB_11,
.bitwidth = ADC_BITWIDTH_12,
};
adc_oneshot_config_channel(adc_handle, MQ2_ADC_CHANNEL, &chan_cfg);
ESP_LOGI(TAG, "MQ-2 initialized. Waiting 60s warmup...");
vTaskDelay(pdMS_TO_TICKS(60000));
ESP_LOGI(TAG, "MQ-2 ready.");
}
typedef struct {
float voltage;
float rs;
float ratio;
bool alarm;
} mq2_reading_t;
esp_err_t mq2_read(mq2_reading_t *out) {
int raw = 0;
esp_err_t ret = adc_oneshot_read(adc_handle, MQ2_ADC_CHANNEL, &raw);
if (ret != ESP_OK) return ret;
// ESP32 12位ADC,衰减11dB时量程约0-3.9V
// MQ2输出0-5V需分压或使用衰减校准
out->voltage = (raw / 4095.0f) * 3.9f; // 近似
if (out->voltage > 0.01f) {
out->rs = (VCC - out->voltage) * RL / out->voltage;
} else {
out->rs = 999.0f;
}
out->ratio = out->rs / R0;
out->alarm = (gpio_get_level(MQ2_DO_GPIO) == 0);
return ESP_OK;
}
void mq2_task(void *pvParameters) {
mq2_init();
mq2_reading_t reading;
while (1) {
if (mq2_read(&reading) == ESP_OK) {
// LPG浓度估算
float lpg_ppm = 1000.0f * powf(reading.ratio / 3.5f, -1.5f);
ESP_LOGI(TAG, "V=%.3fV Rs=%.1fkΩ LPG≈%.0fppm %s",
reading.voltage, reading.rs, lpg_ppm,
reading.alarm ? "🔴ALARM!" : "🟢OK");
}
vTaskDelay(pdMS_TO_TICKS(2000));
}
}
// 在app_main中创建任务:
// xTaskCreate(mq2_task, "mq2", 4096, NULL, 5, NULL);
```
## 四、MQ2报警联动 - 继电器/蜂鸣器控制
```cpp
#define MQ2_DO_PIN 2 // 数字报警
#define BUZZER_PIN 5 // 蜂鸣器
#define RELAY_PIN 6 // 继电器(控制排风扇/电磁阀)
#define LED_GREEN 7 // 正常指示灯
#define LED_RED 8 // 报警指示灯
void setup() {
Serial.begin(115200);
pinMode(MQ2_DO_PIN, INPUT);
pinMode(BUZZER_PIN, OUTPUT);
pinMode(RELAY_PIN, OUTPUT);
pinMode(LED_GREEN, OUTPUT);
pinMode(LED_RED, OUTPUT);
digitalWrite(RELAY_PIN, LOW); // 继电器的安全默认状态
digitalWrite(LED_GREEN, HIGH); // 初始正常
Serial.println("MQ-2 报警联动系统启动,预热60秒...");
delay(60000);
}
void loop() {
bool alarm = !digitalRead(MQ2_DO_PIN);
if (alarm) {
digitalWrite(LED_GREEN, LOW);
digitalWrite(LED_RED, HIGH);
digitalWrite(BUZZER_PIN, HIGH);
digitalWrite(RELAY_PIN, HIGH); // 打开排风扇
Serial.println("🔴 燃气泄漏! 排风扇已启动!");
delay(5000); // 最少运行5秒
} else {
digitalWrite(LED_RED, LOW);
digitalWrite(LED_GREEN, HIGH);
digitalWrite(BUZZER_PIN, LOW);
digitalWrite(RELAY_PIN, LOW); // 关闭排风扇
}
delay(200);
}
```
## 五、MQ系列传感器速查
| 型号 | 检测对象 | R0标定气体 | 加热电压 |
|------|----------|------------|----------|
| MQ-2 | LPG/甲烷/烟雾/酒精 | 1000ppm H2 | 5V |
| MQ-3 | 酒精 | 0.4mg/L酒精 | 5V |
| MQ-5 | LPG/天然气 | 1000ppm H2 | 5V |
| MQ-7 | 一氧化碳 | 100ppm CO | 1.4V/5V交替 |
| MQ-135 | 空气质量 | 100ppm NH3 | 5V |
暂无参考文献