3、超时参数设计:响应超时、帧间隔超时、连接超时

好,咱们进入正题。超时参数设计,这玩意儿看着简单,但坑特别多。我见过太多项目,通讯不稳定,最后查来查去,就是超时参数设得不对。

说白了,Modbus 通讯里就三种超时:响应超时帧间隔超时连接超时。它们各管各的事,千万别搞混。

3.1 响应超时(Response Timeout)

这个最直观。主站发了个请求,从站得在规定时间内回复。过了这个时间没回,主站就认为这次通讯失败了。

那这个值设多少合适?

我个人习惯,先看从站的典型响应时间。比如一个 PLC,它扫描周期是 10ms,那响应时间至少得 20ms 以上。但你不能只算这个。

  • 物理层延迟:串口波特率越低,传输时间越长。9600 波特率下,传一个 8 字节的帧,光传输就要 8ms 左右。
  • 从站处理时间:有些老设备,处理一个请求要 50ms 甚至 100ms。
  • 网络抖动:如果是 Modbus TCP,还得考虑网络延迟和丢包重传。

经验公式:

响应超时 = 从站最大处理时间 × 2 + 最大传输时间 × 2 + 安全余量(50~100ms)

嗯,这里要注意。别把响应超时设得太小。我曾经在一个项目里,把超时设成了 20ms,结果从站偶尔处理慢一点,就疯狂超时重试,把总线都占满了。

避坑指南:

我曾经遇到过,把响应超时设得和帧间隔超时一样大。结果帧间隔超时先触发了,把正常的数据帧当成了错误帧处理。这两个参数一定要拉开差距。

3.2 帧间隔超时(Inter-frame Timeout)

这个参数,很多人容易忽略。它管的是:两个 Modbus 帧之间的最小间隔时间

为什么要设这个?因为 Modbus 是半双工通讯。主站发完一帧,从站得等一段时间才能发下一帧。反过来也一样。这个间隔时间,就是为了让总线上的设备有时间切换收发状态。

标准规定:

通讯模式 帧间隔时间
Modbus RTU ≥ 3.5 个字符时间
Modbus ASCII ≥ 1 个字符时间
Modbus TCP 通常不需要(TCP 流控制)

你想想看,3.5 个字符时间怎么算?以 9600 波特率、8 数据位、1 停止位、无校验为例:

一个字符时间 = (1 起始位 + 8 数据位 + 1 停止位) / 9600 = 1.04ms
帧间隔时间 = 1.04ms × 3.5 ≈ 3.65ms

但实际项目中,我建议把这个值设得比理论值大一点。为什么?因为有些 USB 转串口线,或者虚拟串口,它的时序不太准。设成 5ms 甚至 10ms,更稳妥。

我的经验:

在调试阶段,我会把帧间隔超时设得稍微大一点(比如 20ms),等通讯稳定了,再慢慢调小。这样能快速定位到底是帧间隔问题,还是其他问题。

3.3 连接超时(Connection Timeout)

这个主要针对 Modbus TCP。它管的是:建立 TCP 连接的最大等待时间

Modbus TCP 通讯,第一步就是建立 TCP 连接。如果从站没开机、IP 地址不对、或者防火墙拦了,TCP 三次握手就完不成。这时候就需要连接超时来兜底。

连接超时设多少?

  • 局域网环境:通常 1~3 秒就够了。局域网延迟很小,1 秒内连不上,基本就是连不上。
  • 跨网段或公网:建议 5~10 秒。网络延迟大,丢包多,需要多点时间重试。
  • 工业现场:我个人习惯设 3 秒。太短了容易误判,太长了影响故障恢复速度。

重要提醒:

连接超时和响应超时是两码事。连接超时只管 TCP 握手阶段。一旦连接建立成功,后续的通讯超时就归响应超时管了。别把它们混在一起算。

我记得有一次,现场有个从站偶尔会掉线。我把连接超时设成了 1 秒,结果每次掉线后重连都要等 1 秒,感觉太慢了。后来改成 500ms,重连速度快了一倍,而且也没出现误判。

3.4 三个超时的协同设计

这三个超时不是孤立的。它们得配合好,才能让整个通讯系统稳定高效。

我推荐的设计原则:

  1. 帧间隔超时 < 响应超时 < 连接超时。这个顺序不能乱。
  2. 帧间隔超时:按标准值设,或者稍微大一点(1.5~2 倍)。
  3. 响应超时:根据从站性能动态调整。快的从站设小点,慢的设大点。
  4. 连接超时:固定值,一般 3~5 秒。除非网络环境特别差。

避坑指南:

我曾经见过一个项目,把三个超时都设成了 1 秒。结果帧间隔超时和响应超时同时触发,系统完全乱套了。记住,它们要有明显的层级关系。

好了,超时参数设计就讲到这里。下一章咱们聊聊重试策略——超时之后怎么办?是立即重试,还是等一会儿再试?这里面也有不少门道。