冯工聊数采NodeSCADA · 工控老兵手记 · Modbus 数采 工业网络
明明配置的时候采集正常,刚离开项目,客户很快打来电话说采集不了了。你是否遇见过这种情况呢
今天说的是那种让你改了好几遍遍程序、换了不同设备、打了一圈电话,最后发现是网络层问题的那类坑。做数采这行做久了,你会发现 Modbus TCP 本身其实很简单,但现场环境复杂起来,它能给你折腾出各种幺蛾子。
一、TCP 长连接,它不稳
之前做 Modbus TCP 会选长连接,觉得省事。建一次连接,反复轮询,挺好。但问题就出在这里——TCP 本身没有应用层心跳,连接在操作系统层面看着是通的,实际上对端早就没响应了。
我遇到过一个场景:车间里有台老式施耐德变频器,做 Modbus TCP 从站。服务器轮询一切正常,但每隔两三天,采集程序就"假死"——不报错,也不断开,就是不采数据。重启进程恢复正常。
排查了很久。抓包发现,TCP 连接在对端设备静默之后,客户端没有收到 RST 也没有收到 FIN,连接在操作系统 keepalive 没配置的情况下会无限挂着。Modbus TCP 的事务标识符早就轮转了一圈,对端反正也不回复,进程就堵死在那里。
排查建议:先看你的 socket 超时有没有在应用层设置。光靠系统默认的 TCP keepalive 不够用,工业设备的实现参差不齐,有些从站在负载稍高时会长时间不响应但不主动断开。建议在请求层面加强制超时,每帧响应等待不超过 1.5~2 秒(这个得看现场网络条件,有时候真的挺慢的,但是能采,就设置的久一些),超时主动断线重连,比傻等强得多。
二、交换机的端口隔离,采集工程师的容易忽略的坑
这个问题在新建厂区比较常见。IT 部门或者集成商交付的工业交换机,出于安全考虑,设备接入端口配了 PVLAN 或者端口隔离,同一个 VLAN 内的设备互相不通,只能走到上联口。
症状很迷惑:ping 网关通,ping 对侧设备不通,但你用网络分析工具扫,设备 IP 是存在的。从采集服务器发出去的 TCP SYN 包直接石沉大海,不回 SYN-ACK,也不回 RST。
不懂交换机的人能在这里耗一整天。
类似的还有工厂防火墙 ACL 规则漏配——Modbus TCP 默认端口 502,有些防火墙模板里没有放行这个端口,采集连不上设备,但 ping 是通的,因为 ICMP 和 TCP 是两回事。
可以使用 windows 自带的 telnet 工具去测试端口的 tcp 连接是不是真的通。只有 telnet 的 tcp 连接通了,才算是网络通
三、高并发轮询的性能陷阱
数采点位一多,轮询并发上来,很多从站设备就开始不稳定——偶发超时、偶发响应错误码。
Modbus 协议本身是一问一答的半双工模式,即使跑在 TCP 上,大多数设备的从站实现也不支持真正的多请求并发。你同时发两个请求,设备处理完第一个才会看第二个,或者直接丢弃后来的。
做高密度数采,合理的策略是:。
2. 寄存器地址尽量连续,合并读取。 能用一帧读多个寄存器,就别分请求,比如有的布尔值都是在同一个寄存器里,直接用 16位数字读取出来,然后解析。Modbus 每次请求的建立和等待开销是固定的,拆碎了采效率极低。
3. 区分采集频率。 不是所有点位都需要秒级采集。产量、温度、压力,刷新周期按需配,别一股脑都设置成高频采集,写程序时或者配置采集软件选用哪种支持各个点位不同频率的。

现在我在用 NodeSCADA 做数采,它在这块处理得比较合理——每个连接器的轮询是独立的,每个点位支持单独设置采集。点位多了不用手动去算怎么区分,省了不少事。(nodescada.cn,有兴趣可以去看看文档)
四、从站返回异常码,不等于设备坏了
Modbus 异常响应码是有标准定义的,但现场设备实现差异很大。碰到 0x02(Illegal Data Address)或者 0x03(Illegal Data Value)不要慌着换设备。
见过一个案例:读某品牌仪表的浮点值,地址 0x0064,文档写的是双字寄存器。结果用功能码 03 读 2 个寄存器,偶发返回 0x02。查了很久,最后发现是那台仪表固件的一个 bug:当上一次请求还在内部处理时,下一个请求进来,它就返回地址非法。把轮询间隔从 500ms 拉到 1200ms,问题消失。
异常码只是从站告诉你"我现在处理不了",原因五花八门——地址范围、功能码支持、处理能力、内部状态……遇到要对着设备手册慢慢排,不用上来就怀疑是自己的问题。
写了这么多,核心意思其实就一句:Modbus TCP 的坑,大多数不在协议本身,在现场环境和设备实现。
见得多了就有感觉了。遇到怪问题别急着换方案,先抓包,先看日志,再逐层排查。
有什么具体场景欢迎评论区说,我尽量回。
冯工聊数采NodeSCADA · 持续更新工控数采实战经验

436

被折叠的 条评论
为什么被折叠?



