我用两个打火机,把i.MX6ULL变成了火灾预警系统
2026/7/4 4:00:20 网站建设 项目流程
title: 我给物联网系统加上了「眼睛」—— i.MX6ULL AI火灾检测 + 多传感器融合(开源更新) date: 2026-06-30 categories: 嵌入式开发 tags: [i.MX6ULL, YOLOv8, AI, 火灾检测, 嵌入式AI, 物联网, 开源]

项目地址(全部开源):https://github.com/wuqiZhu/IoTDualCtrl(13,000+ 行 C/C++)


简介

本文基于 i.MX6ULL 嵌入式 Linux 开发板,实现一套融合 YOLOv8 AI 视觉、8 类传感器加权评分的火灾预警系统,包含完整端云 MQTT 链路、状态机设计、容错机制与全流程踩坑复盘,全部代码开源。

一、这次更新了什么

上次分享了基于 i.MX6ULL 的五层物联网架构,这次给它加上了「眼睛」——AI视觉火灾检测

上次:传感器 → HAL → RPC → MQTT → 云端 → 钉钉 这次: + AI摄像头 → YOLOv8 → 融合评分 → 状态机

核心新增:

功能说明
AI火灾检测YOLOv8n + ONNX Runtime,每10秒自动拍照推理
多传感器融合评分8类信号加权投票,不依赖单一传感器
状态机SAFE→MONITOR→ALERT→COOLDOWN
时序滤波滑动窗口5帧中2帧通过才触发
深度学习训练D-Fire数据集训练YOLOv8n,导出ONNX部署
腾讯云推理服务Flask + ONNX Runtime,systemd托管

二、为什么要给物联网加AI

从烟雾传感器说起

传统烟雾传感器有一个固有问题——只能等烟飘到了才报警。仓库火灾往往是先有明火(几秒到几十秒),然后才有烟。烟雾传感器发现时,火可能已经烧起来了。

时间线: t=0 电线短路,产生火花 t=5 周围可燃物被点燃(明火) t=30 产生大量烟雾 t=60 烟雾飘到传感器位置 → 报警!← 晚了1分钟

AI视觉检测可以在明火阶段就发现火情,比烟雾传感器提前几十秒到几分钟

为什么不只靠AI

AI也有自己的问题——误报。墙上的反光、窗外的阳光、甚至是飞过的虫子,都有可能被模型误判为火焰。

AI单独:该报的报了,不该报的也报了 ← 这不行 传感器单独:有些场景报不了,报的时候已经太晚了 ← 也不行

所以需要两者融合——AI负责早期发现,传感器负责确认,互相补位。


三、多传感器融合评分(核心设计)

3.1 设计思想

不依赖任何单个传感器,所有信号加权投票

烟雾传感器报警 → +40分 AI看到明火 → +30分 温度快速上升 → +20分 湿度骤降 → +10分 ...... ​ 总分 ≥ 60 → 告警

这样就不会出现"AI误报就发钉钉"或者"烟雾传感器坏了就不报警"的问题。

3.2 信号权重表

信号权重触发条件动态修正
烟雾传感器40分GPIO读到0(报警)深夜×1.5
AI检测到fire30分conf>0.30深夜×1.5
温度上升速率20分≥2°C且>3°C/分钟夏季减半
温度>45°C15分绝对温度夏季减半
温度批量偏高2分/°C高于历史平均5°C上限20
湿度骤降10分降幅>30%/分钟-
光敏(夜间突亮)10分暗→亮夜间
光敏(白天变暗)5分持续黑暗白天
PIR有人(配合报警)5分+烟雾/AI同时-
并发倍率×1.5≥2个高权重信号同时触发

深夜0-6点所有权重×1.5,因为夜间无人值守,更警惕是合理的。

3.3 一个实际的例子

昨天测试时的一个真实场景——打火机测试:

第1次AI拍照:没看到火 → 不触发 第2次AI拍照:看到火 conf=0.46 → +30分 → 进入MONITOR 第3次AI拍照:看到火 conf=0.32 → +30分 → 总分 30×0.95+30 = 58 → 还差2分 第4次AI拍照:看到火 conf=0.30 → +30分 总分 58×0.95+30 = 85 → ALERT → 钉钉

