MQ2 气体传感器驱动代码例程
一、Arduino - 模拟量读取 + 浓度换算
#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;
float rs = 0;
if (voltage > 0.01) { // 防止除零
rs = (VCC - voltage) * RL / voltage;
}
float ratio = rs / R0;
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
#define MQ2_PIN A0
#define RL 10.0
#define VCC 5.0
#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 - 完整气体检测任务
#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_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_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;
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) {
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));
}
}
四、MQ2报警联动 - 继电器/蜂鸣器控制
#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 |