当前位置: 首页 > news >正文

零知派——STM32智能小车系列教程(五):DHT11温湿度、火焰传感器与风扇灭火模块原理及调试

引言:智能小车要实现的功能很多——避障、跟随、贴边、灭火、直线行驶,每一个模块单独调试起来都有自己的难点。如果一开始就把所有模块塞进一个工程里联调,出了问题很难分清到底是传感器硬件的问题、电平极性的问题,还是上层控制算法的问题

所以这一系列教程的思路是:先把每个功能模块单独拎出来,配一个不依赖其他硬件的最小测试程序,把模块本身调通调透,再回头看它在完整项目里是怎么被使用的

目录

一、引言

二、模块硬件原理

2.1 DHT11单总线通信协议

2.1.1 完整通信时序

2.1.2 数据格式

2.2 红外火焰传感器原理

2.2.1 火焰传感器工作原理

2.2.2 灵敏度调节

三、硬件接线说明

3.1 引脚定义

3.2 接线方案表

3.3 连接示意图

四、独立测试程序

4.1 调试流程

4.2 视频演示

五、整车项目灭火模式实现

5.1 灭火模式状态机

5.2 关键设计细节

5.3 参数调优

六、常见问题 FAQ

Q1:灭火模式下小车不执行灭火动作,但指示灯亮了?

Q2:灭火模式中,火焰熄灭后风扇不关闭?


一、引言

前面四篇讲的都是“运动控制”相关的模块——循迹让小车知道“路在哪”、超声波让小车知道“障碍在哪”、红外让小车知道“目标在哪”、编码器让小车知道“跑多快”。这一篇转向“环境感知与执行”——检测环境温度湿度、检测火焰、控制风扇灭火

灭火模式在整个项目中的定位与其他模式完全不同

特性其他模式(循迹/避障/跟随等)灭火模式
控制权完全由代码自动控制手动遥控为主,代码自动干预为辅
触发方式进入模式即开始自动运行由用户遥控驾驶,检测到火焰时自动接管
退出方式切换模式退出火焰熄灭3秒后自动归还控制权
用户交互不需要用户随时可用方向键控制移动

这种“用户驾驶 + 自动灭火”的混合设计思路——小车平时由用户遥控行驶,只有检测到火焰时才自动干预执行灭火动作,灭火完成后立即归还控制权——是嵌入式项目中“人机协同”的一个典型实例

这个系列教程拆成以下几篇:

篇号主题核心硬件
第一篇(已完成)五路循迹模块TCRT5000 + LM393/LM339
第二篇(已完成)HC-SR04超声波+SG90舵机云台HC-SR04 + SG90
第三篇(已完成)红外双目跟随模块红外避障对管
第四篇(已完成)红外对射式测速+直线行驶PID闭环槛型红外计数模块+码盘+PID
第五篇(本文)DHT11温湿度、火焰传感器、风扇灭火DHT11+火焰传感器+风扇
第六篇(待更新)蓝牙/串口双通道通信协议HC-05/BT06
终篇(待更新)整车项目架构总览全模块整合

二、模块硬件原理

本篇涉及三个独立硬件:DHT11负责测环境温湿度(本项目里主要作为状态展示,不直接参与灭火决策)、红外火焰传感器负责判断"有没有火",风扇负责执行"吹灭"这个物理动作

模块核心元件输出类型
DHT11电阻式湿敏元件+NTC温敏元件+8位单片机单总线数字信号,40bit一次完整数据
红外火焰传感器红外接收管(对760~1100nm波段敏感)+LM393比较器数字开关量,检测到火焰输出低电平
风扇直流电机+扇叶单路开关控制(本项目未做调速)

三者各自独立工作,靠代码逻辑串联成一套完整流程

2.1 DHT11单总线通信协议

2.1.1 完整通信时序

DHT11采用单总线(Single-bus)通信,一根数据线既传输命令也传输数据,靠严格的时序约定区分不同信号

起始信号

主机(开发板)接入数据线的I/O输出低电平,且低电平保持时间不能小于 18ms

响应信号

等待模块的响应信号到来。将数据线改为输入模式,如果接入到低电平,说明接收到模块的响应

数据传输

主机接收模块发送的40位数据,其中,位数据 ‘0’ 表示54us的低电平,27us的高电平;位数据 ‘1’ 表示54us的低电平,74us的高电平

