数据采集卡从入门到精通(39):边缘计算部署——树莓派、系统服务与无人值守
实验室的采集系统有人守着,产线和野外的采集节点必须自己活。把"插着USB线的笔记本"变成"挂在配电柜里三年不动的监测站",需要的是一整套部署工程:嵌入式主机选型、Linux服务化、看门狗、远程访问、数据回传。本文给出完整的无人值守方案。全文约4000字。
一、为什么边缘计算:三个真实需求
场景1 车间振动监测站
→ 8通道24小时连采, 数据本地FFT,
只回传特征值(谱峰/总振值)
→ 减少原始数据上传(带宽/存储省99%),
断网时本地照采不误 ★
场景2 野外光伏电站
→ 无线网络不稳定,
节点本地记录+断点续传
场景3 产线测试台
→ 测试节拍紧凑, 判定必须在本地毫秒级完成,
云端只收结果
边缘计算的本质:把"必须快的"(控制、判定、记录)留在本地,把"可以慢的"(分析、汇总、展示)放远端。
二、边缘主机选型
| 方案 | 算力 | 功耗 | 价格 | 定位 |
|---|---|---|---|---|
| 树莓派4/5 | 4核1.5~2.4GHz | 3~7W | 数百元 | 通用王者 |
| 香橙派/国产派 | 类似 | 类似 | 更低 | 成本敏感 |
| 工控机( x86) | 强 | 15~40W | 千元+ | 恶劣环境/ Windows软件遗产 |
| 树莓派CM4/定制 | 灵活 | 低 | 中 | 嵌入式产品化 |
| ESP32等MCU | 弱 | <1W | 十元级 | 简单节点(数据卡自带MCU可担纲) |
选型三问:跑什么(Python+numpy→树莓派级;只转发数据→卡自身MCU即可);环境多恶劣(温度/振动/粉尘→工控机或加固方案);功耗预算(太阳能供电→低功耗设计,逐瓦算)。
树莓派方案的标配:工业级SD卡(或SSD——SD卡在连续写入下寿命是头号故障源)+ 优质电源(5V/3A,电压跌落是树莓派神秘死机的元凶)+ 金属外壳(散热+EMC)。
三、系统服务化:让程序开机自启、崩溃自拉
采集程序不能靠人手ssh进去启动——必须成为系统服务:
# /etc/systemd/system/daq.service
[Unit]
Description=DAQ Monitor
After=network.target
[Service]
Type=simple
User=daq
ExecStart=/usr/bin/python3 /opt/daq/main.py
Restart=always # ★ 崩溃自动重启
RestartSec=5
WatchdogSec=30 # ★ 30s不喂狗→systemd强杀重启
StandardOutput=append:/var/log/daq.log
[Install]
WantedBy=multi-user.target
# 启用:
sudo systemctl enable --now daq.service
sudo systemctl status daq
两个关键配置:Restart=always(进程崩溃5秒后自动拉起);WatchdogSec(配合sd_notify——程序每周期喂狗,主循环卡死则强杀重启——第37篇软件看门狗的系统级实现)。
程序侧喂狗:
import systemd.daemon
while True:
run_one_cycle()
systemd.daemon.notify('WATCHDOG=1') # 喂狗
四、无人值守的六件套
4.1 硬件看门狗(最后一道防线)
软件看门狗防不了内核崩溃。树莓派内置硬件看门狗(bcm2835-wdt):
sudo modprobe bcm2835_wdt
# 程序里周期写 /dev/watchdog (不写→整机重启)
f = open('/dev/watchdog', 'w')
while True:
run_cycle()
f.write('1'); f.flush() # 喂硬件狗
三层看门狗体系:业务层(超限安全态)→systemd层(主循环卡死重启进程)→硬件层(内核死机整机重启)——层层兜底,无人值守的底气。
4.2 存储健康管理
SD卡写穿的预防三策:日志轮转(logrotate限制日志体积)、数据分卷(每小时新文件+自动清理30天前)、只读根文件系统(overlayfs,数据写独立分区——产线级部署的终极方案)。
# logrotate配置示例
/var/log/daq.log {
daily
rotate 7
compress
missingok
}
4.3 远程访问
- SSH(密钥登录、禁密码、改端口——公网暴露的基础卫生);
- VPN/WireGuard回内网(比暴露端口安全得多);
- 远程桌面(VNC/RDP,调试期用);
- Web面板(程序自带简易HTTP页展示状态——最省事的"远程看一眼")。
4.4 数据回传策略
分层数据策略:
① 特征值(每分钟几条) → MQTT/HTTP 实时上传
② 摘要数据(每小时) → 定时批量上传
③ 原始数据(GB级) → 本地保留N天,
按需拉取/定期淘汰
断点续传: 本地队列+上传确认后才删
→ 断网一天, 恢复后自动补传 ★
4.5 时间同步
无人值守节点的时间必须可信(时间戳是数据的骨架):chrony/ntpd定期对时;无网环境用RTC模块(DS3231)+GPS授时(野外站)。
4.6 健康自报告
节点定期上报自身状态(心跳):
# 每60s上报一次心跳
status = {
'ts': time.time(),
'uptime': get_uptime(),
'disk_free_gb': shutil.disk_usage('/').free/2**30,
'cpu_temp': read_cpu_temp(),
'daq_frames': frame_counter, # 帧计数(丢帧监测)
'version': SW_VERSION
}
mqtt.publish('node/daq01/status', status)
# 服务器侧: 心跳超时→告警"节点失联"
心跳里带帧计数与磁盘余量——服务端能提前发现"采集在跑但数据异常"与"存储将满"两类慢性病。
五、完整部署清单(拷贝即用)
□ 硬件: 树莓派+工业SD/SSD+金属壳+3A电源
□ 系统: Raspberry Pi OS Lite(无桌面省资源)
□ 基础: SSH密钥/改端口/静态IP或DDNS
□ 服务: daq.service(Restart+WatchdogSec)
□ 看门狗: 硬件wdt加载+程序喂狗
□ 存储: 日志轮转+数据分卷+空间监控(>80%告警)
□ 时间: chrony对时
□ 回传: MQTT特征值+批量摘要+断点续传队列
□ 心跳: 60s自报告(含帧计数)
□ 远程: WireGuard回内网
□ 测试:
□ 拔网线10分钟→恢复后数据补传✓
□ kill采集进程→5s自重启✓
□ 断电重启→服务自启、采集恢复✓
□ SD写满模拟→清理逻辑触发✓
最后四项破坏性测试是无人值守系统的验收标准——没做过这四项测试的系统,不能叫无人值守,只能叫"还没坏过"。
六、动手实验:30分钟搭建最小节点
# 1) 服务化(上文daQ.service)
sudo systemctl enable --now daq.service
# 2) 心跳脚本
cat > /opt/daq/heartbeat.py << 'EOF'
import time, socket, shutil, json, urllib.request
while True:
s = {'host': socket.gethostname(),
'ts': time.time(),
'disk': shutil.disk_usage('/').free//2**30}
try:
urllib.request.urlopen(
'http://server:8080/heartbeat',
json.dumps(s).encode(), timeout=5)
except Exception:
pass # 断网容忍, 本地继续
time.sleep(60)
EOF
# 3) 破坏性测试三部曲
sudo systemctl kill daq # ① 杀进程→5s自愈
sudo reboot # ② 重启→自启
# ③ 拔网线60s再插 → 心跳恢复+数据补传
七、常见问题FAQ
Q1:树莓派跑采集稳吗?
系统服务化+硬件看门狗+工业SD的配置下,年重启次数个位数——车间的实际表现合格。省钱的SD卡和山寨电源是两大杀手。
Q2:数据断网时怎么保证不丢?
本地优先落盘+上传确认后删除的队列模式——“先保住数据,再谈传输”。
Q3:多个节点怎么管理?
心跳集中监控(Nagios/Zabbix/Prometheus)+配置下发(Ansible)+固件统一版本——节点多了就是运维问题而不是编程问题。
Q4:卡自带的SRAM/Flash记录仪与边缘主机的分工?
卡内记录是"最后一道本地保险"(断主机也不丢);主机负责分析、回传、联动——两层各有兜底。
八、总结
边缘部署三句话:服务化让程序自愈(systemd+看门狗三层)、存储管理让SD长命(轮转+分卷+空间监控)、心跳让远方放心(自报告+断点续传);验收一句话:过不了拔网线、杀进程、断电三重破坏测试的节点,不算无人值守。工程与部署篇完结,下一篇开始三连实战:温度监控系统全案。
下一篇预告:《项目实战一:多通道温度监控系统从接线到报表》
更多推荐


所有评论(0)