火焰传感器-3针

元器件
传感器
库存 1500

介绍

3针红外火焰传感器模块,检测波长760-1100nm(红外/可见光),纯模拟量输出(0-3.3V/5V),火焰越近输出电压越高,无数字比较输出,体积小巧,适用于火焰检测、火灾预警机器人等,灵敏度受环境光影响需注意遮光安装

规格参数

参数
探头红外光电二极管(黑色)
输出AO: 模拟电压(火焰越近/越大 电压越高)
引脚数3针(VCC/GND/AO)
响应时间<1ms
工作电压3.3V - 5V DC
检测波长760nm - 1100nm(红外波段)
检测角度约60°锥形
检测距离约20cm-100cm(取决于火焰大小)
模块尺寸约25×15mm
输出方式纯模拟量(0-VCC)

代码例程

火焰传感器(3针) ADC采样与火焰检测代码例程.md

# 火焰传感器(3针) ADC采样与火焰检测代码例程

## 一、Arduino - 基础ADC读取 + 阈值判断

```cpp
// 3针火焰传感器 - 纯模拟量检测
#define FLAME_AO_PIN    A0
#define BUZZER_PIN      5
#define LED_PIN         6

// 火焰检测阈值(需根据实际环境标定,0-1023)
#define FLAME_THRESHOLD 500     // 高于此值认为检测到火焰

void setup() {
    Serial.begin(115200);
    pinMode(BUZZER_PIN, OUTPUT);
    pinMode(LED_PIN, OUTPUT);
    
    Serial.println("3针火焰传感器检测系统");
    Serial.println("正在建立环境基线...");
    
    // 建立环境光基线
    long baseline = 0;
    for (int i = 0; i < 50; i++) {
        baseline += analogRead(FLAME_AO_PIN);
        delay(20);
    }
    baseline /= 50;
    Serial.print("环境基线: "); Serial.println(baseline);
}

void loop() {
    int raw = analogRead(FLAME_AO_PIN);
    float voltage = (raw / 1024.0) * 5.0;
    
    Serial.print("ADC: "); Serial.print(raw);
    Serial.print(" | 电压: "); Serial.print(voltage, 3);
    Serial.println("V");
    
    if (raw > FLAME_THRESHOLD) {
        Serial.println("🔥 火焰检测! 警报!");
        digitalWrite(BUZZER_PIN, HIGH);
        digitalWrite(LED_PIN, HIGH);
    } else {
        digitalWrite(BUZZER_PIN, LOW);
        digitalWrite(LED_PIN, LOW);
    }
    
    delay(100);
}
```

## 二、Arduino - 自适应阈值(动态基线扣除)

```cpp
// 通过动态基线扣除环境光干扰
#define FLAME_PIN      A0
#define ALPHA          0.05    // EMA平滑系数

float baseline = 0;             // 动态基线

void setup() {
    Serial.begin(115200);
    baseline = analogRead(FLAME_PIN);  // 初始基线
}

void loop() {
    int raw = analogRead(FLAME_PIN);
    
    // 指数移动平均更新基线(只跟踪缓慢变化的环境光)
    baseline = (ALPHA * raw) + ((1 - ALPHA) * baseline);
    
    // 当前值与基线的差值
    float delta = raw - baseline;
    
    Serial.print("Raw: "); Serial.print(raw);
    Serial.print(" | Baseline: "); Serial.print(baseline, 1);
    Serial.print(" | Delta: "); Serial.print(delta, 1);
    
    if (delta > 200) {          // 差值超过阈值
        Serial.println(" 🔥 FIRE!");
    } else if (delta > 50) {
        Serial.println(" ⚠ 附近有热源");
    } else {
        Serial.println(" ✓ 正常");
    }
    
    delay(50);
}
```

## 三、Arduino - 火焰闪烁频率分析(FFT去干扰)