两个格式的分辨主要是高电平的输出时长不同

结束信号

模块的数据线输出 40 位数据后,是以低电平结束,它会继续输出低电平 54 微秒后转为输入状态,主机需要转为输出状态,输出高电平释放总线

2.1.2 数据格式

完整的一次数据传输是40位,格式是8位湿度整数数据+8位湿度小数数据+8位温度整数数据+8位温度小数数据+8位校验位

0011 01010000 00000001 10000000 01000101 0001
湿度高8位湿度低8位温度高8位温度低8位校验位

校验和计算:0011 0101 + 0000 0000 + 0001 1000 + 0000 0100 = 0101 0001,与接收的数据一致

数据时序图

高位先发送,对DHT11来说湿度小数字节和温度小数字节固定为0,校验位是前四个字节相加后取低8位

2.2 红外火焰传感器原理

2.2.1 火焰传感器工作原理

火焰燃烧时会释放特定波长的红外线,火焰传感器中的红外光电三极管接收到红外辐射后,其集电极电流随光强增加而增大,通过 LM393 比较器与预设阈值比较后输出数字电平

与循迹模块 TCRT5000 的红外检测有何不同

对比项TCRT5000 循迹模块火焰传感器
检测对象反射回来的红外光主动发射的红外光
检测原理发射→反射→接收接收环境中的红外辐射
检测距离1~2.5cm0.3~3m
检测角度窄(约 15°)宽(约 60°)
核心用途近距离检测地面颜色远距离检测火源

区别:TCRT5000 需要主动发射红外光然后接收反射光,而火焰传感器只接收不发射——它被动接收火焰燃烧产生的红外辐射。这个区别决定了火焰传感器的检测距离远(可达数米),但也会被阳光、热源等其他红外辐射源干扰

2.2.2 灵敏度调节

模块上那颗蓝色方形可调电位器(3296 型)用于调节火焰检测的阈值电压,从而改变检测灵敏度

调节方向阈值变化检测效果
顺时针旋转参考电压降低更灵敏(检测更远火焰,但易误触发)
逆时针旋转参考电压升高更不灵敏(只检测强火焰,抗干扰强)

实际调试方法

  1. 将火源放在传感器正前方约 30cm 处
  2. 慢慢旋转电位器,观察模块上的状态指示灯
  3. 找到指示灯在“有火源”和“无火源”之间刚好切换的临界点
  4. 再往灵敏方向回调一点(顺时针约 1/8 圈)

三、硬件接线说明

3.1 引脚定义

本项目三个模块的引脚定义(与pinsdefine.h一致):

#define FAN_PIN 22 // 风扇(装在车身左中部) #define FLAME_PIN 23 // 火焰传感器(装在车尾左侧) #define DHT11_PIN 27 // DHT11 单总线数据脚

3.2 接线方案表

模块引脚零知派迷你板引脚说明
DHT11VCC5V供电3~5.5V
DHT11GNDGND共地
DHT11DATAD27单总线数据脚,模块内部已带上拉电阻
火焰传感器VCC3.3V或5V
火焰传感器GNDGND共地
火焰传感器DOD23检测到火焰输出低电平
风扇模块VCC5V/独立电源风扇启动瞬间电流较大,建议独立供电
风扇模块GNDGND共地
风扇模块IND22高电平开启

3.3 连接示意图

风扇启动瞬间电流较大,建议单独供电或确保 5V 电源有足够的余量(≥1A),避免影响主控芯片工作

四、独立测试程序

在整合到整车项目之前,先用下面这个程序单独验证火焰传感器和风扇的功能:

