烟雾+火焰+温湿度三路监测、超阈值自动排风、手机APP远程报警,附"选型结论张冠李戴"翻车实录

做毕业设计的同学注意了:火灾报警系统是单片机毕设的经典题目,但很多论文从选型章节就开始"翻车"——传感器身份张冠李戴、方案对比结论写反、正文两套通信协议打架。本文基于一篇毕设论文改写,带你从需求到代码完整实现一套烟雾+火焰+温湿度三路监测、自动排风、手机APP远程报警的系统,顺便把原文里那些"看不见的坑"一个个揪出来,你写论文时照着避就行。

一、系统功能拆解

先看这套系统到底要干什么,按功能域拆成 4 块、8 个模块:

功能域模块说明
环境监测DHT11 温湿度温湿度超阈值 → 自动启动风扇排风降温
环境监测MQ-2 烟雾浓度ADC 采集,超阈值 → 声光报警
火灾检测火焰检测模块检测到火焰 → 立即声光报警
人机交互OLED12864 显示实时显示温湿度、烟雾浓度、报警状态
人机交互4 按键本地设置温湿度/烟雾阈值
远程通信ESP8266(MQTT→阿里云)数据上报 + APP 远程设阈值、控风扇
报警执行蜂鸣器 + LED声光报警
排风执行继电器 + 风扇温湿度超标自动通风,也支持 APP 手动控制

工作逻辑一句话:主循环采集三路数据 → OLED 刷新 → MQTT 上云 → 温湿度超阈值开风扇 → 烟雾/火焰超限触发声光报警并推送 APP → 随时响应按键和 APP 下发的阈值指令。

二、器件选型对比(含翻车点标注)

选型章节是毕设论文最容易露馅的地方,原文就翻了好几个车,这里逐一对照:

2.1 主控:STM32F103C8T6 vs STM32F407VGT6

对比项STM32F103C8T6STM32F407VGT6
内核/主频Cortex-M3 / 72MHzCortex-M4+FPU / 168MHz
Flash/SRAM64KB / 20KB1MB / 192KB
ADC12位×2(10通道)12位×3
价格≈15 元≈40 元

火灾报警这种"采集+阈值判断+串口透传"的场景,C8T6 性能绰绰有余,选 C8T6 没问题。原文这段写得是对的。

2.2 温湿度:DHT11 vs SHT30

对比项DHT11SHT30
温度精度±2°C±0.3°C
湿度精度±5%RH±2%RH
接口单总线I2C
价格≈5 元≈15 元

DHT11 精度确实拉胯,但用来做"超阈值排风"的粗判够用,预算有限选 DHT11 合理。注意:DHT11 别拿来当"高精度监测"吹,原文摘要只说"实时监测"没吹精度,这点过关。

2.3 烟雾:MQ-2 vs CCS811

对比项MQ-2CCS811
检测对象烟雾/可燃气体(丙烷、甲烷、氢气)TVOC / eCO2
输出模拟电压(接 ADC)I2C 数字量
是否专用烟雾检测✅ 是❌ 测空气质量,非烟雾专用
价格≈8 元≈35 元

原文这段的判断是对的:CCS811 是空气质量传感器不是烟雾传感器,火灾烟雾检测就该用 MQ-2 这类。加分项:MQ-2 上电需要预热 1~2 分钟,期间读数漂移,代码里要做预热跳过或基线校准,原文没提,本文代码补上。

2.4 火焰检测:⚠️ 本篇最大翻车现场

原文方案1写的是"红外火焰传感器 TEMT6000",还煞有介事地分析了一波"高灵敏度、耐高温、抗干扰"。问题来了:TEMT6000 根本不是火焰传感器,它是 Vishay 的环境光照度传感器,峰值响应波长 570nm(绿光附近),本职工作是测环境光亮度给手机自动调节背光用的。拿它"检测火焰红外辐射",属于典型的张冠李戴——这跟把体温计当厨房秤用是一个性质的错误。

真要做火焰检测,常见选择:

方案原理特点
YG1006 / 远红外火焰探头硅光电二极管,响应 700~1000nm 红外便宜(≈8元),需要比较电路,距离近
紫外火焰传感器(如 R2868)探测火焰紫外辉光响应快、抗可见光干扰,但贵
E18-D80 漫反射光电开关940nm 红外对管+漫反射测距⚠️ 检测距离 2~15cm,本是"接近开关"

