基于SHRDZM与太阳能供电的户外PM2.5监测站DIY全攻略 1. 项目概述构建一个自给自足的户外空气监测站几年前为了搞清楚我家附近空气质量随季节和天气变化的真实情况我决定自己动手搭建一个户外颗粒物监测站。核心诉求很简单设备要能长期放在室外不用操心供电和网络布线数据要能本地存储和远程查看最好还能贡献给公共环境数据平台。市面上成品监测仪要么价格昂贵要么数据封闭要么依赖市电都不太符合我的需求。于是一个基于太阳能供电、低功耗传感器节点并通过家庭自动化中枢我用的FHEM进行数据汇聚最终可选推送至OpenSenseMap开源地图平台的方案逐渐成型。这个方案的核心是SHRDZM——一个专为低功耗、多传感器集成而设计的开源设备平台。它就像给传感器装上了“智能电池管理”和“无线通信”大脑让一个简单的PM2.5/PM10传感器如常见的SDS011变身为一台可以独立工作数周甚至数月的野外监测终端。整个系统分为三大部分太阳能供电的传感器节点、负责数据接收的网关/家庭服务器、以及云端数据展示平台。传感器节点负责采集空气中的PM2.5和PM10浓度数据通过低功耗无线方式如LoRa或特定射频间歇性发送网关通常是一个ESP8266模块负责接收并转发数据到本地的家庭自动化服务器如运行在树莓派上的FHEMFHEM进行数据解析、存储和历史记录最后你可以选择将数据同步到OpenSenseMap让监测结果在地图上公开可见。这个方案的优势在于其模块化和灵活性。你可以根据预算和需求选择不同规格的太阳能板和电池传感器也可以更换或增加如温湿度、噪音等。数据完全掌握在自己手中同时又具备与开源社区共享的能力。下面我将从设计思路、硬件选型、软件配置到数据推送一步步拆解这个项目的构建细节并分享我在部署过程中踩过的坑和总结的经验。2. 核心硬件选型与设计思路解析2.1 传感器节点的核心SHRDZM平台与SDS011为什么选择SHRDZM而不是直接用ESP8266开发板连接传感器关键在于功耗。ESP8266在Wi-Fi活跃状态下的电流消耗在70mA以上即使深度睡眠其唤醒、连接、发送数据整个周期的平均功耗对于纯太阳能供电、且需要较高频率如每5分钟一次上报的场景依然压力很大特别是在光照条件不佳的地区。SHRDZM平台的设计哲学是将主控MCU通常是更节能的型号与无线通信模块如LoRa或专用的低功耗射频芯片解耦主MCU和传感器大部分时间处于睡眠状态只有定时唤醒采集数据然后通过极短的时间窗口、低功耗的无线链路将压缩后的数据包发出。这种设计使得整个传感器节点在两次发送间隔内的平均电流可以低至几十微安极大地降低了对太阳能电池板和储能电池的要求。传感器方面我选择了诺方SDS011激光颗粒物传感器。这是一个经过市场长期检验、性价比很高的型号。它通过激光散射原理测量空气中0.3到10微米颗粒物的数量并计算出PM2.5和PM10的质量浓度。其精度对于民用环境监测完全足够且拥有UART串口输出便于与微控制器连接。需要注意的是SDS011本身功耗不低工作电流约70mA因此必须由主控MCU控制其电源仅在测量前通电预热几十秒测量完成后立即断电这是实现整体低功耗的关键操作。注意SDS011的激光管有寿命限制约8000小时。在软件配置中务必设置合理的采样频率如每5或10分钟测量一次避免不间断工作以延长其使用寿命。我的设置是每5分钟唤醒给SDS011供电预热15秒读取20秒的数据取平均然后断电整个活跃窗口约40秒。2.2 供电系统设计太阳能板与电池的平衡艺术供电系统是户外设备稳定运行的基石。设计时需要平衡几个因素设备功耗、当地日照条件、期望的无日照续航时间以及成本。功耗估算首先需要估算设备日均功耗。以我的配置为例SHRDZM主控含射频睡眠电流约20μA每天唤醒288次5分钟间隔。每次唤醒后开启SDS01170mA工作40秒加上主控活跃电流单次循环功耗约为70mA * 40s) ≈ 2.8mAh。每日活跃总功耗约为2.8mAh * 288 ≈ 806mAh。睡眠功耗20μA * 24h≈ 0.48mAh。日均总功耗约807mAh。这是一个非常粗略的估算实际还包括射频发送、电压转换损耗等但可以作为基准。电池容量选择电池需要满足两个需求一是储存太阳能二是应对连续阴雨天。假设我们希望设备在无日照情况下能坚持5天。那么所需电池容量至少为807mAh/天 * 5天 4035mAh。考虑到电池不能完全放电锂电池建议放电至20%-30%即停止以及低温下容量衰减我会选择5200mAh 以上的18650锂离子电池单节标称容量通常为3400mAh两节并联可得6800mAh。并联使用时务必确保电池电压、内阻和型号一致并最好加装平衡保护板。太阳能板功率选择太阳能板的任务是在日照期间为电池充电并补足设备每日消耗的能量。每日需要补充的能量就是日均功耗约807mAh。假设所在地平均有效日照时间为4小时这是一个比较保守的估计需根据地理位置和季节调整那么太阳能板需要提供的平均充电电流为807mAh / 4h ≈ 202mA。考虑到阴天效率下降、充电电路损耗TP4056等线性充电模块效率约80%、以及板子并非一直工作在最大功率点需要留出余量。因此选择标称电流在300-500mA5V输出的太阳能板是合理的。原文提到5瓦5V*1A可能设计过剩我实测下来在光照条件尚可的温带地区一块2-3瓦5V 400-600mA的板子配合6000mAh电池完全可以实现全年不间断运行。实操心得不要盲目追求大功率太阳能板。板子越大成本越高迎风面也越大安装稳定性要求更高。一个更实用的策略是在满足基本充电需求的前提下适当增大电池容量用“储能”来对抗连续的坏天气这往往比一味增大太阳能板更经济可靠。我的配置是6W太阳能板实际是防过设计 两节并联的3400mAh 18650电池在经历了一周连绵阴雨后电池电压仍维持在3.7V以上约剩余40%电量。2.3 网关与服务器轻量级数据枢纽传感器节点发出的数据需要有一个接收器这就是网关。本项目采用集成Style I即网关通过USB直接连接至家庭服务器。网关硬件可以是一个Wemos D1 mini基于ESP8266或NodeMCU。其固件经过特殊编译使其成为一个透明的串口到无线或反之的桥接器。它通过USB从服务器获取电力并通过其无线模块接收来自SHRDZM传感器的数据包再通过USB串口将数据转发给服务器上的软件如FHEM。家庭服务器我选择了树莓派因为它功耗低、24小时运行成本低且Linux系统有丰富的软件生态。上面运行FHEM作为家庭自动化核心。FHEM是一个用Perl编写的开源家庭自动化平台虽然界面复古但极其灵活和强大支持数百种设备协议。它在这里扮演数据聚合器、解析器和存储中心的角色。网关通过USB连接树莓派FHEM中配置一个对应的串口设备模块就能读取到原始的传感器数据报文再通过特定的解析模块SHRDZM.pm将其转换成可读的PM2.5、PM10数值并记录到历史日志中。这种架构的优势是职责分离。传感器只管采集和发送网关只管接收和转发FHEM负责所有的业务逻辑、数据持久化和对外接口。任何一部分升级或更换都不会严重影响其他部分。3. 硬件组装与固件烧录实操指南3.1 传感器节点焊接与组装传感器节点的核心电路并不复杂但焊接和组装时需要格外细心尤其是电源管理部分。所需材料清单SHRDZM传感器节点主板通常为DIY套件或自制PCBESP-12F或类似ESP8266模组用于SHRDZM主控SDS011颗粒物传感器5V/300-500mA太阳能板带USB-A母口或导线TP4056锂电池充电管理模块带保护功能18650锂电池及电池座建议两节并联3.7V转5V升压模块可选如果SHRDZM板载LDO支持3.7V输入则不需要杜邦线、焊锡、导线、防水盒接线步骤与原理太阳能与充电回路将太阳能板的正负极通常红线为正黑线为负连接到TP4056模块的IN和IN-。TP4056的B和B-连接到18650电池的正负极。这里有个关键点TP4056的输出OUT和OUT-是直接连接在电池两端的通过内部电路。所以OUT和B是相通的OUT-和B-也是相通的。这个OUT就是为我们设备供电的电源出口。设备供电回路从TP4056的OUT和OUT-引出电源线连接到SHRDZM主板的电源输入端子。务必确认SHRDZM主板的输入电压范围。如果它支持3.7V-4.2V锂电池电压范围直接输入则可以直接连接。如果它需要稳定的5V或3.3V则需要增加一个DC-DC降压稳压模块如AMS1117-3.3将电池电压稳定到所需值。错误的电压会烧毁主控或传感器。传感器连接将SDS011的串口线TX, RX, GND连接到SHRDZM主板上预留的对应引脚。通常SHRDZM固件会指定某个硬件串口如UART1用于连接SDS011。SDS011的VCC和GND不要直接接在常通电的电源上必须连接到SHRDZM主板的一个受控的GPIO电源输出引脚上。这样MCU才能控制其开关实现低功耗。具体是哪个引脚需要查看你所使用的SHRDZM固件的配置文件或原理图。天线与防水确保SHRDZM的射频天线如果是外置的正确安装并放置在防水盒外部或内部无金属遮挡的区域。所有电路板、接线端子最好用热熔胶或硅胶进行固定和初步防潮处理。最后将整个系统装入尺寸合适的防水接线盒在侧面开孔引出太阳能线、天线并为SDS011的进气口和出气口开孔注意要加装防虫网和防雨罩。踩坑记录我第一次组装时误将SDS011的VCC直接接到了电池正极结果设备待机电流高达70mA电池一天就耗尽了。后来才发现必须通过MCU的GPIO控制供电。另一个坑是防水盒的透气设计如果进气口正对风向或雨淋很容易吸入雨水或形成冷凝。我的解决方案是使用一个“迷宫”式的防雨罩并确保进气口朝下。3.2 固件烧录让硬件“活”起来SHRDZM传感器和网关都需要刷入特定的固件。固件通常是用Arduino IDE或PlatformIO编译的。传感器固件烧录准备环境你需要一台电脑安装Arduino IDE并安装ESP8266开发板支持包。获取代码从SHRDZM的GitHub仓库克隆或下载传感器节点的源代码。配置参数在源代码中你需要修改几个关键配置文件通常是config.h或settings.hSENSOR_ID: 为你的传感器设置一个唯一的ID。RF_CHANNEL和RF_NETWORK_ID: 必须与你的网关设置一致否则无法通信。MEASUREMENT_INTERVAL: 设置测量间隔单位秒如300秒5分钟。SDS011_PIN_POWER: 指定控制SDS011电源的GPIO引脚号。SDS011_WARMUP_TIME: SDS011预热时间单位毫秒建议1500015秒。连接与烧录如果SDS011自带USB转TTL板可以利用它给ESP-12模组烧录。否则你需要一个CP2102或FT232RLUSB转TTL下载器。连接方式为下载器的TX接ESP-12的RX下载器的RX接ESP-12的TXGND接GND。ESP-12的GPIO0引脚需要拉低到GND进入下载模式然后上电。在Arduino IDE中选择正确的开发板如“Generic ESP8266 Module”设置好正确的端口点击上传。验证烧录完成后断开GPIO0与GND的连接重新上电。通过串口监视器波特率115200查看启动日志应该能看到传感器ID、初始化SDS011、进入睡眠等提示信息。网关固件烧录 网关固件烧录更简单因为Wemos D1 mini本身就有USB接口。用Micro-USB线将其连接至电脑在Arduino IDE中选择开发板为“Wemos D1 R2 mini”选择对应的COM口打开网关固件项目直接上传即可。网关固件的配置同样需要确保RF_CHANNEL和RF_NETWORK_ID与传感器端匹配。4. FHEM服务器配置与数据集成详解4.1 FHEM基础安装与SHRDZM网关配置假设你已经在树莓派上安装好了FHEM。通常可以通过包管理器如apt安装或者使用官方提供的便捷安装脚本。连接网关将刷好网关固件的Wemos D1 mini通过USB线连接到树莓派。在树莓派终端输入ls /dev/ttyUSB*或ls /dev/ttyACM*查看新出现的串口设备记下其名称例如/dev/ttyUSB0。在FHEM中定义串口设备登录FHEM的Web界面默认端口8083在命令行输入define SHRDZM_Gateway SerialPort /dev/ttyUSB0115200这创建了一个名为SHRDZM_Gateway的设备连接到指定的串口波特率为115200。加载SHRDZM解析模块SHRDZM的数据包有特定格式需要专门的Perl模块来解析。你需要将下载的SHRDZM.pm文件放入FHEM的模块目录通常是/opt/fhem/FHEM/。然后重启FHEM或者在命令行输入reload SHRDZM关联解析模块现在告诉FHEM用SHRDZM模块来处理SHRDZM_Gateway设备收到的数据attr SHRDZM_Gateway event-on-change-reading .* attr SHRDZM_Gateway room Sensors define SHRDZM_Parser SHRDZM SHRDZM_Gateway这样每当网关收到数据SHRDZM_Parser设备就会将其解析成具体的读数。4.2 传感器配对与数据验证一个网关可以接收多个传感器节点的数据。为了让FHEM正确识别你的颗粒物传感器需要进行“配对”。获取传感器ID传感器上电后网关会收到其广播的包含ID的数据包。在FHEM的SHRDZM_Parser设备日志里你应该能看到类似New SHRDZM device detected: ID 0x1234的消息。记下这个ID十六进制。创建设备关联在FHEM命令行中为这个传感器ID创建一个对应的逻辑设备define My_PM_Sensor SHRDZMSensor 0x1234 attr My_PM_Sensor room AirQuality将0x1234替换为你实际的传感器ID。现在My_PM_Sensor这个设备下应该就会出现PM2.5和PM10等读数单位是µg/m³。数据验证与调试你可以通过get My_PM_Sensor命令查看所有读数。观察数值是否合理。在室内PM2.5通常在10-30 µg/m³之间在通风良好的室外可能更低。你可以用嘴对着传感器吹气模拟高粉尘数值应会急剧上升然后缓慢下降。如果看不到数据检查步骤网关串口是否正确波特率是否匹配115200传感器和网关的RF频道、网络ID是否一致传感器是否在网关的有效通信范围内视天线和环境通常几十到上百米4.3 数据持久化与本地可视化数据进入FHEM后默认只显示当前值。为了绘制历史曲线需要启用日志功能。配置DbLogFHEM通常使用DbLog模块将数据记录到SQLite或MySQL数据库。首先确保DbLog模块已加载。然后创建一个数据库定义这里以SQLite为例define MyLogDb DbLog ./log/SHRDZM.db接着指定哪些设备的数据需要被记录attr My_PM_Sensor logtype MyLogDb使用SVG图形展示FHEM内置了强大的SVG绘图功能。你可以创建一个FileLog另一种日志格式更便于绘图和对应的SVG绘图定义。更简单的方法是使用FHEM的weblink控件或plotly模块来生成更美观的图表。具体配置稍显复杂但网上有大量模板可以参考。配置成功后你就能在FHEM页面上看到PM2.5和PM10随时间变化的曲线图。设置警报你可以在FHEM中设置一些简单的自动化。例如当PM2.5超过75 µg/m³可能表示空气质量不佳时发送一个通知到你的手机通过Telegram或Pushover等通知服务define PM25_Alert notify My_PM_Sensor:PM2.5.* { if ($EVTPART1 75) { fhem(set TelegramBot sendMessage 警告PM2.5浓度过高当前值$EVTPART1 µg/m³) } }这样你就拥有了一个带本地存储、历史回顾和超标警报的完整空气质量监测系统。5. 推送数据至OpenSenseMap公共平台将数据共享到OpenSenseMap可以为开源环境数据地图贡献一份力量也能让你在离家时通过公共网络查看数据。5.1 OpenSenseMap账户与传感器注册注册账户访问OpenSenseMap官网注册一个免费账户。注册传感器登录后在“My Sensors”页面点击“Add new senseBox”。你需要填写以下信息Name: 给你的监测站起个名字如“Home_AirQuality_Backyard”。Location: 在地图上精确拖放标记位置建议精度在10-20米内以保护隐私。Exposure: 选择“户外”等。Add a sensor: 添加两个传感器类型选择“Particulate Matter (PM2.5)”和“Particulate Matter (PM10)”单位选择“µg/m³”。系统会为每个传感器生成一个唯一的Sensor ID务必记下这两个ID后续推送数据时需要。5.2 配置FHEM进行数据推送OpenSenseMap提供HTTP API接收数据。我们需要在FHEM中创建一个虚拟设备定期将My_PM_Sensor的读数通过HTTP POST请求发送出去。创建虚拟发送设备在FHEM中我们可以使用HTTPMOD模块功能强大或简单的notify配合HttpUtils来实现。这里以HTTPMOD为例需先安装该模块define OSM_Sender HTTPMOD http://api.opensensemap.org/boxes/{你的senseBox ID}/data attr OSM_Sender enableControlSet 1 attr OSM_Sender header Content-Type: application/json\r\nAccept: application/json attr OSM_Sender interval 300 attr OSM_Sender readingList .* .*将{你的senseBox ID}替换为你在OpenSenseMap上创建的senseBox的ID。定义数据发送逻辑我们需要一个notify来监听传感器数据更新并构造JSON数据体触发OSM_Sender发送。define Push_to_OSM notify My_PM_Sensor:.* { my $pm25 ReadingsVal(My_PM_Sensor, PM2.5, 0); my $pm10 ReadingsVal(My_PM_Sensor, PM10, 0); my $json [ {sensor: . $SENSOR_ID_PM25 . ,value: . $pm25 . }, {sensor: . $SENSOR_ID_PM10 . ,value: . $pm10 . } ]; fhem(set OSM_Sender sendPost $json); }你需要将$SENSOR_ID_PM25和$SENSOR_ID_PM10替换为之前在OpenSenseMap上获得的两个具体的传感器ID。这个notify会在My_PM_Sensor的任何读数更新时触发获取最新的PM2.5和PM10值构造符合OpenSenseMap API要求的JSON数组然后命令OSM_Sender设备执行一次POST请求。测试与验证手动触发一次更新比如对着传感器吹口气然后在FHEM的OSM_Sender设备日志中查看HTTP请求的返回状态。如果返回201 Created说明发送成功。稍等几分钟刷新你的OpenSenseMap传感器页面应该就能看到最新的数据点出现在图表上。重要提示OpenSenseMap API有速率限制不要设置过短的推送间隔。每5分钟300秒推送一次数据是完全合理的也与常见的传感器测量间隔匹配。在attr OSM_Sender interval 300中我们已经做了限制确保HTTPMOD设备本身不会过快发送。notify是事件驱动的但数据变化频率本身受传感器测量间隔限制所以是安全的。6. 系统优化、故障排查与经验总结6.1 功耗优化与稳定性提升系统搭建完成后长期运行的稳定性至关重要。以下是一些优化点太阳能板清洁与角度定期如每季度清洁太阳能板表面的灰尘和鸟粪。如果条件允许将板子朝向正南北半球并调整一个接近当地纬度的倾角以获得最大年发电量。电池健康监测可以在FHEM中通过读取SHRDZM设备上报的电池电压读数如果固件支持来监控电池状态。设置一个警报当电压持续低于3.5V对于锂电池时发出警告提示可能需要检查太阳能板或电池老化问题。固件看门狗与异常恢复确保使用的SHRDZM固件启用了硬件看门狗WDT。这样即使程序因为未知原因跑飞也能自动重启。在源代码配置中检查#define ENABLE_WDT是否被启用。通信可靠性如果发现数据丢包严重可以尝试1) 调整传感器和网关的位置减少障碍物2) 尝试不同的RF频道避开可能的无线干扰3) 在固件中增加简单的重发机制如果固件支持。6.2 常见问题与排查速查表问题现象可能原因排查步骤与解决方案FHEM中收不到任何传感器数据1. 网关未正确连接或供电。2. 串口配置错误端口号、波特率。3. 传感器与网关RF参数不匹配。4. 传感器未上电或损坏。1. 检查树莓派ls /dev/tty*确认网关设备存在。重启网关或重插USB。2. 确认FHEM中SerialPort设备的波特率设置为115200。3. 核对传感器和网关固件中的RF_CHANNEL和RF_NETWORK_ID是否完全相同。4. 用万用表测量传感器节点电池电压应高于3.5V。靠近网关观察传感器LED如有是否定时闪烁。FHEM中能看到设备但读数全为0或异常1. SDS011传感器未正确初始化或损坏。2. 传感器串口线接反TX/RX。3. 电源控制引脚配置错误SDS011未得电。1. 通过USB-TTL适配器直接连接SDS011到电脑用串口工具如CoolTerm查看是否有数据输出。正常应为一串十六进制数据。2. 交换SDS011与主控板连接的TX和RX线。3. 检查固件中SDS011_PIN_POWER定义是否正确并用万用表测量该引脚在测量期间是否输出高电平。数据推送至OpenSenseMap失败1. 网络连接问题。2. API URL或Sensor ID错误。3. JSON格式错误或值异常。1. 在树莓派上使用curl命令手动测试API连通性。2. 仔细检查FHEM中notify命令里的senseBox ID和Sensor ID是否与官网完全一致。3. 在FHEM命令行用{ReadingsVal(...)}手动输出$json变量内容检查格式是否正确数值是否为“undefined”或异常大数。电池很快耗尽无法坚持阴天1. SDS011电源未受控常开。2. 太阳能板功率不足或损坏。3. 电池本身容量衰减或质量差。4. 设备存在其他漏电。1. 用万用表串联测量设备静态电流睡眠时应低于1mA。若过高重点检查SDS011的VCC电压。2. 在晴天正午测量太阳能板开路电压和短路电流是否接近标称值。3. 将电池充满后单独用电子负载测试实际容量。4. 逐一断开外围元件查找漏电源头。测量数值长期偏高或偏低1. SDS011传感器需要校准或已老化。2. 进气口被灰尘、昆虫或雨水堵塞。3. 安装位置不当靠近污染源或通风死角。1. SDS011有一定误差可与另一个靠谱的检测仪进行对比测试。激光传感器无法校准偏差过大只能更换。2. 定期每半年打开防水盒用压缩空气清洁SDS011的进气通道和风扇。3. 将传感器安装在离地1.5-2米远离墙壁、空调外机、厨房排气口的位置保证空气自由流通。6.3 项目扩展与进阶玩法这个基础框架有巨大的扩展潜力增加更多传感器SHRDZM平台支持多路数字/模拟接口和I2C总线。你可以轻松添加BME280温湿度气压、SGP30TVOC/eCO2、噪音传感器等打造一个综合环境监测站。只需在固件中启用对应传感器的驱动和配置并在FHEM中解析新的数据字段即可。更换通信方式如果传输距离需要更远1公里可以考虑将射频模块替换为LoRa。SHRDZM也支持LoRaWAN你可以将数据发送到The Things Network (TTN)这样的公共LoRaWAN网络再通过TTN集成转发到你的FHEM或其他服务器实现超远距离、超低功耗的数据回传。使用Grafana打造高级仪表盘虽然FHEM自带绘图但Grafana在数据可视化上更加强大和美观。你可以配置FHEM将数据写入InfluxDB时序数据库然后用Grafana连接InfluxDB创建包含多种图表、仪表盘和警报的豪华监控界面。集成到更广泛的智能家居场景当PM2.5超标时FHEM可以自动关闭窗户如果安装了智能窗器并打开空气净化器。实现真正的环境感知与联动控制。构建这样一个系统最大的收获不是最终那几个读数而是从电源管理、无线通信、嵌入式编程到服务器运维、数据集成这一整套物联网技术栈的实践。它教会你在资源受限的条件下如何权衡与设计也让你对自己所处的微观环境有了前所未有的数据化认知。当你在OpenSenseMap上看到自己贡献的数据点与全球其他站点的数据汇聚在一起时那种参与开源科学的感觉远比购买一个成品设备来得有意义。