```cpp
// 利用火焰特有的4-20Hz闪烁频率过滤误触发
// 使用简易Goertzel算法检测目标频率分量
#include <ArduinoFFT.h>

#define FLAME_PIN      A0
#define SAMPLES        64              // 采样点数(2的幂)
#define SAMPLING_FREQ  200             // 采样频率(Hz)

ArduinoFFT<float> FFT;
float vReal[SAMPLES];
float vImag[SAMPLES];

void setup() {
    Serial.begin(115200);
    Serial.println("火焰频率分析模式");
}

void loop() {
    // 采集数据
    unsigned long start = micros();
    for (int i = 0; i < SAMPLES; i++) {
        vReal[i] = analogRead(FLAME_PIN);
        vImag[i] = 0;
        while (micros() - start < (i + 1) * (1000000 / SAMPLING_FREQ));
    }
    
    // FFT变换
    FFT.windowing(vReal, SAMPLES, FFT_WIN_TYP_HAMMING, FFT_FORWARD);
    FFT.compute(vReal, vImag, SAMPLES, FFT_FORWARD);
    FFT.complexToMagnitude(vReal, vImag, SAMPLES);
    
    // 检查4-20Hz频段的能量
    float flameEnergy = 0;
    float totalEnergy = 0;
    int binStart = (4 * SAMPLES) / SAMPLING_FREQ;   // 4Hz对应的bin
    int binEnd   = (20 * SAMPLES) / SAMPLING_FREQ;  // 20Hz对应的bin
    
    for (int i = 1; i < SAMPLES / 2; i++) {
        if (i >= binStart && i <= binEnd) {
            flameEnergy += vReal[i];
        }
        totalEnergy += vReal[i];
    }
    
    float flameRatio = flameEnergy / totalEnergy;
    
    Serial.print("火焰闪烁能量占比: "); 
    Serial.print(flameRatio * 100, 1); 
    Serial.print("%");
    
    if (flameRatio > 0.4) {    // 火焰频段能量占比>40%
        Serial.println(" 🔥 真实火焰!");
    } else {
        Serial.println(" (静态红外源/环境光)");
    }
    
    delay(200);
}
```

## 四、ESP-IDF - 火焰传感器ADC任务

```c
// esp32_flame.c
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_adc/adc_oneshot.h"
#include "esp_log.h"

static const char *TAG = "FLAME";

#define FLAME_ADC_CHANNEL   ADC_CHANNEL_7   // GPIO35
#define FLAME_THRESHOLD     2000            // 12位ADC下的阈值

static adc_oneshot_unit_handle_t adc_handle;

void flame_sensor_init(void) {
    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, FLAME_ADC_CHANNEL, &chan_cfg);
    ESP_LOGI(TAG, "Flame sensor initialized");
}

void flame_task(void *pvParameters) {
    flame_sensor_init();
    
    // 建立基线
    int64_t baseline_sum = 0;
    for (int i = 0; i < 100; i++) {
        int raw;
        adc_oneshot_read(adc_handle, FLAME_ADC_CHANNEL, &raw);
        baseline_sum += raw;
        vTaskDelay(pdMS_TO_TICKS(10));
    }
    int baseline = baseline_sum / 100;
    ESP_LOGI(TAG, "Baseline: %d", baseline);
    
    while (1) {
        int raw;
        adc_oneshot_read(adc_handle, FLAME_ADC_CHANNEL, &raw);
        
        int delta = raw - baseline;
        
        if (delta > FLAME_THRESHOLD) {
            ESP_LOGW(TAG, "🔥 FIRE DETECTED! Raw=%d Delta=%d", raw, delta);
        } else {
            ESP_LOGI(TAG, "OK | Raw=%d Delta=%d", raw, delta);
        }
        
        vTaskDelay(pdMS_TO_TICKS(100));
    }
}
```

## 五、3针 vs 4针代码对比

| 特性 | 3针(纯模拟) | 4针(模拟+数字) |
|------|-------------|----------------|
| 信号读取 | `analogRead(A0)` | `analogRead(A0)` + `digitalRead(D2)` |
| 阈值设置 | 代码中定义常数 | 旋转板上电位器 |
| 灵敏度调节 | 修改代码重新烧录 | 螺丝刀拧电位器 |
| 快速原型 | 需要编程 | 不需要代码即可触发 |
| 抗干扰能力 | 软件滤波灵活 | 硬件固定阈值 |
| MCU资源 | 需1个ADC引脚 | 需1个ADC + 1个GPIO |

参考资料

暂无参考文献