更妙的是:原文附录代码里初始化的是 E18_D80_Init()——也就是说选型章节写 TEMT6000,实际代码用的是 E18-D80 漫反射光电开关(一个 2~15cm 的接近传感器)。选型、图、代码三张皮,这就是毕设答辩时老师最爱抓的点。

本文实现建议:火焰检测用 YG1006 类红外火焰探头(数字输出接 GPIO 或模拟输出接 ADC),代码里做连续确认防误报。

2.5 无线通信:RFM95W(LoRa)vs ESP8266

对比项RFM95W(LoRa)ESP8266-01S
频段/协议433/868/915MHz LoRa2.4GHz Wi-Fi
速率≤50Kbps≤72Mbps
距离数公里数十米
需要网关需要直接进家庭路由器

家用火灾报警要接手机 APP,显然 ESP8266 更合适。但原文这里翻了个经典的车:先说"方案1:Adafruit RFM95W、方案2:ESP8266",结论却写成"因此选择方案1,ESP8266-01S"——选了方案1的编号、用了方案2的型号。答辩时被问"你到底选的哪个方案"就尴尬了。写论文时方案编号和结论型号一定要对得上。

2.6 显示:OLED12864 vs TFT LCD

OLED12864(0.96寸,I2C)驱动简单、功耗低,显示温湿度和浓度数值足够,选它没问题。小坑:原文写 OLED12864"通常尺寸为 2.6 英寸",实际市面上 12864 OLED 几乎都是 0.96 英寸,2.6 寸那种大屏一般是 SPI 的 LCD。细节别抄错。

2.7 BOM 成本清单

器件参考价
STM32F103C8T6 最小系统板≈15 元
DHT11≈5 元
MQ-2 烟雾模块≈8 元
YG1006 红外火焰探头≈8 元
ESP8266-01S≈10 元
OLED12864(I2C)≈10 元
继电器模块+5V风扇≈12 元
蜂鸣器、LED、按键、洞洞板≈10 元
合计≈78 元

三、硬件接线

模块引脚说明
DHT11 DATAPC15⚠️ 见下方接线坑1
MQ-2 AOUTPB0(ADC1_IN8)模拟量进 ADC
火焰探头 OUTPB1数字量输出
ESP8266 TX/RXPA2/PA3(USART2)115200bps
OLED SDA/SCLPB6/PB7(I2C1)—
继电器(风扇)PA0、PA1高电平吸合
LED 报警灯PA12—
蜂鸣器PB8高电平响
按键×4PB12~PB15内部上拉、按下接地

接线坑三条:

  1. PC15 不是随便用的脚。PC14/PC15 默认是 LSE 32.768kHz 晶振脚(OSC32_IN/OSC32_OUT),原文主控电路章节还专门写了"RTC 采用 32.768kHz 晶振",转头又把 DHT11 挂 PC15——如果你要用 RTC,PC14/15 就不能当 IO;既然 DHT11 占了 PC15,RTC 晶振就废了,两段描述自相矛盾。稳妥做法:DHT11 换到 PA8 或 PB5 等普通 IO。
  2. MQ-2 的 AOUT 接 ADC,别接 3.3V 供电。MQ-2 加热丝要 5V,模块一般有 VCC-5V 和模拟输出,输出电压范围要看模块分压,超 3.3V 时要电阻分压后再进 ADC(F103 ADC 满量程是 3.3V 不是 5V,原文 ADC 换算若按 5V 算就错了)。
  3. ESP8266-01S 是 3.3V 供电且峰值电流 300mA+,别从 C8T6 板载 3.3V 稳压器硬拉,容易掉电重启;CH_PD 要拉高,GPIO0 拉高进运行模式。

四、软件设计

4.1 主程序框架

int main(void)
{
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_2);
    delay_init();
    TIM4_Init(300, 7200);          /* 1ms 滴答,为按键扫描/消抖提供时基 */
    OLED_Init();
    KEY_Init();                    /* PB12~PB15 */
    DHT11_Init();                  /* 温湿度 */
    Relay_init();                  /* PA0/PA1 风扇继电器 */
    Beep_init();                   /* PB8 */
    Flame_Init();                  /* PB1 火焰数字输入 */
    Adc_Init2();                   /* PB0 MQ-2 */
    ALi_ESP8266_GPIO_Init();       /* ESP8266 复位脚 */
    MQTT_Buff_Init();
    AliIoT_Parameter_Init();       /* 三元组 + 订阅主题 */

    while (1)
    {
        Sensor_Update();           /* 采集:温湿度/烟雾/火焰 */
        OLED_Display_Cotrol();     /* 显示刷新 */
        Fan_AutoControl();         /* 温湿度超阈值 -> 排风 */
        Alarm_Check();             /* 烟雾/火焰 -> 声光报警 + 上报 */
        Key_Scan();                /* 本地阈值设置 */
        MQTT_Loop();               /* 收发云端数据、执行下发指令 */
    }
}

