首页 / 资讯中心 / 文章详情

STM32+WiFi物联网环境检测节点:烟雾粉尘噪音远程监控实战

STM32+WiFi物联网环境检测节点:烟雾粉尘噪音远程监控实战 ★ FEATURED ARTICLE
1. 为什么我要做这个环境检测节点前阵子有个做工厂安全管理的朋友找我说车间里粉尘大、噪音吵工人反映不舒服但管理层看不到数据也没法量化到底哪个时段、哪个区域超标。他问我能不能搞一个便宜、能联网、能实时看数据的检测设备。我第一反应就是STM32加WiFi模块传感器用现成的烟雾、粉尘、噪音三合一方案数据直接推到云平台手机和电脑都能看曲线。这个项目说白了就是一个环境检测物联网节点STM32做主控采集烟雾浓度、粉尘浓度、噪音分贝三个核心指标通过WiFi模块把数据上传到云平台实现远程监控、历史查询和超标告警。它解决的核心问题是——把看不见的环境风险变成看得见的数据让管理者能追溯、能预警、能决策。适合谁来参考如果你有STM32基础玩过串口和GPIO想入门物联网项目这个方案非常合适。如果你是纯小白也没关系我会把每个环节拆开讲包括传感器选型、接线、代码逻辑、云平台配置甚至踩过的坑都给你标出来。整套硬件成本控制在百元级别复现门槛不高。我实测下来这套方案在室内环境下数据稳定性不错连续跑一周没掉线。下面我把整个项目的设计思路、核心细节、实操过程和排查经验完整分享出来你照着做基本能一次跑通。2. 整体方案设计与选型思路2.1 系统架构怎么搭整个系统分三层感知层、控制层、云端层。感知层就是三个传感器负责把物理量转成电信号控制层是STM32负责采集、处理、打包数据云端层是WiFi模块加云平台负责传输、存储、展示。数据流向是这样的传感器输出模拟或数字信号STM32的ADC或外部中断读取经过滤波和换算得到实际物理值再通过串口发给WiFi模块WiFi模块以MQTT协议推送到云平台云平台做数据存储和可视化用户在网页或App上查看。为什么选MQTT而不是HTTP因为MQTT是长连接、轻量级、开销小适合这种周期性上报小数据的场景。HTTP每次都要建连接功耗和流量都浪费。实测下来MQTT在STM32这种资源有限的平台上跑起来更顺畅。2.2 主控为什么选STM32市面上主控很多ESP32自带WiFi更省事但我还是选了STM32加独立WiFi模块的方案。原因有几个第一STM32的ADC精度和稳定性更好粉尘和噪音信号对采样要求高第二STM32生态成熟资料多出问题好查第三独立WiFi模块可以灵活更换不会被主控绑定。具体型号我用的STM32F103C8T6也就是常说的“最小系统板”72MHz主频64KB Flash20KB RAM资源够用价格便宜。如果你手头有F4系列也完全可以性能更充裕。2.3 三个传感器怎么选传感器是整个项目的眼睛选错了后面全白搭。我逐个说。烟雾传感器我选的是MQ-2。它对液化气、丙烷、氢气、烟雾都有响应模拟输出接STM32的ADC引脚。优点是便宜、通用缺点是预热时间长大概要预热20秒以上数据才稳定而且受温湿度影响。粉尘传感器我选的是GP2Y1010AU0F夏普那款光学粉尘传感器。它内部有红外LED和光电接收管通过检测散射光强度来判断粉尘浓度。输出也是模拟信号但需要驱动LED脉冲时序有要求不能直接当普通ADC读。噪音传感器我选的是模拟噪音模块核心是一个驻极体麦克风加放大电路输出模拟电压对应声压级。注意它输出的是瞬时值不是直接的分贝数需要软件做峰值检测和换算。三个传感器都是模拟输出STM32的ADC通道够用。这里有个细节MQ-2和噪音模块输出范围大概0到3.3V粉尘模块输出范围小一些大概0到1V左右ADC参考电压要设对不然精度浪费。2.4 WiFi模块和云平台的选择WiFi模块我用的是ESP-01S也就是ESP8266核心板通过AT指令和STM32串口通信。为什么不用ESP32直接做主控前面说了我想保留STM32的ADC优势而且ESP-01S便宜、体积小、AT指令成熟。云平台我选的是一个支持MQTT协议的通用物联网平台具体名字不点了市面上这类平台很多功能大同小异。选平台看三点支持MQTT、有免费额度、能画实时曲线。注册后创建产品和设备拿到三元组产品Key、设备名、设备密钥后面代码里要用。注意云平台的三元组信息相当于设备的身份证不要泄露。代码里如果硬编码建议做简单混淆别直接明文放在开源仓库里。3. 核心细节解析与实操要点3.1 电源设计别偷懒很多人做项目直接用USB供电觉得5V够用。但MQ-2加热丝电流不小大概150mA加上WiFi模块发射时瞬间电流能到300mA如果电源不稳STM32会复位WiFi会掉线。我的做法是输入用5V/2A的电源适配器板上加一片AMS1117-3.3给STM32和传感器供电WiFi模块单独用一片LDO或者直接从5V经分压供电ESP-01S是3.3V的千万别接5V。另外在每个传感器的电源脚旁边并一个0.1uF和10uF电容滤掉高频和低频噪声。实测下来电源做扎实了ADC读数波动能小一半。这个细节看起来不起眼但它是数据稳定的基础。3.2 ADC采样与滤波STM32的ADC是12位的参考电压3.3V理论分辨率是3.3/4096≈0.8mV。但实际读数会有跳动尤其是WiFi发射的时候。所以软件滤波必须做。我用的方法是多次采样加中值滤波每个通道连续采15次去掉最大和最小的3个剩下的取平均。这样既能滤掉突发尖峰又能平滑随机噪声。采样间隔我设的是10ms15次大概150ms对这三个慢变量来说完全够用。代码逻辑大概是这样#define SAMPLE_TIMES 15 uint16_t adc_filter(uint8_t ch) { uint16_t buf[SAMPLE_TIMES]; for(int i0;iSAMPLE_TIMES;i){ buf[i] adc_read(ch); delay_ms(10); } // 冒泡排序 for(int i0;iSAMPLE_TIMES-1;i) for(int j0;jSAMPLE_TIMES-1-i;j) if(buf[j]buf[j1]){ swap } // 去掉首尾各3个取中间9个平均 uint32_t sum0; for(int i3;iSAMPLE_TIMES-3;i) sumbuf[i]; return sum/(SAMPLE_TIMES-6); }这个滤波方法我用了很多年简单有效资源占用也小。3.3 粉尘传感器的时序坑GP2Y1010AU0F这个传感器有个坑它的LED需要脉冲驱动不是一直亮。典型时序是LED亮0.32ms然后等0.28ms再采样整个周期10ms。如果你直接读ADC读到的值完全不对。具体操作是用一个GPIO控制LED驱动脚拉低点亮注意它是低电平点亮延时0.32ms然后启动ADC采样采样完拉高熄灭再延时9.68ms进入下一个周期。这个时序必须用示波器或者逻辑分析仪确认光靠延时函数有时候不准。我当时的做法是用定时器产生PWM周期10ms占空比3.2%然后用ADC的外部触发在PWM下降沿后0.28ms采样。这样时序最稳不占用CPU。3.4 噪音分贝的换算逻辑噪音模块输出的是交流信号的包络不是直接的分贝值。要得到分贝数需要做几步先采一段时间内的峰值然后换算成电压再根据模块的灵敏度曲线换算成声压级。我用的模块灵敏度大概是-44dBV/Pa输出经过放大后每帕斯卡对应多少伏要看具体电路。简化做法是在安静环境下测一个基准电压然后用标准声源比如手机放一个固定音量的白噪声标定一个参考点之后用线性关系估算。更严谨的做法是取一段时间内的最大值和有效值用公式dB 20*log10(V/Vref) K来算其中Vref是基准电压K是校准常数。这个K需要你自己标定不同模块不一样。提示噪音测量受环境影响很大建议在传感器外面加一个防风罩减少气流噪声。另外采样窗口不要太短我一般取1秒内的峰值这样读数比较稳。3.5 WiFi模块的AT指令配置ESP-01S出厂固件支持AT指令但默认波特率可能是115200或者9600要先确认。我的配置流程是发送AT确认通信正常发送ATCWMODE1设为Station模式发送ATCWJAPSSID,PASSWORD连接路由器发送ATCIPMUX0设为单连接发送ATCIPSTARTTCP,broker地址,1883连接MQTT服务器发送ATCIPSEND长度然后发送MQTT报文这里有个大坑AT指令的响应有延迟不能发一条等一条要用状态机或者超时重试。我一开始用阻塞式延时结果WiFi信号不好的时候整个系统卡死。后来改成非阻塞状态机主循环里轮询就稳多了。另外MQTT报文需要自己拼装包括固定头、可变头、载荷。CONNECT、PUBLISH、PINGREQ这几个报文必须实现。如果嫌麻烦可以用现成的MQTT AT固件但那样灵活性差一些。4. 完整实操过程与核心环节实现4.1 硬件接线清单先把接线理清楚这是最容易出错的地方。我列一个表模块引脚STM32引脚说明MQ-2AOPA0ADC通道0MQ-2VCC5V加热丝供电MQ-2GNDGND共地GP2Y1010VOPA1ADC通道1GP2Y1010LED驱动PA2GPIO输出GP2Y1010VCC5V经RC滤波噪音模块AOPA3ADC通道3噪音模块VCC3.3V注意电压ESP-01STXPA10USART1_RXESP-01SRXPA9USART1_TXESP-01SVCC3.3V独立LDOESP-01SEN3.3V使能接线的时候注意ESP-01S的TX接STM32的RXRX接TX别接反了。还有ESP-01S的供电一定要足我用的是单独一片AMS1117-3.3输入5V输出3.3V旁边并470uF电容。4.2 STM32端代码框架代码分几个模块ADC采集、传感器换算、串口通信、MQTT报文、主循环调度。我用的是标准库HAL库也可以逻辑一样。主循环的节奏是这样的每2秒采集一轮数据采集完做换算然后拼MQTT报文发给WiFi模块WiFi模块负责发送。同时每30秒发一次PINGREQ保持连接。关键代码片段// 主循环 while(1){ if(tick_2s_flag){ tick_2s_flag 0; uint16_t smoke_raw adc_filter(0); uint16_t dust_raw adc_filter(1); uint16_t noise_raw adc_filter(3); float smoke_ppm smoke_convert(smoke_raw); float dust_ugm3 dust_convert(dust_raw); float noise_db noise_convert(noise_raw); mqtt_publish_data(smoke_ppm, dust_ugm3, noise_db); } if(tick_30s_flag){ tick_30s_flag 0; mqtt_ping(); } wifi_state_machine(); }smoke_convert这些函数就是线性映射根据传感器的数据手册曲线来。MQ-2的曲线不是线性的我用分段线性近似在常用浓度范围内误差可以接受。4.3 MQTT报文拼装细节MQTT的CONNECT报文格式是固定的我直接给一个可用的模板// CONNECT报文 uint8_t connect_pkt[] { 0x10, 0x1A, // 固定头剩余长度26 0x00, 0x04, M,Q,T,T, // 协议名 0x04, // 协议级别 0x02, // 连接标志Clean Session 0x00, 0x3C, // 心跳60秒 0x00, 0x0A, // 客户端ID长度 c,l,i,e,n,t,0,0,0,1, 0x00, 0x08, // 用户名长度 u,s,e,r,n,a,m,e, 0x00, 0x08, // 密码长度 p,a,s,s,w,o,r,d };PUBLISH报文要动态拼主题和载荷长度会变。我写了一个函数传入主题字符串和JSON载荷自动计算长度并拼装。JSON格式我用的是{smoke:12.5,dust:35.2,noise:58.3}简单明了。注意MQTT的剩余长度字段是变长编码小于128用1字节128到16383用2字节。我一开始没注意数据量大的时候报文就错了。后来写了个编码函数自动处理。4.4 云平台配置与数据展示云平台那边注册后创建产品添加设备拿到三元组。然后在平台的“数据流”或“物模型”里定义三个属性smoke、dust、noise类型都是浮点。这样平台才能解析你上报的JSON。数据展示我用的是平台自带的仪表盘拖三个折线图分别绑定三个属性。设置刷新间隔2秒就能看到实时曲线。告警规则也简单smoke超过某个阈值、dust超过某个阈值、noise超过某个阈值就触发邮件或App推送。实测下来从传感器采集到云端显示延迟大概1到2秒完全满足实时监控需求。历史数据平台会存可以导出CSV做进一步分析。4.5 外壳与安装外壳我用的是标准塑料防水盒尺寸大概100x68x50mm。开孔位置要注意MQ-2和粉尘传感器要暴露在空气中不能封死噪音传感器的麦克风孔要朝外但又要防尘。我在噪音传感器前面贴了一层薄薄的无纺布既能透声又能挡灰。安装位置很关键。烟雾传感器要装在可能泄漏源的上方因为烟雾和某些气体比空气轻粉尘传感器要装在呼吸带高度大概1.5米噪音传感器要远离设备本身的风扇噪声。我朋友那个车间我建议他装在车间中部离地1.6米避开通风口直吹。5. 常见问题与排查技巧实录5.1 数据跳动大怎么办这是最常见的问题。排查顺序先看电源用示波器看3.3V和5V的纹波如果超过50mV加电容或者换LDO再看传感器预热MQ-2要预热至少20秒粉尘传感器也要几秒稳定最后看滤波参数采样次数不够就加大中值滤波的窗口可以调到21次。我遇到过一次数据跳得厉害最后发现是WiFi模块和ADC共用了一个LDOWiFi发射时把电源拉低了。分开供电后立刻就好了。5.2 WiFi连不上或者频繁掉线先确认路由器是2.4G的ESP-01S不支持5G。然后看信号强度ATCWJAP?可以查RSSI低于-70dBm就不太稳。再检查供电ESP-01S发射瞬间电流大LDO响应要快输出电容要够。如果频繁掉线加一个看门狗STM32检测WiFi状态超过一定时间没响应就复位ESP-01S。我还在代码里加了自动重连逻辑掉线后每隔10秒重试一次直到连上。5.3 MQTT连接被拒绝一般是三元组不对或者客户端ID重复。云平台通常要求客户端ID唯一如果你用同一个ID多设备连接会被踢。检查产品Key、设备名、设备密钥是否和平台一致。还有有些平台要求用户名和密码有特定格式比如设备名产品Key要看平台文档。5.4 粉尘传感器读数一直是0或者满量程先检查LED驱动时序用示波器看PA2脚有没有脉冲。如果没有可能是GPIO配置错了或者定时器没启动。如果有时序但读数不对检查VO脚的电压范围正常应该在0.1V到1V之间。如果一直是0可能是传感器坏了或者供电不对如果一直是3.3V可能是LED没亮或者接收管饱和。5.5 噪音读数不随声音变化噪音模块输出的是交流包络如果你用普通ADC读读到的可能是直流偏置。要确认模块输出是否隔直如果没有加一个隔直电容。另外采样率要够噪音变化快ADC采样间隔要小于1ms不然峰值抓不到。我一般用定时器触发ADC1kHz采样率采1秒然后软件找峰值和有效值。这样读数才跟实际听感一致。5.6 常见问题速查表现象可能原因排查方法解决数据跳动大电源纹波、预热不足、滤波不够示波器看电源、等预热、加大滤波加电容、延长预热、改滤波参数WiFi掉线信号弱、供电不足、路由器5G查RSSI、查LDO、确认频段换位置、换LDO、连2.4GMQTT拒绝三元组错、ID重复核对平台信息、查日志改正三元组、换唯一ID粉尘读数异常时序错、供电错、传感器坏示波器看驱动、量电压调时序、换供电、换传感器噪音不变化隔直电容缺、采样率低量输出、看采样率加电容、提高采样率系统复位电源跌落、看门狗看复位原因寄存器加强电源、喂狗5.7 几个独家避坑技巧第一ADC参考电压要稳。STM32的VDDA如果和数字电源共用噪声会串进来。我一般给VDDA单独加LC滤波效果明显。第二串口通信加超时。AT指令的响应不能无限等每个指令设500ms超时超时就重发重发3次还不行就复位WiFi模块。第三数据上报加时间戳。虽然平台会加接收时间但设备端加时间戳更准尤其是网络延迟大的时候。STM32没有RTC的话可以用开机时间累加。第四固件留OTA接口。虽然这个项目简单但留个串口升级接口以后改参数不用拆机。我一般留一个命令收到特定指令就进入Bootloader。第五外壳做防尘防水。工业环境粉尘大传感器窗口容易堵。我建议每三个月清理一次或者加一个微型风扇做气流循环。6. 后续可以怎么扩展这个项目跑通之后扩展空间很大。比如加一个继电器超标时自动启动排风扇加一个SD卡模块本地也存一份数据防止网络断了丢数据加一个OLED屏现场就能看读数不用掏手机。软件层面可以把数据推到多个平台做冗余备份可以加边缘计算在STM32上做简单阈值判断超标才上报省流量还可以做低功耗版本用电池供电定时唤醒采集。我自己下一步打算加一个CO2传感器把空气质量也纳入进来。传感器选型上NDIR的CO2模块贵一些但精度好适合室内环境监测。这套方案的核心价值在于用最低的成本把环境数据数字化、网络化、可视化。硬件不到一百块代码开源思路清晰云平台免费用。你照着做一个周末就能跑起来。真正花时间的是调试和标定但这也是最有意思的部分——看着曲线随着环境变化跳动那种成就感比刷手机强多了。
阅读完成 · 觉得有帮助?
咨询建站