开篇
前面 6 篇,我们已经实现了:网关 上电 → 采集 Modbus 数据 → MQTT 上传云端。
但真实工业现场一定会遇到:
- 4G 信号差、突然断网
- 网线松动、基站故障
- 云端升级、临时断开
如果没有缓存 + 断点续传,断网期间的数据直接丢失,项目直接验收不通过。
这一篇,我用最简单、最稳定、嵌入式网关最常用的方案,教你实现:断网自动存本地 → 联网自动补发 → 不丢一条数据。这是廉价网关没有、老工程师最值钱、私活必加的加分功能。
一、先讲清楚:断点续传到底是什么?
用大白话讲:
- 网络正常:采集 → 直接上传
- 网络断开:采集 → 存到网关 Flash(相当于本地小硬盘)
- 网络恢复:自动把断网期间存的历史数据,一条一条补发云端
- 存满自动循环覆盖,不会撑爆存储空间
这就是工业网关量产级必备功能。
二、实现思路(超级简单,3 步搞定)
-
定义一条数据结构(时间、地址、电压、电流)
-
写两个函数:
SaveDataToFlash():断网时存本地LoadAndSendHistory():联网时读出来补发
-
主流程加判断:
- MQTT 在线 → 直接发
- MQTT 不在线 → 先存起来
三、数据结构定义(复制即用)
我们要存的就是一条采集记录:
c
运行
// 历史数据结构体(断网缓存用)
typedef struct {
unsigned int timestamp; // 时间戳(什么时候采的)
unsigned char dev_addr; // 设备地址
float voltage; // 电压
float current; // 电流
} HistoryData;
// 最多缓存 1000 条(可根据 Flash 大小调整)
#define MAX_HISTORY 1000
四、核心函数 1:断网时保存数据到本地
c
运行
// 缓存数据到本地(断网时调用)
int SaveHistoryData(HistoryData data)
{
// 1. 获取当前存储位置(循环覆盖,防止撑满)
static int index = 0;
// 2. 写入 Flash / 文件(嵌入式网关通用)
SaveToFlash(index % MAX_HISTORY, &data);
// 3. 下标自增
index++;
return 0;
}
作用:网一断,自动把数据一条条存进去,存满 1000 条从头覆盖,不会死机。
五、核心函数 2:联网后补发历史数据
c
运行
// 联网后,读取所有历史并上传
int SendAllHistoryData(void)
{
int i;
HistoryData data;
for (i = 0; i < MAX_HISTORY; i++)
{
// 1. 从本地读取一条
if (ReadFromFlash(i, &data) < 0)
break;
// 2. 组装JSON上传
BuildHistoryJson(&data);
MQTT_PublishData(PUB_TOPIC, json_buf);
// 3. 延时一下,防止发太快被平台限流
usleep(200000);
}
return 0;
}
六、最终完整网关主逻辑(最强闭环)
这就是真正工业量产网关的代码逻辑:
c
运行
void Gateway_MainTask(void)
{
HistoryData data;
// 1. Modbus 采集(第5篇代码)
Modbus_Collect(&data.dev_addr, &data.voltage, &data.current);
// 2. 打上时间戳
data.timestamp = GetSystemTimestamp();
// 3. MQTT 在线:直接上传
if (MQTT_IsConnected())
{
// 先补发历史数据
SendAllHistoryData();
// 再上传当前数据
Build_JsonData(data.dev_addr, data.voltage, data.current);
MQTT_PublishData(PUB_TOPIC, json_buf);
}
// 4. MQTT 不在线:保存本地
else
{
SaveHistoryData(data);
}
// 轮询间隔
sleep(1);
}
七、新手最容易踩的 3 个坑
1. 不做循环覆盖,Flash 直接写爆
一定要用 index % MAX_HISTORY,循环覆盖,不然设备跑半个月必挂。
2. 补发太快,平台拒收
补发时加 200ms 延时,不然几百条一起发,平台直接判定攻击。
3. 不存时间戳
工业项目必须带时间,否则补发的数据平台不认。
八、本篇总结(一句话)
Modbus 是基础,MQTT 是通路,断点续传才是网关能量产交付的灵魂。
很多年轻开发者只会调通功能,但缓存、断点续传、异常自愈,才是 40+ 老工程师最值钱的地方。
下篇预告
下一篇我们讲 **《网关稳定性保命设计:看门狗 + 内存泄漏防护 + 日志管理》**专门解决:设备跑半个月死机、重启、卡死、不采集、不上传等现场最头疼问题。