4.2 关键子程序一:DHT11 单总线时序

DHT11 是"一问一答"式单总线,主机拉低 ≥18ms 再释放,等传感器回 80µs 低 + 80µs 高的响应,然后收 40 位数据,每一位以 50µs 低电平开头,高电平持续 26~28µs 表示 0、70µs 表示 1:

#define DHT_PORT  GPIOC
#define DHT_PIN   GPIO_Pin_15

u8 DHT11_Read_Data(u8 *temp, u8 *humi)
{
    u8 buf[5], i;
    if (DHT11_Start() == 0) {              /* 无响应 */
        return 1;
    }
    for (i = 0; i < 5; i++) {
        buf[i] = DHT11_ReadByte();         /* 逐字节收 8bit */
    }
    if (buf[0] + buf[1] + buf[2] + buf[3] == buf[4]) {  /* 校验和 */
        *humi = buf[0];
        *temp = buf[2];
        return 0;
    }
    return 1;                              /* 校验失败 */
}

u8 DHT11_ReadBit(void)
{
    while (!DHT_READ());                   /* 等 50µs 低电平结束 */
    delay_us(40);                          /* 卡在 0/1 的判定窗口 */
    return DHT_READ() ? 1 : 0;             /* 40µs 后仍高 -> 1 */
}

坑:原文代码是 while(DHT11_Init()){}——传感器一旦没接好,程序直接死在这行,OLED、报警全瘫痪。正确做法是读失败就跳过本轮、置离线标志,别死等。

4.3 关键子程序二:MQ-2 ADC 采样与预热基线

#define MQ2_WARMUP_MS  120000   /* 预热 2 分钟 */

u16 MQ2_GetAverage(void)
{
    u32 sum = 0;
    u8 i;
    for (i = 0; i < 10; i++) {
        sum += Get_Adc(ADC_CH_8);
        delay_ms(5);
    }
    return (u16)(sum / 10);            /* 10 次均值滤波 */
}

/* 上电预热结束后记录洁净空气基线,报警阈值 = 基线 + 偏移 */
void MQ2_Calibrate(u16 *baseline)
{
    if (sys_tick < MQ2_WARMUP_MS) {
        *baseline = 0;                 /* 预热期不判报警 */
        return;
    }
    if (*baseline == 0) {
        *baseline = MQ2_GetAverage();  /* 首次稳定读数作为基线 */
    }
}

换算公式:12 位 ADC 读数 → 电压 V = adc * 3.3f / 4095。烟雾浓度 ppm 需查 MQ-2 的 Rs-Ro 曲线,毕设阶段用"ADC 原始值 + 阈值"或"电压阈值"判定即可,别在论文里硬编一个没出处的 ppm 公式。

4.4 关键子程序三:火焰检测连续确认(防误报)

火焰探头是数字开关量,光照突变、反光都可能瞬时报"有火",必须做连续确认:

#define FLAME_CONFIRM_CNT  5     /* 连续 5 次(每次间隔 20ms)才确认 */

u8 Flame_Detected(void)
{
    static u8 cnt = 0;
    if (FLAME_READ() == 0) {         /* 探测到火焰,OUT 拉低 */
        if (++cnt >= FLAME_CONFIRM_CNT) {
            return 1;
        }
    } else {
        cnt = 0;                     /* 断一次就清零重来 */
    }
    return 0;
}

4.5 关键子程序四:MQTT 报警上报与阈值下发

STM32 端走阿里云三元组连接(ProductKey/DeviceName/DeviceSecret),发布属性上报主题、订阅阈值设置主题:

/* 属性上报:JSON 物模型格式 */
void Report_Status(void)
{
    sprintf(mqtt_txbuf,
        "{\"id\":%d,\"params\":{\
        \"Temp\":%d.%d,\"Humi\":%d,\
        \"Smoke\":%d,\"Flame\":%d,\
        \"FanSwitch\":%d,\"Alarm\":%d}}",
        ++pkg_id, temp / 10, temp % 10, humi,
        smoke, flame, fan_on, alarm);
    AliIoT_Publish(PROP_POST_TOPIC, mqtt_txbuf);
}

