ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

从零搭建室内环境检测系统:ESP32+传感器+MQTT+数据可视化

从零搭建室内环境检测系统:ESP32+传感器+MQTT+数据可视化 简介基于Qt与Zigbee的室内环境检测系统上位机源码包面向物联网、嵌入式开发者及课程设计人群解决环境数据采集、串口通信与人机交互等环节的代码实现问题。压缩包共92个文件约49.14MB包含13个C源文件、11个头文件、6个UI界面文件以及PNG/JPG图片素材、数据库文件、QSS样式和可直接运行的EXE等资源目录结构完整便于直接查看或二次开发。目前已有2800人学习/浏览。该资源为Qt人机交互部分的完整实现涵盖串口通信、温湿度与甲烷含量数据的接收显示、数据库建立、警报系统及用户注册登录机制UI设计文件与素材齐全可快速修改界面外观内置的数据库与可执行文件则方便先运行再研读代码适合作为课程设计、毕业设计或自学者搭建类似系统时的参考框架。1. 项目概述为什么需要一套“室内环境检测系统”前阵子家里换了新房子装修完晾了半年但我心里一直不踏实总觉得空气里还有东西。市面上那些几十块钱的温湿度计只能看一眼当下数值没办法连续记录更别说把不同房间的数据放在一起对比了。网上也有一些检测仪但大几千的售价加上耗材更换成本实在下不去手。所以我就动了手花了大概两周时间做了一套属于自己的室内环境检测系统也就是标题里这个“室内环境检测系统.zip”。这套系统说白了就是把温湿度、空气质量这些关键指标用传感器采集回来再通过无线传输汇总到本地服务器最终变成一张可以随时打开看的趋势图和告警记录。它解决的最大痛点不是告诉你“现在温度是多少”而是告诉你“过去24小时温度怎么变的”“厨房做饭时PM2.5会飙到多少”“半夜卧室二氧化碳浓度有没有超标”。这些信息普通温湿度计给不了你。项目源码、PCB工程、外壳3D打印文件都打包在一个zip里了所以命名为“室内环境检测系统.zip”。整套东西对新手很友好不需要你会嵌入式开发只要你愿意焊几根线、会改一个配置文件就能跑起来。我的目标读者有三类一是正在装修想监控室内空气质量的业主二是智能家居爱好者想自己DIY一个环境监测节点三是对物联网数据链路感兴趣、想完整走一遍采集到展示流程的开发者。这篇文章我就把从硬件选型到软件部署的完整思路和踩坑记录都写出来。2. 整体架构拆解不要一上来就堆功能拿到这个项目的时候我最怕的是贪多嚼不烂。市面上很多开源环境监测项目又是甲醛又是负氧离子传感器挂了一排最后数据乱到根本没法看。我做架构决策的第一条原则就是只监测那些有明确传感器方案、且对生活有直接指导意义的指标。最终锁定了四个温度、湿度、PM2.5、CO2。前两个不必多说后两个是室内空气质量的核心参考项。PM2.5直接关系呼吸道健康CO2浓度超过1000ppm会造成明显的昏沉感这两个数据对长期待在室内的人非常有价值。2.1 主控与通信方案为什么选ESP32主控这块我选的是ESP32-WROOM-32模组。价格在十几块钱左右支持WiFi和蓝牙双模自带足够的GPIO口还有I2C、UART、ADC这些外围接口完全可以胜任多个传感器的数据采集任务。更关键的是ESP32在Arduino和ESPHome这两个生态里都极其成熟就算你不会写代码用现成固件也能跑起来。考虑到这套系统要长期24小时运行ESP32的低功耗模式和稳定的网络重连机制也是我选择它的核心理由。通信方案我放弃了蓝牙直接走WiFi。原因很简单这套系统定位是“持续监测历史回放”数据要落到服务器上蓝牙只能做本地短距离传输还得天天开着手机App才能看数据违背了设计的初衷。WiFi方案配合MQTT协议传感器数据推送到局域网内的服务器稳定、省心而且在任何房间打开电脑或手机就能访问数据面板。2.2 传感器选型要看的三个关键参数选传感器这件事我踩过不少坑。最开始贪便宜买了一批国产DHT11测出来的温度能比水银温度计偏2度湿度在60%以上直接飘到没法看。后来老老实实换了传感器核心就看三个参数测量精度、响应时间、长期稳定性。温度湿度这块我用了SHT30I2C接口精度±0.3℃和±2%RH价格十几块比DHT11贵几块钱但数据质量不知道好到哪里去了。PM2.5用攀藤PMS5003激光散射原理响应时间在10秒以内数据稳定风扇寿命也够长业界很多空气净化器用的就是这颗传感器。CO2用的是SenseAir S8NDIR非色散红外原理这是目前民用级别里最靠谱的方案不会像电化学传感器那样随时间漂移。成本确实不低单颗要一百多但它能保证数据在长期运行中依然可信。2.3 软件分层思路采集、传输、展示各管各的软件架构上我坚持“采集、传输、展示”三层分离。采集层跑在ESP32上负责定时读取传感器数据做简单的滤波处理传输层用MQTT协议把格式化后的JSON数据推送到MQTT Broker展示层部署在服务器或树莓派上负责接收数据、存库、画图表。这样的好处是每一层都可以独立替换比如以后想换更强的气体传感器只需要改采集层的代码服务器端完全不用动。很多新手喜欢把所有业务逻辑都塞进ESP32固件里比如直接在设备上生成图表页面甚至挂一个小数据库。这在单节点时看着很过瘾但节点一多就崩了。设备端的资源和性能都有限长时间跑Web服务容易发热、死机。我的经验是设备端只做一件事采集数据然后老老实实把数据发出去。其他让服务器来干。3. 核心硬件实操要点焊接、布局和供电的细节硬件部分如果只看原理图会觉得很简单但真正焊起来问题一个接一个。我第一次打样回来的PCB三个传感器直接挂在同一个I2C总线上结果CO2传感器死活识别不到排查了一整个晚上才发现是SDA线的上拉电阻焊错了位置。所以这块我想多写几句实操细节都是常规文档里不会告诉你的。3.1 PCB布局的干扰问题PMS5003这个PM2.5传感器有一个内置风扇转速还不低电机启动瞬间会有比较大的电流波动。如果这个波动直接串到模拟电路的电源轨上表现就是数据周期性跳动。解决方法是给PMS5003独立供电用一颗LDO单独供电或者至少加一个100uF的电解电容和0.1uF的陶瓷电容做去耦。同样的问题也会出现在S8传感器的加热器脉冲上尤其是老板子驱动电流大的时候数据会突然跳一个尖峰。布局顺序上我把主控放中间左侧是温湿度和CO2传感器右侧是PM2.5传感器电源和接口放在板边。S8的NDIR光学腔体比较大不要紧贴板边放置否则机械强度不够插拔排线的时候容易把焊盘拽掉。另外I2C总线的走线要对称避免一根长一根短。说白了给I2C留的空间越大抗干扰能力越强排查起来也省心。3.2 传感器I2C地址冲突问题这块遇到一个特别坑的问题SHT30和S8的默认I2C地址都是0x44S8是0x58但某些国产版本用0x44如果你跟我一样同时挂这两颗传感器必须手动改地址。SHT30支持通过ADDR引脚拉高切换地址到0x45而S8部分固件版本不带地址切换功能只能换一个库或者用软件模拟I2C总线。我的方案是让SHT30走硬件I2C地址改到0x45S8走软件I2C挂在另外两个GPIO引脚上彻底物理隔离问题一次性解决。顺带说一句如果用了ESP32硬件I2C总线其实可以配置到任意引脚不一定非得是默认的GPIO21和GPIO22。多看看芯片的引脚复用表灵活一点能省很多事。3.3 供电方案稳定性和安全冗余这套系统我设计的是5V USB供电板载一颗AMS1117-3.3给ESP32和数字传感器供电PMS5003和S8直接吃5V。但有个细节需要注意AMS1117的最大输出电流其实只有800mA左右而PMS5003峰值电流能到120mAS8的峰值在100mA左右再加上ESP32在某些瞬间会有500mA级别的电流尖峰这些加在一起会让1117烫得厉害。我的建议是主控和传感器分开供电或者直接用MP1584这种DC-DC模块把电压降下来效率高、发热小。如果以后想升级成电池供电就建议用ESP32的深度睡眠模式每10分钟醒来一次采集数据然后继续休眠整体平均电流可以压到几毫安配合18650电池能撑很久。这块我还没做但已经在准备第二版了。4. 固件开发与数据处理从原始数据到可用趋势图固件这块我选了Arduino框架因为生态最丰富遇到问题能找到的参考案例最多。整个采集逻辑其实不复杂核心就是一句话定时读取传感器、做滤波、打包成JSON、通过MQTT发出去。但真正有几个小点是决定这套系统能不能稳定长期运行的关键。4.1 传感器读取时序为什么要做隔离PMS5003的读取方式不是I2C而是串口。传感器内部有一个风扇和激光器通电后需要大概30秒预加热才能给出稳定数据。所以开机后如果立刻去读拿到的数据要么是零要么是严重偏低。S8的预热时间更长官方标称是1分钟到2分钟。我的做法是在固件里做一个初始化阶段上电后前90秒只采集温湿度不处理PM2.5和CO2的数据等系统稳定了再读取这两个传感器。虽然这会让开机后前几分钟的面板数据缺失但换来的是整体数据质量的稳定非常值得。4.2 数据滤波一趟简单的滑动平均就够了传感器数据永远有噪声如果是OLED屏幕上实时显示你会看到数字疯狂跳动。我用了一趟5点滑动平均滤波效果立竿见影。具体逻辑就是维护一个长度为5的环形缓冲区每次采集到新数据就丢进缓冲队列输出队列的平均值。这样做法比卡尔曼滤波简单得多且对温湿度、PM2.5这类慢变量来说完全够用。float buffer[5] {0}; uint8_t idx 0; float addSample(float value) { buffer[idx] value; idx (idx 1) % 5; float sum 0; for (uint8_t i 0; i 5; i) sum buffer[i]; return sum / 5.0; }上面是Arduino风格的代码片段放到循环里每2秒调用一次然后把输出值用于MQTT发布数据就会平滑很多。特别是PM2.5这种本身波动幅度就大的指标滤波前后的曲线完全像两个设备的数据。4.3 MQTT服务器与数据面板的部署MQTT Broker我用的Mosquitto轻量、稳定在树莓派或任何小主机上一条命令就能装好。ESP32端发布到home/stats/temperature、home/stats/humidity这类主题数据用JSON格式打包。订阅端的数据采集服务用Python写基于paho-mqtt库收到消息直接往InfluxDB时序数据库里写。展示端用Grafana数据源连InfluxDB可以直接拖拽生成面板不需要做任何前端开发。Grafana的配置里有一个关键点在Dashboard设置中把时间范围默认设为“Last 24 hours”并且开启自动刷新每30秒刷新一次。这样打开面板就能看到从昨天到现在每一分钟的曲线变化比看即时数值有价值得多。另外InfluxDB的保留策略我设置30天超过30天的数据自动清理避免SD卡被写满。这个策略可以根据个人需要调整比如想保留一年就改下保留策略配置。4.4 告警规则超过阈值就推消息数据光有曲线还不够最好能在异常时主动通知人。我在Grafana里建了几个Alert规则比如CO2浓度连续5分钟超过1000ppm触发一个Warning级别的告警通过Telegram机器人推消息到手机PM2.5超过75ug/m³时触发提醒。之所以强调“连续5分钟”是为了过滤掉瞬时噪声和偶然波动比如有人站在传感器旁边大口呼吸就会造成CO2瞬间冲高这种短时尖峰不构成长时段通风需求。告警阈值不能随意设参考了室内空气质量标准CO2推荐浓度下限是1000ppmPM2.5日均限值是75ug/m³温湿度按体感舒适区设定在18-26℃、40%-60%RH。刚开始用建议把阈值放宽一些先跑两周收集基线数据再去调整阈值至少要知道自家环境的“正常值”是什么水准。5. 常见问题与排查技巧实录这一章是专门写给动手过程中快要崩溃的朋友的。我做的过程中遇到的问题好多都是网上查半天查不到答案的。这里直接整理成速查表省得你再走一遍弯路。5.1 传感器数据全是零或者固定值原因传感器初始化失败大概率是供电不足或者I2C地址错误。解法先用I2C扫描程序跑一遍确认哪些地址有设备应答。如果没有发现设备量一下传感器供电引脚对地电压是否正常再看有没有把SDA和SCL接反。这块我建议把I2C扫描代码烧进设备之前焊完就做一次不要等整套系统上线了再查。5.2 数据面板时而有数据时而断流原因ESP32的WiFi连接不稳定。家用路由器的2.4G频段干扰非常严重尤其是靠近微波炉、蓝牙音箱这些设备时丢包和掉线是家常便饭。解法在固件里加上看门狗机制WiFi断开5秒后自动重连重连失败就重启。另外在代码里尽量避免同步阻塞操作比如WiFi连接时用WiFi.disconnect(); WiFi.reconnect();这种非阻塞式写法保持系统主循环不卡死。5.3 CO2传感器的数值长时间不变原因一S8的ABC自动基线校准功能在“长期无人且通风良好”的环境里会把当前浓度误判为400ppm的基线导致室内真实CO2浓度变化时读数反应迟缓。解法在固件里关闭ABC功能或者定期把传感器拿到户外通风处校准一次。原因二传感器本身没问题是刷新频率太低。S8的响应时间是2分钟一个循环你把数据读取间隔设为1秒自然看到的就是反复同一个值等两分钟再看就正常了。这里不要调得太快按官方推荐的读取周期来就好。5.4 温湿度数据跳动剧烈原因传感器受到阳光直射或者空调直吹局部微气候影响读数也可能是传感器紧挨着S8这个会发热的器件导致温度读数虚高。解法外壳设计时把传感器放在风道位置远离发热源同时在SHT30上方加一个辐射罩——其实就是一层铝箔隔热棉成本几毛钱效果立竿见影。5.5 MQTT连接正常但数据不落库原因InfluxDB的表结构和MQTT主题字段对不上。比如Python解析了JSON里的temperature字段但写数据库时用的field名是temp查询时就拿不到数据。解法在Python订阅端加一个日志输出把收到的原始payload打出来先确认数据格式正确再谈落库。别问我怎么知道的这个问题我整整排查了一个下午最后发现只是字段名差了一个字母。6. 写在最后的一些实操心得整套系统跑起来之后我最直观的感受是数据带来的确定性比智能家居的酷炫感重要得多。以前总觉得“屋里应该通风了”现在看二氧化碳数据飙到1200ppm心里明明白白立刻开窗。以前担心PM2.5超标现在每天回家先看一眼曲线数据告诉你今天空气质量到底怎么样不用再靠感觉猜。在实际使用中我最推荐的场景是卧室的二氧化碳监测。卧室关窗睡觉一晚CO2能到2000ppm以上早上起来头痛、口干是很典型的二氧化碳中毒症状。自从我看了这个数据不管冬天多冷我都会留一条窗缝通风睡眠质量确实有了明显提升。这也是我强烈建议所有自己搭这套系统的朋友最先关注的数据指标。一个小建议做这套东西第一版不要追求全功能先把温湿度和CO2两个数据跑通用一周时间验证稳定性再逐步加PM2.5、加告警、加第二节点。我身边好几个朋友就是上来就焊了七八个传感器结果数据乱成一锅粥直接弃坑。慢就是快先跑起来比什么都重要。另外外壳最好用带通风孔的3D打印外壳直接把传感器裸露在外面虽然散热好但灰尘积累会影响长期精度得不偿失。本文还有配套的精品资源点击获取
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进