1. 项目概述:打造智能环境监测终端
去年工作室装修时,我发现自己经常被三个问题困扰:不知道室内温湿度是否适宜、无法判断新风机过滤效果、每次查看数据都要走到设备跟前。于是用周末时间做了这个能同时监测温湿度与PM2.5浓度,并通过WiFi实时上传数据的小装置。整套系统成本不到200元,但实现了商业级监测设备80%的功能。
这个设计特别适合需要持续监控环境质量的场景,比如智能家居中的婴儿房监护、实验室环境记录、办公室空气质量监测等。核心功能模块包含:
- DHT22温湿度传感器(精度±0.5℃)
- 攀藤PMS5003激光PM2.5传感器
- ESP8266 WiFi模块
- Arduino Uno主控板
2. 硬件选型与电路设计
2.1 传感器选型对比
在环境监测项目中,传感器精度直接决定数据价值。我对比了市面上常见的三种方案:
| 传感器型号 | 温湿度精度 | PM2.5检测原理 | 单价 | 功耗 |
|---|---|---|---|---|
| DHT11+BME280 | ±2℃/±5%RH | 无 | 35元 | 1.2mA |
| DHT22+PMS5003 | ±0.5℃/±2%RH | 激光散射 | 85元 | 80mA |
| SHT31+SM-UART-04L | ±0.2℃/±1.5%RH | 红外原理 | 210元 | 45mA |
最终选择DHT22+PMS5003组合,因为:
- 温湿度精度满足民用需求
- 激光式PM2.5检测比红外更准确
- 总价控制在百元内
特别注意:PMS5003工作时需要较大电流(峰值100mA),建议单独供电或配置470μF以上的滤波电容
2.2 电路连接要点
主控板采用Arduino Uno Rev3,其5V输出足够驱动所有模块。关键连接方式:
arduino复制// 温湿度传感器
DHT22 DATA → Arduino D2
// PM2.5传感器
PMS5003 RX → Arduino TX
PMS5003 TX → Arduino RX
// WiFi模块
ESP8266 TX → Arduino RX
ESP8266 RX → Arduino TX
实际接线时踩过两个坑:
- PMS5003的串口与ESP8266共用Arduino的硬件串口,必须通过SoftwareSerial库创建虚拟串口分流
- DHT22数据线需要接4.7K上拉电阻,否则可能读取失败
3. 核心代码实现解析
3.1 多传感器数据采集
使用非阻塞式编程避免传感器读取阻塞主线程。关键代码结构:
arduino复制#include <SoftwareSerial.h>
SoftwareSerial pmsSerial(3, 4); // RX,TX
void setup() {
Serial.begin(9600);
pmsSerial.begin(9600);
}
void loop() {
static uint32_t lastRead = 0;
if(millis() - lastRead > 2000){ // 每2秒读取一次
readDHT22();
readPMS5003();
lastRead = millis();
}
handleWiFi(); // 持续处理网络连接
}
PM2.5传感器数据解析需要特别注意校验和计算:
arduino复制bool verifyChecksum(uint8_t *data) {
uint16_t sum = 0;
for(int i=0; i<30; i++) sum += data[i];
return (sum == (data[30]<<8)+data[31]);
}
3.2 WiFi数据传输方案
选用ESP8266的AT指令模式实现TCP长连接,比HTTP请求更稳定。建立连接的关键步骤:
- 发送AT+CWMODE=1设置STA模式
- AT+CWJAP="SSID","password"连接路由器
- AT+CIPSTART="TCP","api.thingspeak.com",80
- 循环发送AT+CIPSEND=xx指定数据长度
实测发现两个优化点:
- 添加AT+CIPRECONNINTV=5000自动重连
- 每次发送前检查AT+CIPSTATUS连接状态
4. 数据可视化与报警系统
4.1 云端平台对接
选用ThingSpeak平台存储数据,主要考虑:
- 免费账户支持4个字段/15秒更新
- 自带Matlab分析工具
- 可通过webhook触发报警
数据上传格式示例:
code复制GET /update?api_key=XXX&field1=23.5&field2=55&field3=12
4.2 本地报警策略
当PM2.5超过阈值时,通过蜂鸣器+LED双重提醒:
arduino复制void checkAlert(float pm25) {
static bool alerting = false;
if(pm25 > 75 && !alerting) {
digitalWrite(LED_PIN, HIGH);
tone(BUZZER_PIN, 1000, 500);
alerting = true;
}
else if(pm25 < 50 && alerting) {
digitalWrite(LED_PIN, LOW);
noTone(BUZZER_PIN);
alerting = false;
}
}
5. 功耗优化与长期运行
5.1 电源管理技巧
使用9V电池供电时,通过以下手段延长续航:
- 修改ESP8266的AT+SLEEP=2进入轻睡眠模式
- 将传感器采样间隔调整为5分钟
- 关闭Arduino的板载LED(修改bootloader)
实测电流消耗对比:
| 模式 | 工作电流 | 休眠电流 |
|---|---|---|
| 初始方案 | 85mA | 45mA |
| 优化后 | 20mA | 0.5mA |
5.2 数据补发机制
添加本地SD卡缓存,当网络中断时暂存数据:
arduino复制void saveToSD(float temp, float humi, float pm25) {
File dataFile = SD.open("datalog.txt", FILE_WRITE);
if(dataFile) {
dataFile.print(millis());
dataFile.print(",");
dataFile.print(temp);
dataFile.print(",");
dataFile.println(pm25);
dataFile.close();
}
}
网络恢复后优先上传缓存数据,按时间戳排序避免乱序。
6. 常见问题排查指南
6.1 传感器读数异常
现象:PM2.5值持续为0
排查:
- 检查传感器风扇是否转动
- 测量VCC电压是否≥4.5V
- 用逻辑分析仪抓取串口数据
现象:温湿度数据跳变
解决:
- 给DHT22增加0.1μF去耦电容
- 避免将传感器放置在空调出风口
6.2 WiFi连接不稳定
日志分析:
code复制[WiFi] Connecting...
[WiFi] Failed (1)
[WiFi] Connecting...
[WiFi] Connected (3s)
优化方案:
- 修改AT+CIPRECONNINTV=3000
- 添加AT+CWJAP_CUR保存多组SSID
- 更换为ESP-07S外接天线版本
7. 项目进阶方向
这套系统我已经稳定运行8个月,期间做过三次重要升级:
- 多节点组网:通过MQTT协议实现5个监测点数据汇总
- 预测算法:基于历史数据建立ARIMA模型预测PM2.5变化
- 联动控制:当PM2.5超标时自动开启空气净化器(通过红外发射)
最近正在尝试用TensorFlow Lite实现边缘端异常检测,替代简单的阈值报警。虽然Arduino性能有限,但经过量化的模型已能实现90%的准确率。