尧图建网站 尧图建网站 YAOTU WEB BUILD 免费咨询
ARTICLE DETAIL

资讯详情

深耕网站建设与建站编程的一线实战洞察。

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

零知派——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 参数调优六、常见问题 FAQQ1灭火模式下小车不执行灭火动作但指示灯亮了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 型用于调节火焰检测的阈值电压从而改变检测灵敏度调节方向阈值变化检测效果顺时针旋转参考电压降低更灵敏检测更远火焰但易误触发逆时针旋转参考电压升高更不灵敏只检测强火焰抗干扰强实际调试方法将火源放在传感器正前方约 30cm 处慢慢旋转电位器观察模块上的状态指示灯找到指示灯在“有火源”和“无火源”之间刚好切换的临界点再往灵敏方向回调一点顺时针约 1/8 圈三、硬件接线说明3.1 引脚定义本项目三个模块的引脚定义与pinsdefine.h一致#define FAN_PIN 22 // 风扇装在车身左中部 #define FLAME_PIN 23 // 火焰传感器装在车尾左侧 #define DHT11_PIN 27 // DHT11 单总线数据脚3.2 接线方案表模块引脚零知派迷你板引脚说明DHT11VCC5V供电3~5.5VDHT11GNDGND共地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移动速度动作更快但可能吹动火焰更平稳但移动慢六、常见问题 FAQQ1灭火模式下小车不执行灭火动作但指示灯亮了A_st 状态标志没有被正确设置火焰检测的极性判断错误。确认 EnvSensor::flameDetected() 返回值正确检测到火焰返回 true。串口打印 _st 值确认状态机是否正确进入 FIRE_BACKQ2灭火模式中火焰熄灭后风扇不关闭ANO_FLAME_MS 3000 意味着需要连续 3 秒未检测到火焰才判定灭火成功。如果传感器偶尔误读到火焰会重置计时器。确认火焰传感器没有误触发适当降低 NO_FLAME_MS灭火模式是整个项目中唯一一个“用户驾驶为主、代码自动干预为辅”的混合模式——小车平时由用户遥控行驶只有检测到火焰时才会自动介入执行灭火动作灭火完成后立即归还控制权。这种“人机协同”的设计思路在其他模式循迹、避障、跟随中是见不到的是一个非常典型的“人机协同”嵌入式设计
返回列表