PLC 数据采集不稳定,九成出在三个地方:轮询周期拍脑袋定、一主多从不排队、断线后没有重连和数据补偿。解决起来不复杂——数据按变化快慢分级采集、批量读代替逐个点读、通信层做超时重试和质量标记。协议上,新系统选 OPC UA 或 S7 / MC 原生协议,老设备用 Modbus,现场总线再交给网关去转。
一、先选对通讯协议:四条主流路线
| 协议 | 适用设备 | 特点 | 主要坑点 |
|---|---|---|---|
| Modbus TCP/RTU | 通用仪表、各品牌 PLC | 简单通用、好上手 | 要自己管轮询、功能码 |
| S7 / S7CommPlus | 西门子全系列 | 直连 DB 块、效率高 | 优化块、PUT/GET 设置 |
| MC 协议 / SLMP | 三菱 Q / L / FX5U | 三菱原生、点位直接 | 帧格式、二进制 / ASCII |
| OPC UA | 新设备、跨品牌 | 可订阅、带安全模型 | 证书、老设备不支持 |
选型原则其实不绕:单品牌固定选原生协议直连;多品牌混用、以后还想扩展,上 OPC UA;现场仪表和低成本设备,交给 Modbus。别为了听起来先进,给所有设备硬上 OPC UA,老网关和小 PLC 根本扛不住那个开销。
二、轮询周期怎么定?按数据快慢分级,别一刀切
见过不少程序,所有点位都 100ms 刷一遍。CPU 和网卡全占满,数据反而时快时慢,画面还一卡一卡。靠谱的做法是分级:
- 快速状态(运行、急停、关键计数):200~500ms;
- 工艺参数(温度、压力、转速):1~2 秒;
- 统计 / 配置(班次、参数表):分钟级,或者只在变化时读。
// 采集点定义:地址、周期、值、时间戳、质量五件套 class TagDef { public string Addr; public int PeriodMs; public object Value; public DateTime Ts; public Quality Q; // Good / Uncertain / Bad }
还有一条很省资源:能订阅就别轮询。OPC UA 的 MonitoredItem 只在数据变化(再加个死区过滤)时推送,通信量能降一个数量级。调度器再把同周期、同设备的点合并成一次批量读,比如西门子 DB 块整块读,这是性能上最关键的一步。
三、一主多从怎么排?一个通道配一个队列
Modbus RTU 一主多从最容易堵:所有请求共用一条 485 总线,必须排队、错峰,谁也别插队。几个硬规矩:
- 每个通信通道配一个请求队列,发一条、等一条、超时再发下一条;
- 从站按地址轮询加超时退避,出故障的站先跳过,但不能一直饿死;
- 走 TCP 也别开多线程同时猛连一台 PLC,连接数有限,用单连接复用最稳。
我之前处理过一条印染线,三个线程同时往同一台 S7-1200 写数据,通信灯狂闪、数值乱跳,现场怎么都查不出毛病。后来改成单通道队列、写操作带回执,立刻就正常了。这类问题看着像网络故障,根子其实在软件排队上。
四、丢包和断线:重连、补偿、质量戳一个不能少
把"采没采到"本身也当成数据,每个点至少带上两样:时间戳(采集那一刻,所有设备 NTP 对时)和质量戳(Good / Uncertain / Bad)。通信层再补上这些机制:
// 安全读取:超时重试若干次,指数退避,全失败就标 Bad object SafeRead(TagDef t) { var backoff = new[] { 500, 1000, 2000 }; for (int i = 0; i < 3; i++) { try { return _plc.Read(t.Addr); } catch { Thread.Sleep(backoff[i]); } } t.Q = Quality.Bad; return null; }
- Socket 加心跳,读超时建议 1~3 秒,重试 2~3 次;
- 断线按指数退避重连(1s → 2s → 4s 封顶),连上之后重新订阅;
- 关键报警变化先在边缘网关本地缓存,恢复后再补传;
- 长时间 Bad 的数据界面明确标灰,绝不能拿旧值冒充新值。
五、一套稳定的数据采集系统,架构长什么样
比较经得起现场折腾的链路是:现场 PLC / 仪表 → 边缘采集网关(协议解析、轮询调度、本地缓存)→ MQTT / OPC UA 上抛 → 实时库 / 历史库 / MES。还有几个容易被忽略、但后期很要命的点:
- 点位表配置化,地址改动改配置就行,不动代码;
- 网段隔离,采集网卡和办公网分开,别让车间设备暴露在公网;
- 写操作和读操作分开通道,写必须带回执和回读校验;
- 记录通信日志:超时次数、重连次数都存下来,出问题有据可查。
现在就能排查的一件事:打开你的采集程序,挑 5 个关键点位,记录它们在 30 分钟内的实际刷新间隔和超时次数。如果间隔忽长忽短、超时频繁,问题基本就在轮询调度和通道复用这两处。先把周期分级和单通道队列做掉,稳定性的提升,往往比换协议、加硬件来得快得多,也便宜得多。
