Modbus RTU
串行总线上的 Modbus,物理线路被显式建模出来,由它上面那些按从站 ID 寻址的设备共用。
Modbus RTU 驱动和串行总线上的 Modbus 设备对话,总线是 RS-485 或 RS-232,通过一个物理 COM 端口、一个 USB 适配器或者一个虚拟/重定向端口够到。因为总线在物理上是共用的,所以拓扑是驱动 → 线路 → 设备 → 点位:线路拥有一切与电气有关的东西(端口、波特率、格式、时序),而它上面的每一台设备只拥有自己的从站地址、轮询和点位。
串行线路
| 字段 | 含义 | 默认值 |
|---|---|---|
| 名称 | 这条总线的友好名称。任何时候都能改。 | 必填 |
| 串口 | 操作系统的端口,例如 COM3。这个字段是自由文本,物理端口、虚拟端口和重定向端口都能用,旁边的箭头会提供 Windows 当前检测到的那些端口(并带一个刷新,供适配器热插拔时用);检测出来的列表只是方便,绝不是白名单。 |
COM1 |
| 波特率 | 总线上每台设备共用的位速率。 | 9600 |
| 串行格式 | 封闭的选项:8N1、8N2、8E1、8E2、8O1、8O2;数字是数据位,字母是校验(N 无校验,E 偶校验,O 奇校验),最后一位是停止位。别的位宽、mark/space 校验和 1.5 位停止位都不支持。 |
8E1 |
| 响应超时(毫秒) | 等一台从站应答的最长时间,100 到 60000。超时放长能迁就慢设备,但也让缺席的从站和设备发现更慢才认得出来。 | 1000 |
| 最小事务间隔(毫秒) | 全线通用的兼容性节奏,0 到 1000。填零就只保留协议自动的那段静默;填正数只会抬高它,绝不会缩短它。 | 0 |
协议本身要求帧与帧之间有静默,线路始终把这段静默执行到位:波特率在 19200 及以下时,自动静默是按配置的格式算出来的 3.5 个字符时间;高于 19200 时,则是规范建议的固定 1.75 毫秒。实际生效的静默取那个自动下限和配置的间隔中较大的那个,绝不是两者相加,面板会把两个值都显示出来。把间隔抬高就是有意让线上每一台从站都慢下来;它是一种兼容性辅助手段,不是用来修接线、终端电阻、接地或干扰问题的。
新线路一开始是已禁用的,好让它的物理设置先配好。每个物理端口最多属于一条线路,比较时不区分大小写,即使那些线路都禁用着也一样。线路跑着的时候,名称和事务间隔仍然可以改(改时序不必让端口重新开合就生效);端口、波特率、格式和响应超时在线路启用期间锁住,要改就先禁用并保存。禁用一条线路会停掉它所有设备的通信,但不改动它们各自的“已启用”选择。
线路把物理传输和它的设备分开报告:已关闭、空闲(没有已启用的设备)、正在连接、在线,或者带诊断文字的端口故障。删掉一条空线路只删这条线路;删掉一条有设备的线路会要求你明确确认,并把那些设备和它们的点位一并删掉。
设备
| 字段 | 含义 | 默认值 |
|---|---|---|
| 串行线路 | 固定:设备是在它的线路下面创建出来的,并继承那组物理参数,在面板里显示为只读。请把设备加在你想要的那条线路下面。 | 无 |
| 从站 ID | 这台设备在总线上的 Modbus 地址,1 到 247,在线路内部唯一(已禁用的设备也算在内)。 | 1 |
| 轮询间隔(毫秒) | 没有自己另作规定的点位所用的默认轮询速率。 | 1000 |
运行时内部的地址是 modbus+rtu://<line-id>/<port>/<baud>/<format>/<timeout>/<unitId>/<interval>:它带的是线路稳定的身份和完整的物理设置,绝不是它的友好名称。
共用线路的行为
驱动每条线路开一个串行会话,并把来自每台设备的每一个请求都通过一个调度器串起来,所以总线上的读和写绝不重叠。等着写的请求会以有上限的优先级拿到下一个空闲的轮次:写入被及时服务,但持续不断的写入也饿不死轮询。每台从站的超时是彼此隔离的,并带渐进退避,所以一台沉默的设备只拖慢它自己。一个 CRC 校验通过的 Modbus 异常,是那个点位上一次请求的错误,线路仍然健康。只有物理 I/O 故障(端口消失、适配器被拔掉)才会让共用会话失效,并为整条线路发起一次协调好的重开。最后一台设备释放时,端口关掉。
点位寻址
点位寻址和 Modbus TCP 完全一样:一个寄存器类别(HoldingRegister、InputRegister、Coil、DiscreteInput,默认由点位的类型和读写推出来)、一个从 0 起的寄存器号、一个自动的数量(布尔 1 个寄存器,Int32 和 Float 2 个,文本 4 个;这个框只在文本点位上画出来,因为其余每一种宽度都是定死的),以及两个互不相干的字节序框,都默认为高位在前。支持的数值类型是同样那四种,Boolean、Int32、Float 和 String,而读写用的功能码和四种总线排布在 Modbus TCP 页面上讲,这里原样适用。
设备发现
设备发现在一条已有线路上探测一段从站 ID 范围,它住在那条线路的面板上:
| 字段 | 含义 | 默认值 |
|---|---|---|
| 起始从站 ID | 第一个要探测的从站 id,1 到 247。 | 1 |
| 结束从站 ID | 最后一个从站 id,从起点往上递增。 | 32 |
扫描会重新载入线路已保存的物理设置,把端口打开一次,然后用“读取基本设备识别”(功能码 43/14)按顺序探测这段范围,每一次探测都按线路实际生效的帧间静默来定节奏。它从不去试各种设置组合,也从不读寄存器。一个 CRC 校验通过的 Modbus 异常足以证明有这台从站,只是说不出它的身份;一次超时或者一个无效帧则证明不了。
一条正在使用的线路绝不会被自动打断或自动开关:请在扫描前先禁用它,扫描完之后再由你自己把它启用回来。取消会关掉串行会话,并把已经显示出来的结果留作临时候选项,直到你明确把它们加进来为止。已经配置过的从站 id 会被标出来,并打开已有的那台设备,而不是造一个重复的;结果不带点位,寄存器是在添加之后再配置的。
设备发现和线路配置对每个物理端口共用一份快速失败的占用登记,所以一次扫描和一次改设置不会为端口打起来:输的那一方会被告知是哪一项操作占着它。
值得知道的限制
- 那四种数值类型就是总线编解码的全部词汇;不提供宽整数和 Double。
- 吞吐是总线的属性:线上每一台设备共用同一条请求流,节奏由实际生效的帧间静默决定,所以设备一多,或者间隔一抬高,每一轮轮询周期都会变长。