从点火到告警,约30秒

如果打火机同时靠近烟雾传感器,两个信号并发触发:

烟雾+40 + AI+30 = 70 并发倍率 ×1.5 = 105 → 一次达到ALERT

3.4 衰减规则

每5秒:累积分 × 0.95 连续60秒无新信号:清零

这样短暂的事件(比如一个人走过被AI误判)不会长期影响分数,持续的事件(真火)可以稳定积累。

3.5 状态机

有可疑信号 评分≥60 30秒后 30秒后 SAFE ───────────→ MONITOR ───────────→ ALERT ──────────→ COOLDOWN ──────────→ SAFE ↑ │ │ └── 60秒无确认 ───┘ └── 恢复正常 ──────────────────────┘
状态行为
SAFE正常监控,不做任何操作
MONITOR关注但不告警,记录数据
ALERT发钉钉 + 开风扇 + 拍照上传
COOLDOWN冷却,防止重复告警

四、AI模型的选型与训练

4.1 模型选择

YOLOv8n,参数量3.0M,模型仅6MB。选择它的原因:

因素说明
轻量3M参数,适合边缘部署
精度COCO mAP 37.3,足够火灾检测
生态ONNX导出方便,跨平台推理
速度CPU上~500ms/帧,满足10秒检测周期

4.2 数据集:D-Fire

使用D-Fire公开数据集训练。选择它而非其他数据集的原因:

数据集类别特点
D-Firefire + smoke只有2类,无干扰类别
NEWFire2fire + smoke + otherother类干扰严重
Roboflow通用多种场景不够聚焦

第一版用的 NEWFire2 有 "other" 类,模型把所有前景都标为 smoke,fire 类完全学不到。换 D-Fire 后问题解决。

D-Fire 包含约 21,000 张图像:

类别标注框数
fire14,692
smoke11,865

4.3 训练过程

# 训练平台:AutoDL RTX 4090 # 训练时长:约2.5小时 from ultralytics import YOLO model = YOLO('yolov8n.pt') model.train( data='data.yaml', epochs=100, imgsz=640, batch=16, device=0 )

验证结果:

fire: mAP50 = 66% smoke: mAP50 = 83.7%

4.4 ONNX导出与部署

model.export(format='onnx', imgsz=640)

导出后部署到腾讯云,使用 ONNX Runtime CPU推理:

session = ort.InferenceSession('fire_model.onnx') outputs = session.run(None, {input_name: preprocess(img)})

Flask服务 + systemd托管,故障自动重启。


五、解决了哪些问题

5.1 模型误报(最头疼的问题)

现象:什么都没发生,AI却检测到smoke conf=0.53,加了30分。

分析:摄像头画面左侧有个固定物体被模型误认成烟雾,20分钟内误报了7次。

解决:

  • 置信度阈值从0.15提高到0.30,过滤低置信度误报

  • AI未检出时立即清零,不留60秒残留

  • 滑动窗口5帧中2帧通过才触发,单帧误报不影响

改之前:conf=0.18 → AI加30分 → 可能误报 改之后:conf=0.18 < 0.30 → 忽略 conf=0.35 > 0.30 → AI加30分 → 但需要第二帧确认

5.2 温度噪声

现象:DHT11精度±1°C,27→28°C的正常波动被算成"温度上升6.7°C/分钟",加了20分。

解决:最低变化量≥2°C才算,排除DHT11噪声。

5.3 风扇跟评分打架

现象:ALERT状态强制开风扇,紧接着温度控制检测到<30°C又关掉,1秒内跳3次。

解决:ALERT和COOLDOWN状态下不执行温度关风扇逻辑,风扇保持运行。

5.4 评分算完了没人用

现象:融合评分算了一堆分数,但烟雾传感器该告警还是直接告警,评分是个玩具。

解决:评分直接决定是否进入ALERT状态,不再让传感器直接触发告警。

5.5 板子时间不对

现象:板子用的是UTC时间,深夜权重判定不准,PIR半夜不加分。

解决:设置时区为Asia/Shanghai,写入/etc/profile永久生效。


