树莓派+传感器搭建环境监测系统
2024年5、6月左右,参加了一个物联网比赛(具体哪个比赛记不清了),做了一个基于树莓派4B的环境监测系统,主要面向农业温室场景。最后拿了个省三等奖。
系统功能
- 实时检测温湿度(DHT11)、烟雾、火焰、人体红外。
- 摄像头拍照和录像(报警时触发)。
- 超出设定范围或检测到异常时:蜂鸣器报警、LED闪烁、发送邮件、记录日志。
- 所有传感器数据多线程并发读取,提高响应速度。
硬件连接
树莓派4B通过面包板连接以下模块:
| 模块 | GPIO引脚(BCM) | 功能 |
|---|---|---|
| DHT11 | 16 | 温湿度 |
| 火焰传感器 | 26 | 检测火源 |
| 烟雾传感器 | 20 | 检测烟雾 |
| 人体红外 | 27 | 检测人员 |
| 蜂鸣器 | 13 | 报警 |
| LED(红) | 17 | 报警指示灯 |
传感器供电从树莓派3.3V/5V取,共地。
代码结构
项目目录如下:
shell
基于树莓派4b的环境检测系统
├── buzzer.py 蜂鸣器控制
├── camera.py 摄像头采集(拍照/录像)
├── cell.py 主控逻辑
├── DHT11.py 温湿度驱动
├── flame.py 火焰传感器
├── human.py 人体红外
├── record.py 数据记录(日志、JSON)
├── smoke.py 烟雾传感器
├── us_email.py 邮件发送(QQ邮箱SMTP)
└── 测试.py 临时调试脚本主程序 cell.py 的核心逻辑:
python
import RPi.GPIO as GPIO
import time
import DHT11, smoke, flame, human, us_email, camera, buzzer, record
from concurrent.futures import ThreadPoolExecutor
GPIO.setmode(GPIO.BCM)
dht11_pin = 16
flame_pin = 26
smoke_pin = 20
human_pin = 27
beeper_pin = 13
led_pin = 17
def multithreading(settings, now_time):
with ThreadPoolExecutor() as executor:
future_dht = executor.submit(DHT11.read_dht11, settings[0])
future_flame = executor.submit(flame.detect_fire, settings[1])
future_smoke = executor.submit(smoke.detect_smoke, settings[2])
future_human = executor.submit(human.run_person_detector, settings[3])
future_photo = executor.submit(camera.capture_photo, f"{now_time}.jpg")
# 获取结果
temp, hum = future_dht.result()
flame_ok = future_flame.result()
smoke_ok = future_smoke.result()
human_ok = future_human.result()
photo_path = future_photo.result()
return temp, hum, flame_ok, smoke_ok, human_ok, photo_path遇到过的问题及处理
1. 传感器读数不稳定,尤其是DHT11
DHT11偶尔会读出nan或明显异常值(如温度-50°C)。解决方案:在读取函数中加入校验,如果数值明显超出物理范围,跳过本次数据,使用上一次有效值或等待下一次轮询。
2. 单线程轮询太慢
如果顺序读取每个传感器(先读DHT11(约2秒),再读火焰、烟雾、人体……),一次完整检测需要几十秒。改用ThreadPoolExecutor并发读取后,几秒内就能完成所有检测。超时机制统一设置,一旦某个传感器长时间无响应则跳过。
3. 摄像头录像格式.h264的播放问题
报警时触发摄像头录制5秒视频,保存为.h264格式。比赛期间直接在文件系统中找到视频文件,用VLC或树莓派自带播放器查看。原本打算写一个配套的App来实时查看,但比赛后没有继续。
4. 邮件发送配置(QQ邮箱)
报警邮件通过QQ邮箱的SMTP服务发送。配置如下:
- SMTP服务器:
smtp.qq.com - 端口:
587(TLS) - 密码:使用授权码,不是QQ登录密码。代码中写的是
qhlgnjtybtazdjja(示例,实际已更改)。
没有被拦截为垃圾邮件,可能是因为发送频率不高。
5. 多传感器同时触发时的行为
如果火焰、烟雾、人体同时检测到异常,报警逻辑会:
- 点亮红色LED
- 激活蜂鸣器,持续几秒 → 停止 → 再持续(防止长时间吵闹)
- 录制视频并保存
- 发送包含错误信息、传感器数据、视频路径的邮件
- 写入错误日志
温湿度范围设定
通过DHT11.dht11_range_setting()让用户交互式输入温度(°C)和湿度(%)的上下限。比赛演示时临时设为温度20-30°C,湿度40-70%。实际没有真正部署到农田或温室,只是实验室演示。
最终状态
比赛结束后,代码和硬件都还保留着。没有实地部署过。省三等奖,虽然不高,但这是第一次用树莓派做物联网完整项目,学到了多线程、传感器驱动、邮件通知、异常处理等。
附:代码仅作存档,硬件环境已拆散。如果重新部署需要重新接线和配置SMTP授权码