资讯动态

STM32环境检测物联网系统:从传感器选型到云平台对接的完整实战

发布时间:2026/10/14 19:57:56 来源:尧图企业网站定制
1. 项目缘起与整体设计思路1.1 这个项目到底在做什么先把这个项目的核心讲清楚。STM32环境检测物联网系统本质上就是用一个STM32单片机作为主控挂载烟雾传感器、粉尘传感器和噪音传感器把采集到的环境数据通过WiFi模块上传到云平台用户可以在手机或电脑上远程查看实时数据。听起来好像不复杂但真正动手做的时候从传感器选型到数据校准从WiFi通信稳定性到云端数据存储每一步都有不少坑。我做这个项目的初衷其实很朴素想给一个封闭的储物间做一套环境监测。那个空间通风不好偶尔有人在里面抽烟又靠近马路粉尘和噪音都不小。市面上的成品监测设备要么功能太单一要么价格虚高而且数据都锁在厂商自己的App里没法自己二次开发。所以干脆自己搭一套硬件成本控制在百元级别数据完全自己掌控。这套系统适合什么人参考我觉得有三类人一是正在学STM32想找个综合项目练手的同学这个项目涉及ADC采集、UART通信、定时器、中断、协议解析等多个知识点覆盖面够广二是需要做环境监测方案但预算有限的开发者这套方案可以直接复用三是对物联网感兴趣想了解“端-云”完整链路的爱好者从传感器到云平台的全流程都能跑通。1.2 为什么选STM32而不是其他方案市面上做环境监测的主控方案很多ESP32、Arduino、树莓派都能干这事。我选STM32主要基于几个考虑。第一是实时性和稳定性。STM32基于ARM Cortex-M内核中断响应快定时器精度高做周期性数据采集的时候时间抖动很小。我实测过用STM32F103做1秒周期的ADC采样连续跑24小时采样间隔的偏差在微秒级别。ESP32虽然也强但WiFi协议栈跑起来之后任务调度会有一些不确定性对采样精度要求高的场景不太友好。第二是外设资源丰富。STM32F103C8T6这块芯片虽然便宜但有2个12位ADC、3个USART、多个定时器烟雾和粉尘传感器用ADC采集噪音传感器可以用ADC或者数字接口WiFi模块走USART资源刚好够用还有余量。而且ADC的参考电压可以外部提供精度比直接用VDDA做参考要稳。第三是生态成熟。STM32的HAL库、标准库资料铺天盖地遇到问题搜一下基本都有答案。对于新手来说这一点太重要了。我见过太多人卡在ESP32的某些底层配置上文档少、社区回答质量参差不齐很容易劝退。当然STM32方案也有代价它本身不带WiFi必须外挂WiFi模块硬件成本和PCB面积都会增加。但换来的是灵活性——WiFi模块可以换从ESP-01到ESP-12F到其他型号只要AT指令集兼容上层代码几乎不用改。1.3 系统架构的取舍整个系统的架构我反复调整过几次最终定下来的方案是STM32负责采集和预处理WiFi模块负责透传云平台负责存储和展示。为什么不让STM32直接跑TCP/IP协议栈因为F103的内存只有20KB RAM跑轻量级协议栈虽然勉强能行但加上传感器数据处理和缓冲内存会很紧张而且开发难度陡增。用WiFi模块做透传STM32只需要通过串口发AT指令把数据打包成JSON或者自定义格式发出去就行简单可靠。为什么选云平台而不是自己搭服务器自己搭服务器当然更自由但需要维护公网IP、处理证书、做数据持久化对于个人项目来说运维成本太高。用现成的物联网云平台注册个账号就能用数据存储、可视化、告警推送都是现成的省下来的时间可以花在硬件和采集逻辑的打磨上。这里有个关键决策点数据上传频率。上传太频繁WiFi模块功耗高、云平台消息条数消耗快上传太慢实时性差。我最后定的是正常状态下每30秒上传一次如果某个指标超过阈值立即触发一次上传并推送告警。这个策略在实时性和资源消耗之间取了个平衡。2. 核心硬件选型与电路设计要点2.1 主控芯片的确定主控我选的是STM32F103C8T6也就是常说的“蓝板”或“最小系统板”。这块芯片的核心参数72MHz主频、64KB Flash、20KB RAM、2个12位ADC共10个外部通道、3个USART、2个I2C、2个SPI、多个定时器。对于这个项目来说资源绰绰有余。为什么不用F4系列F4性能更强但价格也更高而且这个项目对算力要求不高F103完全够用。省下来的预算可以花在更好的传感器上对最终数据质量的提升更明显。最小系统板的使用有个细节要注意市面上很多蓝板的核心板USB接口旁边的5V和3.3V输出能力有限如果WiFi模块峰值电流较大最好单独供电或者加一个大电容。我一开始直接用板载3.3V给WiFi模块供电结果WiFi连接瞬间电压跌落导致STM32复位。后来在WiFi模块的电源脚并了一个470μF的电解电容加一个0.1μF的陶瓷电容问题就解决了。2.2 三种传感器的选型对比传感器是整个系统的数据源头选型直接决定数据质量。我把选型过程和对比整理成表格方便你参考。传感器类型候选型号接口方式优点缺点最终选择烟雾MQ-2模拟输出便宜、资料多、灵敏度可调需要预热、受温湿度影响大MQ-2烟雾MQ-135模拟输出对多种气体敏感选择性差、校准复杂备选粉尘GP2Y1010AU0F模拟输出光学原理、精度尚可需要驱动电路、怕灰尘积攒GP2Y1010AU0F粉尘PMS5003串口输出精度高、直接出数字值价格高、体积大备选噪音驻极体麦克风放大模拟输出便宜、电路简单需要自己算分贝、一致性差自制模块噪音数字噪音模块数字/模拟直接输出、使用简单精度一般、量程有限最终选择烟雾传感器选MQ-2理由很简单它对液化气、丙烷、氢气、烟雾都有响应虽然不能区分具体气体种类但作为“有没有烟雾”的定性判断完全够用。而且它的模拟输出可以直接接STM32的ADC不需要额外的转换电路。粉尘传感器选GP2Y1010AU0F这是一个光学粉尘传感器内部有红外LED和光电晶体管通过检测散射光来判断粉尘浓度。它的输出也是模拟电压但需要给内部LED提供脉冲驱动不能直接接直流。这一点后面在电路部分会详细说。噪音传感器我最后用的是现成的数字噪音模块它内部已经把麦克风信号放大并做了峰值检测输出一个模拟电压对应噪音的强度。虽然精度不如专业声级计但用来判断“安静/正常/吵闹”三个档位绰绰有余。2.3 电路连接的关键细节电路连接看起来简单但有几个地方如果处理不好数据会飘得厉害。MQ-2的供电和预热。MQ-2的加热丝需要5V供电而且第一次使用或者长时间断电后需要预热24小时以上才能稳定。我一开始没注意上电就开始测数据从几百跳到几千完全没法用。后来查了资料才知道MQ-2的敏感材料需要在一定温度下老化稳定。所以如果你要做这个项目建议提前一天给传感器通电预热或者至少预热半小时再开始采集。GP2Y1010AU0F的驱动电路。这个传感器的LED需要脉冲驱动典型驱动周期是10ms其中LED点亮0.32ms熄灭9.68ms。STM32需要输出一个PWM信号来控制LED同时在LED点亮的期间采集模拟输出。如果直接用直流驱动LED传感器会很快老化而且输出也不准。我用的方案是用一个定时器输出PWM另一个定时器在PWM高电平期间触发ADC采样这样时序最准。噪音模块的参考电压。噪音模块输出的是模拟电压STM32的ADC参考电压默认是VDDA3.3V。如果噪音模块的供电也是3.3V那没问题但如果噪音模块用5V供电输出可能超过3.3V会烧ADC引脚。我一开始就犯了这个错噪音模块用5V供电输出峰值到了4V多幸好STM32的ADC引脚有钳位二极管没烧掉但数据一直卡在4095。后来改成3.3V供电问题解决。WiFi模块的串口电平。ESP-01和ESP-12F都是3.3V电平和STM32的串口可以直接连。但有些WiFi模块是5V电平如果直接连STM32的3.3V串口可能会损坏STM32的引脚。连接之前一定要确认模块的电平标准不确定的话加一个电平转换电路。3. 软件架构与核心代码实现3.1 整体软件流程设计软件部分我采用的是前后台架构主循环负责传感器数据采集和状态机调度定时器中断负责精确的采样时序串口中断负责WiFi模块的数据接收。为什么不跑RTOS因为这个项目的任务数量不多优先级关系也不复杂用前后台架构足够。而且RTOS会占用额外的RAM和Flash对于F103来说能省则省。当然如果你后续要加更多传感器或者更复杂的逻辑可以考虑上FreeRTOS但那是另一个话题了。主循环的流程是这样的初始化系统和外设然后进入无限循环。循环里依次做几件事检查定时器标志位如果到了采集时间就依次读取三个传感器的值对数据进行滤波和单位转换判断是否超过阈值把数据打包成JSON格式通过WiFi模块发送到云平台最后处理云平台下发的命令比如修改上传间隔。3.2 传感器数据采集与滤波ADC采集原始值之后不能直接用必须做滤波。我试过几种滤波方案最后用的是滑动平均滤波加中值滤波的组合。具体做法是每个传感器连续采5次去掉最大值和最小值剩下的3个取平均。这样既能滤掉突发的尖峰干扰又能平滑随机噪声。5次采样的间隔是10ms总共50ms完成一个传感器的采集。三个传感器轮流采一轮下来150ms对于30秒的上传周期来说完全来得及。这里有个细节ADC的采样时间要设置够。STM32的ADC采样时间可以配置默认的采样周期可能太短导致采样值不准。我一般把采样时间设成239.5个ADC时钟周期这是F103支持的最长采样时间对于高阻抗的传感器输出信号来说采样更充分。数据转换方面MQ-2的输出电压和烟雾浓度不是线性关系而是近似对数关系。我用的简化公式是浓度 a * (V/V0)^b其中V是当前电压V0是洁净空气中的电压a和b是经验系数。这个公式不精确但用来判断“有没有烟雾”足够了。如果你需要精确的浓度值需要做多点校准用标准气体标定。粉尘传感器的转换相对简单GP2Y1010AU0F的输出电压和粉尘浓度基本是线性的典型灵敏度是0.5V/(100μg/m³)。也就是说输出电压每升高0.5V粉尘浓度增加100微克每立方米。但要注意这个传感器的输出有零点漂移需要在洁净空气中测一个基准值后续的数据都减去这个基准。噪音传感器的转换最麻烦。它输出的是模拟电压对应的是声音的峰值强度。要转换成分贝值需要知道麦克风的灵敏度和放大电路的增益。我用的简化方法是先测出安静环境下的输出电压V_quiet再测出已知声压级下的输出电压V_ref然后用公式dB 20 * log10(V/V_quiet) dB_quiet来估算。这个方法不精确但用来做相对比较没问题。3.3 WiFi通信与云平台对接WiFi模块我用的是ESP-01S固件是AT指令版本。STM32通过串口发送AT指令来控制它。整个通信流程分几步首先是硬件初始化包括串口配置和WiFi模块复位然后是连接WiFi热点发送ATCWMODE设置模式ATCWJAP连接热点接着是连接云平台服务器发送ATCIPSTART建立TCP连接最后是发送数据用ATCIPSEND指令。这里有几个坑我踩过。第一个坑是AT指令的响应时间。ESP-01S在执行某些指令时比如连接热点可能需要几秒钟才能返回OK。如果STM32不等响应就发下一条指令模块会直接忽略。我的做法是每条AT指令发出后等待模块返回“OK”或者“ERROR”如果超时比如5秒就重试重试3次还不行就复位模块重新来。第二个坑是数据发送的长度限制。ATCIPSEND指令一次最多发送2048字节但实际使用中如果数据太长模块可能会分包发送导致云平台收到不完整的数据。我的做法是把JSON数据控制在200字节以内只包含必要的字段时间戳由云平台自己生成。第三个坑是WiFi断线重连。WiFi连接不是永远稳定的路由器重启、信号波动都可能导致断线。我在主循环里加了一个心跳检测每隔一段时间检查WiFi模块的连接状态如果发现断线就自动执行重连流程。重连流程包括复位WiFi模块、重新连接热点、重新建立TCP连接。这个过程大概需要10到15秒期间数据会丢失但恢复之后就能继续上传。数据格式我用的是JSON因为云平台基本都支持JSON解析而且可读性好。一个典型的数据包是这样的{ device_id: env_monitor_01, smoke: 125, dust: 38, noise: 52, timestamp: 0 }其中smoke是MQ-2的ADC原始值dust是粉尘浓度微克每立方米noise是估算的分贝值。timestamp留0由云平台填充接收时间。3.4 云平台配置与数据可视化云平台我选的是一个支持MQTT和HTTP接入的通用物联网平台。配置流程不复杂注册账号、创建产品、添加设备、定义数据点。数据点就是你要上传的字段比如smoke、dust、noise每个字段定义好名称、类型、单位。设备创建好之后平台会分配一个设备ID和鉴权信息。STM32在发送数据的时候需要把这些信息带上平台才能识别是哪个设备发的数据。我用的是HTTP协议因为ESP-01S对MQTT的支持不如HTTP稳定而且HTTP的调试更直观用串口助手就能看到完整的请求和响应。数据可视化方面平台一般都有现成的仪表盘组件拖拽就能生成折线图、仪表盘、数据表格。我配置了一个折线图显示三个指标的历史趋势一个仪表盘显示当前值还有一个告警规则当烟雾值超过阈值或者粉尘浓度超过阈值时平台会发送邮件或者App推送通知。这里有个经验云平台的数据存储有免费额度限制。比如某些平台每月只免费存储一定条数的消息超出之后要么付费要么数据被丢弃。所以上传频率不能太高30秒一次的话一天是2880条一个月是86400条基本在免费额度内。如果你把频率提高到1秒一次那一个月就是259万条肯定超了。4. 调试过程中的典型问题与排查实录4.1 传感器数据异常与排查问题一MQ-2数据一直很高降不下来。现象是上电之后MQ-2的ADC值一直在3000以上在洁净空气中也是这个值。排查过程先用万用表测MQ-2的模拟输出脚电压发现是3.2V接近VDDA。这说明传感器输出确实很高不是STM32的问题。然后检查供电发现加热丝电压只有4.2V低于标称的5V。换了一个输出能力更强的5V电源之后加热丝电压恢复到5.0V但数据还是高。最后查资料才知道MQ-2需要预热而且预热时间很长。通电老化24小时之后洁净空气中的ADC值降到了800左右正常了。问题二粉尘传感器数据跳动很大。现象是粉尘浓度的读数在10到200之间随机跳。排查过程先用示波器看GP2Y1010AU0F的模拟输出发现波形上有很大的尖峰噪声。检查电路发现传感器的供电脚没有加滤波电容。在供电脚并了一个100μF的电解电容和一个0.1μF的陶瓷电容之后噪声明显减小。另外传感器的LED驱动脉冲和ADC采样之间的时序也很关键如果采样时刻不在LED稳定点亮期间读数会偏低。我调整了定时器的相位让ADC采样点落在LED点亮后0.2ms的位置数据就稳定了。问题三噪音数据在安静环境下也有50多分贝。现象是夜深人静的时候噪音读数还是50dB以上。排查过程先确认麦克风没有收到实际声音用示波器看噪音模块的输出发现有一个低频的波动信号。这个信号来自电源纹波。噪音模块的供电和STM32的供电是同一个3.3VSTM32的数字电路开关噪声耦合到了模拟部分。解决办法是在噪音模块的供电脚加一个LC滤波电路用一个10Ω电阻和一个100μF电容组成低通滤波器把高频噪声滤掉。另外噪音模块的地线要单独走不要和数字地混在一起最后在电源入口处单点接地。4.2 WiFi通信故障与解决问题四WiFi模块连接热点失败返回ERROR。排查过程先用串口助手直接连WiFi模块手动发AT指令发现ATCWJAP返回ERROR。检查热点名称和密码发现密码里有一个特殊字符“”而AT指令的参数是用逗号分隔的特殊字符可能导致解析错误。把密码改成纯字母数字之后连接成功。所以如果你要用AT指令连接热点密码里最好不要有特殊字符或者用转义的方式处理。问题五数据发送成功但云平台收不到。排查过程先用串口助手抓STM32发给WiFi模块的数据发现ATCIPSEND指令发出后模块返回了“”然后STM32发送了JSON数据模块返回“SEND OK”。这说明数据发出去了。然后检查云平台的设备日志发现平台收到了TCP连接但没有收到有效的数据包。最后发现是HTTP请求的格式不对缺少了Content-Length头导致平台无法正确解析。补上Content-Length之后数据正常入库。问题六系统运行几个小时后死机。现象是系统运行一段时间后串口没有输出WiFi也不发送数据了。排查过程先用调试器连上STM32发现程序卡在HardFault_Handler里。查看调用栈发现是串口中断处理函数里出现了数组越界。原因是WiFi模块返回的数据长度超过了接收缓冲区的长度导致溢出。解决办法是把接收缓冲区从128字节扩大到512字节并且在中断里加了长度检查超过缓冲区长度就丢弃。4.3 常见问题速查表问题现象可能原因排查方法解决方案传感器读数偏高预热不足、供电电压不对测供电电压、预热24小时更换电源、延长预热时间数据跳动大电源噪声、采样时序不对示波器看波形、检查采样时刻加滤波电容、调整采样相位WiFi连接失败热点密码有特殊字符、信号弱串口助手手动发AT指令修改密码、靠近路由器云平台收不到数据HTTP格式错误、鉴权失败抓包看请求内容补全请求头、检查设备ID系统死机中断溢出、内存越界调试器看调用栈扩大缓冲区、加长度检查数据上传延迟大上传频率太高、网络拥塞看云平台接收时间戳降低上传频率、增加重试5. 系统优化与扩展方向5.1 功耗优化如果这个系统要用电池供电功耗就是必须考虑的问题。我实测过不加任何优化的情况下整个系统的平均电流在80mA左右其中WiFi模块占了大头。优化方向有几个一是降低采集频率从30秒一次改成5分钟一次二是让STM32在两次采集之间进入Stop模式把电流降到微安级别三是WiFi模块不用的时候进入睡眠模式需要发送数据时再唤醒。Stop模式的进入和退出需要配置中断唤醒我用的是RTC定时器每30秒产生一个唤醒中断。唤醒后STM32重新初始化时钟和外设采集数据发送然后再次进入Stop模式。这样平均电流可以降到15mA左右用2000mAh的电池能撑5天左右。5.2 数据精度提升如果对数据精度要求更高有几个方向可以改进。烟雾传感器可以换成数字输出的型号比如某些带I2C接口的气体传感器直接输出校准后的浓度值。粉尘传感器可以换成PMS5003它是激光散射原理精度比红外的高不少而且直接输出数字值不需要ADC采集。噪音传感器可以用专业的声级计模块带A计权滤波更接近人耳的感受。另外温湿度对传感器的影响不能忽略。MQ-2的输出受温度影响很大如果能在板上加一个温湿度传感器比如SHT30用温湿度数据对烟雾和粉尘读数做补偿精度会明显提升。5.3 功能扩展思路这个系统的框架是通用的传感器可以换云平台可以换扩展性很好。几个我觉得有意思的扩展方向一是加一个继电器模块当烟雾浓度超过阈值时自动启动排风扇二是加一个OLED屏幕本地也能看到实时数据三是加一个SD卡模块网络断开的时候数据先存本地恢复后再补传四是把数据接入语音助手问一句“储物间空气怎么样”就能播报当前数据。我个人最推荐的是加本地屏幕和SD卡存储。屏幕让你不用掏手机就能看到数据SD卡保证数据不丢失。这两个模块都很便宜加起来不到20块钱但实用性提升很大。5.4 外壳与安装注意事项最后说一个容易被忽略的环节外壳和安装。传感器暴露在空气中才能准确测量但直接裸露又容易积灰受潮。我的做法是用一个带透气孔的塑料外壳传感器朝下安装避免灰尘直接落在传感器上。MQ-2的加热丝会发热外壳不能完全密封否则热量积聚会影响读数。WiFi模块的天线要远离金属物体否则信号会变差。安装位置也很关键。烟雾传感器要装在可能产生烟雾的区域附近但不要离厨房油烟太近否则会频繁误报。粉尘传感器要装在离地面1米到1.5米的高度这个高度接近人的呼吸带数据更有参考价值。噪音传感器要远离空调出风口和窗户避免风噪干扰。我在实际使用中发现这套系统最考验人的不是代码而是耐心。传感器需要预热数据需要校准WiFi需要调试每一个环节都可能卡住。但一旦跑通看到手机上的数据实时更新那种成就感还是很足的。如果你也在做类似的项目我的建议是先把单个传感器调通再逐个加进来不要一上来就全部连好那样出了问题很难定位。另外串口打印调试信息是最有效的排查手段别嫌麻烦关键节点都加上打印能省很多时间。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