搭一个能跑生产的物联网小系统
一、需求:茶水间温湿度“肉眼可见”
行政妹子吐槽:“每次进去都像进了桑拿房。”
于是老板甩给我一句话:“三天内给我实时曲线,预算 100 以内。”
我翻了翻抽屉:
- 树莓派 3B(咸鱼 70 元)
- DHT22 模块(淘宝 15 元)
- 杜邦线若干(库存,算 0 元)
- 5 V 风扇(偷的台式机废旧,算 0 元)
预算 85 元,剩余 15 元请全组喝了蜜雪冰城。
二、协议解析:自己写的最小 TLV
MQTT 当然香,但行政电脑装不了客户端。
我用最简单粗暴的 Type-Length-Value 格式,UDP 广播到局域网:
[1B Type][1B Length][N B Value][2B CRC16]
Type 定义:
| 十进制 | 含义 | 示例 Value |
|---|---|---|
| 0x01 | 温度 | 0x0FA0 |
| 0x02 | 湿度 | 0x12C0 |
| 0x03 | 上线心跳 | 0x0001 |
Python 解码就 6 行:
def parse_tlv(pkt):
if len(pkt) < 4: return None
t, l = pkt[0], pkt[1]
value = int.from_bytes(pkt[2:2+l], 'big')
crc = int.from_bytes(pkt[2+l:], 'big')
if crc16(pkt[:-2]) != crc: return None
return t, value
三、设备接入:三步上线法
为了不让树莓派每次改 Wi-Fi 都要拔卡,我做了“零接触”接入:
| 步骤 | 动作 | 耗时 | 备注 |
|---|---|---|---|
| 1 | 启动 AP 模式 | 10 s | create_ap wlan0 eth0 TeaMon 12345678 |
| 2 | 手机连上后打开 captive portal | 5 s | 纯 HTML 表单,填 Wi-Fi SSID+密码 |
| 3 | 写入 /etc/wpa_supplicant.conf 并重启 |
15 s | 总耗时 30 s |
四、传感器接口:DHT22 的 1-Wire 玄学
DHT22 手册号称 ±0.5 ℃,但我的第一版数据每隔 20 分钟飘一次。
排查表:
| 排查项 | 结果 | 解决 |
|---|---|---|
| 线长 1 m | 5V 供电掉压 | 换成 3.3 V + 上拉 5.1 kΩ |
| GPIO 无中断 | CPU 100 % | 改用 Adafruit_DHT + pigpio 后端 |
| 无屏蔽 | 被微波炉干扰 | 铝箔纸裹住信号线 |
最终采样稳定到 ±0.2 ℃,够用了。
五、Python 开发:327 行主循环
文件结构:
tea-mon/
├─ main.py # 主循环
├─ tlv.py # 编解码
├─ influx_client.py # 写时序库
├─ ota.py # 极简 OTA
└─ boot.py # 开机自动启动
主循环核心 30 行,贴关键:
while True:
t, h = read_dht22()
frame = build_tlv(0x01, int(t*10)) + build_tlv(0x02, int(h*10))
sock = socket(AF_INET, SOCK_DGRAM)
sock.sendto(frame, ("255.255.255.255", 5005))
write_influx(t, h)
check_ota()
sleep(60)
六、数据同步:InfluxDB + 一条 SQL 曲线
本地时序库 InfluxDB 2.7,只开 8086 端口,防火墙内网可见。
查询最近 24 小时平均温度:
from(bucket: "tea")
|> range(start: -24h)
|> filter(fn: (r) => r["_field"] == "temp")
|> aggregateWindow(every: 10m, fn: mean)
Grafana 里拉一条折线图,挂在 42 寸旧电视上,行政妹子终于不用再摸黑猜温度。
七、云端管理:多设备批量升级
虽然只有 3 台树莓派,但还是写了 OTA:
- 打包:
tar czf teamon_v1.2.tar.gz *.py - 上传:私有 GitHub Release(带 token)
- 校验:本地 SHA256 比对
- 回滚:
mv bak/main.py main.py && reboot
实测 30 秒完成静默升级,无人值守。
八、实时数据:WebSocket 推送到 Slack
行政没空盯着电视,于是我加了一个 Slack Bot:
当温度 > 28 ℃ 或 < 18 ℃,自动往 #general 丢一条消息:
🌡️ 茶水间 29.3 ℃,风扇已自动开启。
代码 10 行,用的 Slack Incoming WebHooks。
九、完整成本 & 功耗
| 部件 | 单价 | 功耗 |
|---|---|---|
| 树莓派 3B | 70 元 | 1.2 W |
| DHT22 | 15 元 | 0.05 W |
| TF 卡 32 GB | 25 元 | — |
| 合计 | 110 元 | 1.3 W ≈ 31 Wh/天 |
电费 0.6 元/度,一天 2 分钱,行政表示“比开空调便宜”。
十、踩坑小结(血泪版)
- UDP 广播跨 VLAN 被交换机吃掉 → 改用单播列表 + 轮询。
- DHT22 在 3.3 V 时偶尔 NACK → 上拉电阻从 10 kΩ 降到 4.7 kΩ。
- influx 写爆磁盘 → 开 7 天自动过期策略。
- OTA 回滚忘备份
boot.py→ 远程变砖,抱显示器去机房救场。
附:一键启动脚本
#!/bin/bash
git clone https://github.com/yourname/tea-mon.git
cd tea-mon
sudo apt update && sudo apt install python3-pip pigpio -y
pip3 install adafruit-circuitpython-dht influxdb-client
sudo systemctl enable pigpiod
sudo systemctl start pigpiod
python3 main.py
【结语】
从协议解析到实时数据,这套“奶茶级”物联网系统跑了 5 个月,CPU 占用 2 %,温度误差 ±0.2 ℃,行政妹子再也不吐槽桑拿房。
- 点赞
- 收藏
- 关注作者
评论(0)