/************************************************************************************** * 文件: Fire_Extinguish_Standalone_Test.ino * 作者:零知实验室(深圳市在芯间科技有限公司) * 功能:火焰传感器 + 风扇灭火 独立测试程序 * 不依赖其他硬件,用于验证火焰检测灵敏度和风扇控制 * * 引脚(与主项目 pinsdefine.h 完全一致): * FLAME_PIN = D23 * FAN_PIN = D22 * * 串口命令(波特率115200): * f 手动开关风扇(切换状态) * s 打印一次温湿度(DHT11) * t 火焰检测灵敏度测试模式(连续监测) * h 打印帮助信息 * * 使用方法: * 1. 烧录本程序到零知派迷你板 * 2. 打开串口监视器,波特率115200 * 3. 用打火机(不点燃)或手机闪光灯作为火源 * 4. 在不同距离测试火焰检测的灵敏度 **************************************************************************************/ #include <SimpleDHT.h> #define FLAME_PIN 23 #define FAN_PIN 22 #define DHT11_PIN 27 SimpleDHT11 dht11(DHT11_PIN); // ── 状态变量 ────────────────────────────────────────────────────── bool fanState = false; // false=关, true=开 bool testMode = false; // false=命令模式, true=持续监测模式 unsigned long lastFlameDetectedMs = 0; // ── 串口命令处理 ────────────────────────────────────────────────── void printHelp() { Serial.println(F("========================================")); Serial.println(F(" 火焰传感器 + 风扇 独立测试程序")); Serial.println(F("========================================")); Serial.println(F(" 命令:")); Serial.println(F(" f 手动开关风扇")); Serial.println(F(" s 读取并打印温湿度")); Serial.println(F(" t 进入/退出持续监测模式")); Serial.println(F(" h 打印本帮助信息")); Serial.println(F("")); Serial.println(F(" 当前状态:")); Serial.print(F(" 火焰检测: ")); Serial.println(digitalRead(FLAME_PIN) == LOW ? "有火焰 (LOW)" : "无火焰 (HIGH)"); Serial.print(F(" 风扇状态: ")); Serial.println(fanState ? "ON" : "OFF"); Serial.println(F("========================================")); } void handleCommand(String cmd) { cmd.trim(); if (cmd.length() == 0) return; if (cmd == "f") { fanState = !fanState; digitalWrite(FAN_PIN, fanState ? HIGH : LOW); Serial.print(F("[FAN] ")); Serial.println(fanState ? "ON" : "OFF"); return; } if (cmd == "s") { byte temp = 0, humi = 0; int err = dht11.read(&temp, &humi, nullptr); if (err != SimpleDHTErrSuccess) { Serial.print(F("[DHT] 读取失败 err=")); Serial.println(err); if (err == SimpleDHTErrStartLow) { Serial.println(F("[DHT] 提示:DHT11 需要至少 1s 采样间隔")); } } else { Serial.print(F("[DHT] 温度=")); Serial.print((int)temp); Serial.print(F("°C 湿度=")); Serial.print((int)humi); Serial.println(F("%RH")); } return; } if (cmd == "t") { testMode = !testMode; Serial.print(F("[TEST] ")); Serial.println(testMode ? "持续监测模式 ON" : "持续监测模式 OFF"); return; } if (cmd == "h") { printHelp(); return; } Serial.print(F("[WARN] 未知命令: ")); Serial.println(cmd); } // ── 火焰检测封装 ────────────────────────────────────────────────── bool flameDetected() { return (digitalRead(FLAME_PIN) == LOW); } // ── setup ───────────────────────────────────────────────────────── void setup() { Serial.begin(115200); delay(200); pinMode(FLAME_PIN, INPUT_PULLUP); pinMode(FAN_PIN, OUTPUT); digitalWrite(FAN_PIN, LOW); Serial.println(F("========================================")); Serial.println(F(" 火焰传感器 + 风扇 独立测试程序")); Serial.println(F(" 波特率:115200")); Serial.println(F(" 命令:f(开关风扇) s(读温湿度) t(监测模式) h(帮助)")); Serial.println(F("========================================")); Serial.println(F("提示:火焰传感器检测到火焰时 DO 输出 LOW")); Serial.println(F("")); } // ── loop ────────────────────────────────────────────────────────── void loop() { // ── 串口命令 ────────────────────────────────────────────────── while (Serial.available()) { String cmd = Serial.readStringUntil('\n'); handleCommand(cmd); } // ── 持续监测模式 ───────────────────────────────────────────── if (testMode) { bool flame = flameDetected(); static bool lastFlame = false; if (flame != lastFlame) { lastFlame = flame; Serial.print(F("[FLAME] ")); Serial.println(flame ? "检测到火焰!" : "无火焰"); } // 检测到火焰时自动开启风扇(模拟灭火) if (flame) { if (!fanState) { fanState = true; digitalWrite(FAN_PIN, HIGH); Serial.println(F("[AUTO] 火焰检测触发 → 风扇 ON")); } lastFlameDetectedMs = millis(); } else { // 连续3秒无火焰则关闭风扇 if (fanState && (millis() - lastFlameDetectedMs > 3000)) { fanState = false; digitalWrite(FAN_PIN, LOW); Serial.println(F("[AUTO] 连续3秒无火焰 → 风扇 OFF")); } } delay(50); } else { // 命令模式下,每隔1秒打印一次火焰状态(非侵入式) static unsigned long lastPrintMs = 0; if (millis() - lastPrintMs >= 1000) { lastPrintMs = millis(); Serial.print(F("[MONITOR] 火焰=")); Serial.print(flameDetected() ? "有" : "无"); Serial.print(F(" 风扇=")); Serial.println(fanState ? "ON" : "OFF"); } delay(100); } }

