火焰传感器(4针) 双模式检测与中断触发代码例程
一、Arduino - AO+DO双路读取
#define FLAME_AO_PIN A0 // 模拟量
#define FLAME_DO_PIN 2 // 数字量
#define BUZZER_PIN 5
void setup() {
Serial.begin(115200);
pinMode(FLAME_DO_PIN, INPUT);
pinMode(BUZZER_PIN, OUTPUT);
Serial.println("4针火焰传感器检测系统启动");
Serial.println("AO=火焰强度, DO=0表示检测到火焰");
}
void loop() {
int analogVal = analogRead(FLAME_AO_PIN);
bool flameDetected = !digitalRead(FLAME_DO_PIN); // DO低电平有效
float voltage = (analogVal / 1024.0) * 5.0;
Serial.print("AO: "); Serial.print(analogVal);
Serial.print(" ("); Serial.print(voltage, 3); Serial.print("V)");
Serial.print(" | DO: "); Serial.print(flameDetected ? "🔥火焰!" : "正常");
if (flameDetected) {
Serial.print(" | 火焰强度: ");
if (analogVal > 800) Serial.print("极强");
else if (analogVal > 600) Serial.print("强");
else if (analogVal > 400) Serial.print("中");
else Serial.print("弱");
digitalWrite(BUZZER_PIN, HIGH);
} else {
digitalWrite(BUZZER_PIN, LOW);
}
Serial.println();
delay(200);
}
二、Arduino - DO引脚中断方式(低功耗)
#define FLAME_DO_PIN 2 // Arduino Uno: INT0 = D2
#define BUZZER_PIN 5
#define LED_PIN 13
volatile bool fireAlarm = false;
volatile unsigned long lastFireTime = 0;
void IRAM_ATTR onFireDetected() {
fireAlarm = true;
lastFireTime = millis();
}
void setup() {
Serial.begin(115200);
pinMode(FLAME_DO_PIN, INPUT_PULLUP);
pinMode(BUZZER_PIN, OUTPUT);
pinMode(LED_PIN, OUTPUT);
attachInterrupt(digitalPinToInterrupt(FLAME_DO_PIN),
onFireDetected, FALLING);
Serial.println("火焰监控系统启动(中断模式)");
Serial.println("等待火焰触发...");
}
void loop() {
if (fireAlarm) {
fireAlarm = false;
Serial.print("🔥 火焰报警! 触发时间: ");
Serial.println(lastFireTime);
digitalWrite(BUZZER_PIN, HIGH);
digitalWrite(LED_PIN, HIGH);
delay(3000); // 报警持续3秒
digitalWrite(BUZZER_PIN, LOW);
digitalWrite(LED_PIN, LOW);
Serial.println("报警解除,继续监控...");
}
delay(100);
}
三、Arduino - 多级报警系统
#define FLAME_AO_PIN A0
#define FLAME_DO_PIN 2
#define BUZZER_PIN 5
#define RELAY_PIN 6 // 控制灭火装置
#define LED_GREEN 7
#define LED_YELLOW 8
#define LED_RED 9
enum AlarmLevel {
LEVEL_SAFE = 0,
LEVEL_WARNING,
LEVEL_DANGER,
LEVEL_CRITICAL
};
AlarmLevel currentLevel = LEVEL_SAFE;
void setup() {
Serial.begin(115200);
pinMode(FLAME_DO_PIN, INPUT);
pinMode(BUZZER_PIN, OUTPUT);
pinMode(RELAY_PIN, OUTPUT);
pinMode(LED_GREEN, OUTPUT);
pinMode(LED_YELLOW, OUTPUT);
pinMode(LED_RED, OUTPUT);
digitalWrite(RELAY_PIN, LOW);
digitalWrite(LED_GREEN, HIGH);
Serial.println("多级火焰报警系统");
}
void loop() {
int ao = analogRead(FLAME_AO_PIN);
bool doTriggered = !digitalRead(FLAME_DO_PIN);
AlarmLevel newLevel;
if (ao > 800 && doTriggered) {
newLevel = LEVEL_CRITICAL;
} else if (ao > 500 && doTriggered) {
newLevel = LEVEL_DANGER;
} else if (ao > 300) {
newLevel = LEVEL_WARNING;
} else {
newLevel = LEVEL_SAFE;
}
if (newLevel != currentLevel) {
currentLevel = newLevel;
switch (currentLevel) {
case LEVEL_SAFE:
Serial.println("🟢 安全 - 无火焰");
digitalWrite(LED_GREEN, HIGH);
digitalWrite(LED_YELLOW, LOW);
digitalWrite(LED_RED, LOW);
digitalWrite(BUZZER_PIN, LOW);
digitalWrite(RELAY_PIN, LOW);
break;
case LEVEL_WARNING:
Serial.println("🟡 警告 - 检测到微弱红外源");
digitalWrite(LED_GREEN, LOW);
digitalWrite(LED_YELLOW, HIGH);
digitalWrite(LED_RED, LOW);
tone(BUZZER_PIN, 1000, 200);
break;
case LEVEL_DANGER:
Serial.println("🟠 危险 - 确认火焰存在!");
digitalWrite(LED_GREEN, LOW);
digitalWrite(LED_YELLOW, LOW);
digitalWrite(LED_RED, HIGH);
digitalWrite(BUZZER_PIN, HIGH); // 持续报警
digitalWrite(RELAY_PIN, HIGH); // 启动灭火
break;
case LEVEL_CRITICAL:
Serial.println("🔴 紧急 - 强火焰! 全力灭火!");
digitalWrite(LED_GREEN, LOW);
digitalWrite(LED_YELLOW, LOW);
digitalWrite(LED_RED, HIGH);
digitalWrite(BUZZER_PIN, HIGH);
digitalWrite(RELAY_PIN, HIGH);
break;
}
}
delay(100);
}
四、ESP-IDF - 双路检测+FreeRTOS任务通知
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "driver/gpio.h"
#include "esp_adc/adc_oneshot.h"
#define FLAME_DO_GPIO 25
#define FLAME_ADC_CHANNEL ADC_CHANNEL_7
#define BUZZER_GPIO 26
static TaskHandle_t alarm_task_handle = NULL;
static void IRAM_ATTR flame_isr_handler(void *arg) {
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
vTaskNotifyGiveFromISR(alarm_task_handle, &xHigherPriorityTaskWoken);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
void alarm_task(void *pvParameters) {
while (1) {
if (ulTaskNotifyTake(pdTRUE, pdMS_TO_TICKS(1000)) > 0) {
printf("🔥 火焰中断触发! 执行报警...\n");
gpio_set_level(BUZZER_GPIO, 1);
vTaskDelay(pdMS_TO_TICKS(3000));
gpio_set_level(BUZZER_GPIO, 0);
printf("报警解除\n");
}
}
}
void app_main(void) {
gpio_config_t io_conf = {
.pin_bit_mask = (1ULL << FLAME_DO_GPIO) | (1ULL << BUZZER_GPIO),
.mode = GPIO_MODE_INPUT | GPIO_MODE_OUTPUT,
.pull_up_en = GPIO_PULLUP_ENABLE,
.intr_type = GPIO_INTR_NEGEDGE,
};
gpio_config(&io_conf);
gpio_set_direction(BUZZER_GPIO, GPIO_MODE_OUTPUT);
gpio_install_isr_service(0);
gpio_isr_handler_add(FLAME_DO_GPIO, flame_isr_handler, NULL);
xTaskCreate(alarm_task, "alarm", 2048, NULL, 5, &alarm_task_handle);
printf("4针火焰传感器监控系统就绪\n");
while (1) {
vTaskDelay(pdMS_TO_TICKS(500));
}
}
五、电位器调校助手程序
#define FLAME_DO_PIN 2
void setup() {
Serial.begin(115200);
pinMode(FLAME_DO_PIN, INPUT_PULLUP);
Serial.println("=== 电位器调校助手 ===");
Serial.println("1. 将传感器置于检测目标距离");
Serial.println("2. 逆时针旋转电位器直到DO=0(LOW)");
Serial.println("3. 缓慢顺时针旋转直到DO刚刚变为1(HIGH)");
Serial.println("4. 此时阈值最优,固定电位器即可");
Serial.println("=======================");
}
void loop() {
int doState = digitalRead(FLAME_DO_PIN);
Serial.print("DO状态: ");
if (doState == LOW) {
Serial.println("LOW ← 已触发(火焰/红外源太强或阈值太低)");
} else {
Serial.println("HIGH ← 未触发");
}
delay(300);
}