MQ2

元器件
传感器
库存 800

介绍

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 气体传感器驱动代码例程(模拟+数字双模式).md

# 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 |

参考资料

暂无参考文献