4.1 调试流程

①打开串口监视器

显示帮助信息和当前状态,发送t进入持续监测模式,串口实时打印火焰状态变化

②靠近火焰传感器

检测到火焰时自动开启风扇,移开光源等待 3 秒,风扇自动关闭

③发送s读取温湿度

打印当前温湿度数值,发送f手动开关风扇,风扇 ON/OFF 切换

4.2 视频演示

火焰传感器+风扇灭火模块独立测试

输入h展示当前实时状态,用打火机在远、中、近三个距离依次靠近传感器,配合t模式下[FLAME]边沿触发提示和[AUTO]自动开关风扇的串口输出同框录制,重点展示"检测到火焰立刻响应、拿开后延迟3秒才关闭"这个防抖设计的实际效果。切到s命令读取温湿度,展示正常读数和"采样间隔不足"报错两种情况的对比

五、整车项目灭火模式实现

5.1 灭火模式状态机

整车项目中,FireBehavior类实现了完整的灭火状态机

四种状态

enum FireState : uint8_t { FIRE_IDLE, // 空闲态:遥控驾驶,后台监测火焰 FIRE_BACK, // 倒车靠近火源 FIRE_PAUSE, // 停车吹风 FIRE_FORWARD // 前进离开 };

状态转换图

5.2 关键设计细节

①全局火焰监测(独立于状态)

bool flame = g_env.flameDetected(); if (flame) _lastFlameMs = millis();

无论当前处于哪个子状态,每帧都会检查火焰检测状态,并更新_lastFlameMs(最后一次检测到火焰的时间戳)。

② 灭火成功的判定条件

if (_st != FIRE_IDLE && (millis() - _lastFlameMs > NO_FLAME_MS)) { // 连续3秒未检测到火焰 → 判定灭火成功 g_env.setFan(false); g_motor.stop(); _st = FIRE_IDLE; }

只有在非 IDLE 状态下才进行这个判断(IDLE 时本来就没有火焰,不需要判定),避免逻辑混乱。

③ 反复灭火机制

case FIRE_FORWARD: if (millis() - _ts > FORWARD_MS) { g_motor.stop(); if (flame) { // 火焰还在 → 继续倒车吹风 g_motor.motorRun(-BACK_SPEED, -BACK_SPEED); _st = FIRE_BACK; _ts = millis(); } else { _st = FIRE_IDLE; } } break;

前进阶段结束后,如果还检测到火焰,会自动回到FIRE_BACK继续灭火,形成往复循环,直到火焰完全熄灭。

④ 手动驾驶控制权

sc_comms.cpp中的parseCmd()函数将MODE_FIRE加入了方向键白名单

if (g_mode == MODE_MANUAL || g_mode == MODE_STRAIGHT || g_mode == MODE_FIRE) { switch (c) { case '1': g_motor.goWithDirec(carForward); break; case '2': g_motor.goWithDirec(carBack); break; // ... 方向键处理 } }

FIRE_IDLE状态下,用户可以自由遥控驾驶小车。检测到火焰时,代码自动接管控制权执行灭火,灭火完成后自动归还控制权

5.3 参数调优

灭火模式的参数定义

static const long BACK_MS = 500; // 倒车靠近火源的时长 static const long PAUSE_MS = 800; // 停留吹风时长 static const long FORWARD_MS = 500; // 前进离开的时长 static const long NO_FLAME_MS = 3000; // 连续多久未检测到判定灭火成功 static const int BACK_SPEED = 60; // 倒车/前进速度

调参建议

参数作用调大效果调小效果
BACK_MS倒车时长风扇更靠近火源,但可能撞墙离火源较远,效果可能差
PAUSE_MS吹风时长灭火更彻底,但耗时更长响应更快,但可能吹不灭
NO_FLAME_MS判定灭火的等待时间更稳定,避免误判响应更快,但可能误判
BACK_SPEED移动速度动作更快,但可能吹动火焰更平稳,但移动慢

六、常见问题 FAQ

Q1:灭火模式下小车不执行灭火动作,但指示灯亮了?

A:_st 状态标志没有被正确设置,火焰检测的极性判断错误。确认 EnvSensor::flameDetected() 返回值正确,检测到火焰返回 true。串口打印 _st 值,确认状态机是否正确进入 FIRE_BACK

Q2:灭火模式中,火焰熄灭后风扇不关闭?

A:NO_FLAME_MS = 3000 意味着需要连续 3 秒未检测到火焰才判定灭火成功。如果传感器偶尔误读到火焰,会重置计时器。确认火焰传感器没有误触发,适当降低 NO_FLAME_MS

灭火模式是整个项目中唯一一个“用户驾驶为主、代码自动干预为辅”的混合模式——小车平时由用户遥控行驶,只有检测到火焰时才会自动介入执行灭火动作,灭火完成后立即归还控制权。这种“人机协同”的设计思路在其他模式(循迹、避障、跟随)中是见不到的,是一个非常典型的“人机协同”嵌入式设计

http://www.jsqmd.com/news/1345494/

相关文章:

  • 许昌亚克力注塑厂家怎么选?看清材料特性、精度要求、模具投入和量产稳定性 - 中国品牌企业观察网
  • Linux基础学习记录
  • GitLab安全加固实战:从HTTP迁移到HTTPS的完整配置与排坑指南
  • 2026年露营团建如何实现休闲与团建双效合一 - 万相科技
  • 2026年最新苏州geo优化公司——行业白皮书:选型避坑与推荐 - 天下观知
  • 从角色设定到情感工程:拆解“美强惨”叙事的技术化创作流程
  • 2026北京房山透明家装实测:三家装企**与口碑解析 - 2027品牌AI展
  • 2026年拼装罐靠谱厂家** 实用推荐指南 - 奔跑123
  • Python Pygame实现FPS射击游戏:子弹轨迹、碰撞检测与动态弹孔效果
  • Unity异步配置加载实战:基于UniTask与JSON的高效数据管理方案
  • 外文人工翻译服务平台测评 - 逢君学术-AI论文写作
  • 北京特别纳税调整:关联交易申报与同期资料准备评测 - 律师律所推荐
  • Unity InputField焦点与光标控制优化:解决UGUI输入框交互难题
  • Debian正则表达式实战:核心用法与性能优化
  • 2026年油性头皮控油洗发水**单:皮肤科医生力荐的安心选择 - 产品评测官
  • 银行流水翻译如何办理?银行流水翻译线上申报步骤是什么?零跑腿攻略! - 实用干货补给站
  • 从Skill使用者到创造者:手把手教你编写规范的AI Agent技能
  • 陕西报考指导、事业单位培训、留学生就业机构怎么选?2026年本地人力资源服务深度分析 - 优质品牌商家
  • 郑州食品厂卫生设备选型参考:为什么一站式供应商值得优先考虑? - 中国品牌企业观察网
  • 肉鸡服务器:从概念到防御的网络安全实战指南
  • 武汉高性价比不等于廉价,武汉配眼镜要看这三点 - 配眼镜新资讯
  • Godot GDScript自动化工作流:代码格式化、静态检查与CI/CD集成实践
  • 深圳报废设备回收与不锈钢废铁回收企业怎么选?2026年靠谱服务商参考 - 优质品牌商家
  • 从零搭建智能QQ机器人:Astrbot框架与Napcat协议集成大模型API
  • 郑州食品厂人员卫生消毒工程设计避坑指南:从更衣室改造到审核通过的完整方案 - 中国品牌企业观察网
  • 2026年复合材料门窗设备厂家哪家好?济南西格玛数控设备|20年门窗设备制造商 - 米諾
  • AI工具助力论文写作:8款神器提升效率
  • 临沂市宠物加厚尿片厂家推荐,狗狗除臭尿片厂家哪家好?2026避坑指南:4个坑+5条硬标准,一篇讲透 - geo88
  • 2026猎头合作平台哪家好:十大靠谱平台与猎企协同能力**盘点 - 阿辰运营笔记
  • AI Agent编排平台Ruflo:让Claude Code从代码生成器进化为自主软件工程师