六、哪些做得还不够(坦诚说)

说完了做到的,也该说说没做到的:

问题原因如果能重来
对小火焰识别不稳定D-Fire数据集大火场景多,小火苗样本少采集仓库场景数据微调
AI推理在云端i.MX6ULL没有NPU换RK3588等带NPU的板子
温湿度精度差DHT11 ±1°C换成SHT30
单摄像头只能管一个角度支持多路RTSP
光敏/湿度通道不完善改动量大,优先级低加基线学习
无数据闭环误报/漏报无法反馈Web加反馈按钮

这些不是没想过,是做不完。一个人做项目总得有取舍,我把优先级给了最核心的检测链路。


七、项目结构(更新后)

lesson5/rpc_server/ RPC服务 + HTTP管理 + 摄像头驱动 lesson6/ MQTT桥接 + AI检测 + 融合评分 ├── mqtt_bridge.cpp 主程序(~1900行,4线程) ├── config.c/h 配置管理 ├── rpc_client.cpp RPC通信 └── *.c 看门狗、日志、OTA等 cloud/ 云端服务 ├── mqtt_to_influxdb.py MQTT→InfluxDB + 钉钉 └── fire_server.py AI推理服务 ← 新增 config.json 配置文件(阈值、权重等)

八、一点感想

这个项目从5月开始,到今天刚好两个月。

第一个月搭了IoT五层架构——从HAL到RPC到MQTT到云端Grafana。那时候觉得"传感器采集+上云"已经是个完整的项目了。

第二个月加了AI——训练模型、搭推理服务、写融合评分、调参、降误报。才发现前面说"完整"说早了。

最大的收获不是技术,是学会取舍。两个月里想加的东西很多:多摄像头、本地NPU推理、数据闭环。但一个人做项目,时间和精力就那么多,必须选最核心的先做。

代码全部开源,GitHub 13,000+ 行 C/C++,ARM开发板上跑通。

如果对你有帮助,GitHub 点个 Star ⭐

项目地址:https://github.com/wuqiZhu/IoTDualCtrl

九、工程实现深度问答

1. 怎么解决火焰传感器误告警的问题?

答:单一火焰传感器容易受强光、打火机短暂火光干扰,我采用了多维度加权判定策略:火焰传感器信号占40分、温度上升速率占20分、图像火焰识别占30分、环境湿度负向加权。总分≥60分才触发正式告警,同时加入时间衰减机制:每5秒分数衰减5%,60秒无新触发信号直接清零。夜间环境光线稳定时,传感器权重上调;白天强光环境下,视觉识别权重提升,从根源降低误报率。

2. 网络断开后,告警数据会不会丢失?

答:不会丢失。本地实现了环形缓冲区缓存机制,最多可存储100条告警数据,断网期间所有传感器数据、告警日志都写入缓存;网络恢复后自动按时间顺序补传,保证数据完整性。图片上传做了双通道降级:优先HTTP直传,失败则自动转为MQTT Base64分片传输,30秒超时仍失败则保留本地旧图兜底,下次网络恢复重传。

3. 开发中遇到过最棘手的bug是什么?

答:继电器频繁异常跳变。最初逻辑是烟雾触发开风扇、温度达标关风扇,两个条件独立运行,导致1秒内继电器反复吸合3次。排查两天定位到根源:风扇关闭计时变量初始值为0,判断条件`当前时间 >= 关闭时间`永远成立。最终修复了三层保护:烟雾告警期间屏蔽温度控制逻辑、温度未降到安全值不关闭风扇、定时器到期强制重置标志位,彻底解决了继电器抖动问题。

4. V4L2采集图像有没有遇到问题?

答:遇到过首帧黑屏、帧延迟两个主要问题。首帧黑屏是因为摄像头启动需要曝光时间,解决方案是丢弃前3帧数据,从第4帧开始正式采集;帧延迟通过内存映射(mmap)方式采集、双缓冲队列轮换处理,保证告警抓拍的实时性,从触发到图片上传完成控制在2秒以内。


作者:朱相波 | 长春大学旅游学院 物联网工程 大三求职方向:嵌入式软件 / Linux 应用开发

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询