/* 订阅回调:解析 APP 下发的阈值/风扇指令 */
void MQTT_Rx_Parse(u8 *payload)
{
    int v;
    if (sscanf((char *)payload, "{\"SmokeTh\":%d", &v) == 1) {
        g_smoke_th = v;                 /* 烟雾阈值 */
    } else if (sscanf((char *)payload, "{\"FanSwitch\":%d", &v) == 1) {
        Relay_Set(v);                   /* APP 手动控风扇 */
    }
}

协议一致性大坑:原文 4.3 节写的流程是 AT+CIPSEND 进 TCP 透传、连"TCP 服务器";到 4.5 节和附录代码又变成了 MQTT + 阿里云物模型。TCP 透传和 MQTT 是两套完全不同的东西(前者只是"管道",后者是带主题/订阅的协议),论文里混着写,答辩一问就穿帮。本文按代码实际情况统一为 MQTT。

五、系统调试验证

测试项方法预期结果
DHT11 数据与温度计对照误差 ±2°C 内,OLED 正常刷新
MQ-2 响应香烟烟雾/酒精棉靠近读数明显上升,超阈值蜂鸣器+LED 报警
火焰检测打火机 30cm 外点火5 次确认后报警,打火机熄灭后 1s 内解除
排风控制温度加热到阈值以上继电器吸合风扇启动
阈值设置按键 / APP 分别改阈值OLED 与云端同步更新
APP 推送触发烟雾报警3 秒内 APP 收到报警消息
断网恢复关路由器 30s 再开ESP8266 自动重连并续传
误报测试台灯/手机闪光灯照火焰探头不报警(确认逻辑生效)

六、常见坑汇总(原文翻车实录)

  1. TEMT6000 被当"红外火焰传感器":它是环境光照度传感器(峰值 570nm 可见光),不是火焰传感器。火焰检测请用 YG1006 类红外火焰探头或紫外传感器。
  2. 选型、代码、图三张皮:选型写 TEMT6000,附录代码初始化 E18_D80_Init()(E18-D80 是 2~15cm 漫反射接近开关)。实际做哪个就写哪个。
  3. 选型结论张冠李戴:无线通信方案1 是 RFM95W、方案2 是 ESP8266,结论却写"选择方案1,ESP8266-01S"。
  4. "灭火"功能只活在文字里:方案描述写"触发声光报警提醒并灭火",整套硬件里没有任何灭火执行器,纯属纸面功能。论文别写硬件做不到的事。
  5. TCP 透传与 MQTT 混用:4.3 节 AT 透传连 TCP 服务器,4.5 节和代码却是 MQTT 阿里云,前后矛盾。
  6. DHT11 占 PC15 还同时保留 RTC 晶振:PC14/15 是 LSE 引脚,二者只能取其一。
  7. while(DHT11_Init()){} 死等:传感器离线时整机卡死,报警功能形同虚设。
  8. 参考文献凑数:后 6 条引用是"织物火灾报警材料"“英格兰住宅火灾流行病学”“液晶弹性体驱动器”"气凝胶复合材料"等材料学论文,与单片机系统设计毫无关系,一眼假。
  9. 研究现状人物泛化:MIT 约翰·卡特、汉斯·施泰纳、山本健一、清华刘志强……名字具体但查无实据,疑似编造,答辩被追问细节会很被动。
  10. 细节硬伤:OLED12864 写成"2.6 英寸"(实际 0.96 寸);图注出现"图4. SEQ 图4. * ARABIC 1"这种域代码没刷新的痕迹,交稿前记得全选 F9 更新域。

七、可扩展方向

  • 多节点组网:一台主机 + ESP-NOW/LoRa 多个探测分机,覆盖多房间;
  • 联动执行:继电器扩展接电磁阀(切断燃气)+ 排烟风机,把"报警系统"升级为"联动处置系统"(但论文就别再吹"灭火"了,除非真做);
  • NB-IoT 版本:换成 BC26 模块,摆脱家庭 Wi-Fi 依赖,适合仓库等无路由器场景;
  • 数据上云看板:阿里云 IoT Studio 拖一个 Web 可视化大屏,展示历史曲线,答辩演示效果拉满。

八、资料内容完整工程资料(原理图、PCB、代码、元件清单)


九、资料获取方式


Logo

智能硬件社区聚焦AI智能硬件技术生态,汇聚嵌入式AI、物联网硬件开发者,打造交流分享平台,同步全国赛事资讯、开展 OPC 核心人才招募,助力技术落地与开发者成长。

更多推荐