Skip to content

Modbus 设备配置 ​

平台的 Modbus 连接器(服务名 modbus)作为 Modbus-RTU / Modbus-TCP 主站,与仪表、电源、采集模块、板卡等支持标准 Modbus 的从站设备通信。接入分两步:先在工位页面绑定设备(串口或 IP、从站地址、地址基准、字节序),再在仪器指令库按「数据区 + 地址 + 类型」写指令模板。

模板长这样,功能码由连接器自己推导,不用填:

text
HR:100;FLOAT:CDAB          读保持寄存器 100 起的 2 个,按字交换解析成浮点
HR:200=5                   写 5 到保持寄存器 200
CO:0=1                     线圈 0 置 ON

记住三条判据就够了:

看到什么结论
请求里有 =这是写(RW: 例外,带 = 但按读处理)
开头是 HR / IR / CO / DI数据区,决定用哪个功能码(也可以直接写手册的 Modicon 编号,如 40101)
分号后面的一段解析段,决定读回来的字节怎么变成数字

本文以一台虚构的 DEMO_PM100 功率计(RS485,9600 8N1,从站地址 1)贯穿示例,写哪条指令直接对照第 11 节速查表复制即可。

相关页面:ATEBOX 485 连接说明、PMBus 设备配置、UDS 设备配置、PLC 设备配置、WAVESHARE 适配器配置。

1. 先备好点表这几项 ​

从设备手册(或厂家给的点表)里抄下这几项,后面每一步都要用:

项目说明示例
传输方式串口 RTU 还是以太网 TCPRTU(RS485)
从站地址设备的 unit 号,1 ~ 2471
数据区线圈、离散输入、输入寄存器、保持寄存器保持寄存器 HR
地址手册原样抄下来,写法见 1.240001
数据类型16 位、32 位、浮点、BCD、字符串FLOAT,占 2 个寄存器
字节序多字节数值的排列方式字交换 CDAB

1.1 四个数据区与功能码 ​

数据区前缀手册地址段读写单元
线圈(DO)CO00001 ~ 09999FC1单个 FC5、多个 FC151 位
离散输入(DI)DI10001 ~ 19999FC2不可写1 位
输入寄存器(AI)IR30001 ~ 39999FC4不可写16 位
保持寄存器(AO/通用)HR40001 ~ 49999FC3单个值 FC6、多值或 32 位以上 FC1616 位

往离散输入、输入寄存器配写指令,模板在发送前就会被拒(提示「输入寄存器不可写」「离散输入不可写」),不用等设备回异常码。

1.2 地址怎么写 ​

地址有三种写法,同一条模板里(请求和解析段)只能用同一种,不要混着来。

写法一:数据区:点号,如 HR:100、IR:16、CO:0、DI:3。

点号按工位绑定里的「地址基准」解释:

地址基准HR:100 的实际协议地址什么时候选
0(缺省)100手册给的已经是 0 起的协议地址
199手册按 1 起编号(HR:1 指协议地址 0,HR:0 发送前报错)

写法二:Modicon 编号,直接照抄手册的 40001、30010、00001:5 位或 6 位纯数字、首位是区号即可。这种写法不受地址基准影响:

首位数据区例子协议地址
0线圈000010
1离散输入100010
3输入寄存器300109
4保持寄存器40101、400101100
  • 区号后面的点号从 1 起,所以 40101 是第 101 个点,协议地址 100。
  • 5 位编号最多到 9999 点;点数更大写 6 位(400101),或改用 HR: 写法。
  • 首位不是 0、1、3、4(如 22345)、点号为 0(如 40000),发送前直接报错。

写法三:手册的 4x、0x 前缀必须去掉。 信捷等手册常写 4x41098、4x200、0x60,前缀只表示数据区,后面才是地址本体,请改成数据区写法:

手册写法模板里写不要写成
4x200(D200)HR:20040200(这是 Modicon,协议地址 199)
4x41098(HD10)HR:4109841098(会被当成 5 位 Modicon,协议地址 1097)
0x0、0x60(线圈)CO:0、CO:0x6000001(只表示线圈协议地址 0)

元件号是八进制的(Y10、X17 这类只到 7),先自己换算成十进制线圈地址。M、D、HD、Y 这些元件名连接器不认,只认数据区加地址。

1.3 数字怎么写 ​

地址、数量、写入值共用一套规则:

写法含义
100、-5、1.5十进制
0x6000、6000H十六进制,两种等价,不能同时写(0x6000H 报错)
1A、FF、0b101发送前报错。含 A ~ F 的会提示改成 0x1A 或 1AH,二进制不支持,请自行换算

字节串(FC: 的数据区、HEX 写入)另算一套:每个字节一律十六进制,空格、逗号分隔或整串连写都行(01 02、01,02、0102 等价),位数必须是偶数。

1.4 从站地址(unit) ​

取值含义
1 ~ 247正常单播,一问一答
0广播:只发送、不等待响应,不能用于读,也不能用于按位写
248 ~ 255保留,一般不用

同一条 RS485 总线可以挂多台设备,靠 unit 区分;绑成多个仪器就能分别读写。

2. 在工位绑定设备 ​

在工位页面添加仪器,选 Modbus 连接器对应的型号,按传输方式填写。串口参数、从站地址、地址基准、字节序都属于设备级配置,只在这里填,不要写进指令模板。

2.1 RTU(串口 / RS485) ​

字段必填填写说明
协议是选 rtu(串口)
资源是下拉选择本工位的串口,形如 modbus::serial:COM3(以工位列表实际显示为准);插好 USB-RS485、接好 485 端子后再开这个窗口
波特率是与设备一致,常见 9600、19200、38400、115200
数据位是常见 8(可选 5 ~ 8)
校验是N(无)/ E(偶)/ O(奇)
停止位是1 或 2
从站地址是设备的 unit 号,默认 1
地址基准建议核对0(缺省,协议地址)/ 1(手册从 1 编号),见 1.2
字节序建议核对ABCD(缺省)/CDAB/BADC/DCBA,见 2.3
超时时间建议核对毫秒,默认 1000;响应慢的设备加到 2000 ~ 3000
重试次数可选超时、CRC 错误时的额外重发次数,0 ~ 10,默认 0

2.2 TCP(以太网) ​

字段必填填写说明
协议是选 tcp
主机是设备或串口服务器的 IP,如 192.168.0.10
端口是默认 502,串口服务器可能映射成 4001 等,按设备实际填
从站地址是串口服务器后面的从站号;直连网口的设备通常是 1
地址基准 / 字节序 / 超时 / 重试建议核对同上

2.3 字节序选哪个 ​

以 32 位 0x12345678 为例,四种排列在线上发出的字节:

选项线上字节常见叫法
ABCD12 34 56 78大端(缺省)
CDAB56 78 12 34字交换
BADC34 12 78 56字节交换
DCBA78 56 34 12小端

64 位同理:CDAB 是四个寄存器整体倒序,BADC 是每个寄存器内部两字节对调。16 位只看寄存器内部,BADC、DCBA 对调两个字节,ABCD、CDAB 没有区别。

读出来的浮点是离谱大数或 0,先换字节序,再怀疑地址。

2.4 总线是共享的,参数必须一致 ​

  • 同一条串口上绑定的所有仪器共享一根总线和一把锁,请求排队串行执行。同一串口的波特率、数据位、校验、停止位必须完全一致,否则保存时被拒,并提示已占用该串口的仪器序列号。
  • 同一个 IP:端口 上绑定的所有仪器共享一个连接,靠从站地址区分,请求同样串行。
  • 连接器不在指令之间插延时,需要等待时用流程的等待节点控制。

2.5 在线状态怎么看 ​

传输在线判定
TCP连接是否建立(每 15 秒检查一次,断线自动重连)
RTU绑定保存成功即显示在线

连接器不主动探测从站:指令超时、CRC 错误、设备返回异常码,都不会把仪器标成离线。所以「在线」只代表通路在,读数不对仍要按第 12 章查地址、数据区和参数。

3. 模板怎么构成 ​

text
<请求>[;解析段][;解析段]...
  • 请求里有 = 就是写,请求类型必须是 2;RW: 带 = 但仍按读处理。读的请求类型由平台下发(3),读指令必须配测试指标,否则报「读操作必须提供响应定义」。
  • 关键字和类型名不区分大小写,前后空格忽略。
  • 模板里的 {{参数编码}} 先由测试参数替换,再解析。占位符名只认字母、数字、下划线( 可以,NaN 不认);缺参数时发送前失败,并列出全部缺失的名称。

七种骨架,覆盖所有场景:

目的模板骨架示例
读保持/输入寄存器HR:<地址>[:<数量>][;段...]HR:100;FLOAT:CDAB
读线圈/离散输入CO:<地址>[:<数量>][;段...]CO:0:8;BIT;BIT
写(单值/多值)<数据区>:<地址>=<值>[,<值>...]HR:200=5、HR:200=1,2,3
按位写HR:<地址>.<位>=<0|1>HR:100.3=1
先写后读RW:<读地址>:<数量>:<写地址>[:<类型>]=<值>...RW:3:6:14:UINT16=255,255,255;UINT16
读设备标识ID[:<读码>][;ID:<对象>]...ID;ID:PRODUCT
自定义功能码FC:<功能码>[:<字节串>][;段...]FC:0x41:01 02;LEN:6;FLOAT

旧版的 MB:FC…、READ:、WRITE: 写法已全部废弃,现在填进去会直接报「旧语法」。老模板请按本文改写。

4. 读取指令 ​

在仪器指令库中新增 「读取指令」,页面分基本信息、测试参数、测试指标三块,至少要有 1 条测试指标。

读的请求只有数据区、地址、数量三段,数量可以省略:

  • 省略数量:读到解析段覆盖的最后一个地址为止(HR:100;FLOAT 自动读 2 个寄存器);没有解析段时读 1 个。
  • 写了数量:必须盖住所有解析段,HR:0:1;FLOAT 会因为浮点要 2 个寄存器而失败。
  • 上限:寄存器一次最多 125 个,线圈一次最多 2000 个。
text
HR:100;UINT16                    读 1 个寄存器
HR:100:10;UINT16:102;BIT:105.3   读 100~109,取 102 的整数值、105 的第 3 位
CO:0:8;BIT;BIT                   读 8 个线圈,取第 1、2 个
DI:0;BIT;BIT;BIT                 读 3 个离散输入
40101;FLOAT                      同一个点,按 Modicon 编号写

4.1 解析段的地址是绝对地址 ​

这一点和别的组态软件不同,别按「相对偏移」去想:

  • 请求写 HR:100,段里就写 102、0x66,按同一个地址基准解释。
  • 请求用 Modicon 编号(40101),段里也必须写 Modicon 编号(40103)。写成 BIT:105.3 会失败,并提示改成 Modicon 编号。
  • 段地址必须落在本次读取范围内,且不能小于读起点。
  • 省略段地址:紧接上一段往后排,第一段从读地址开始。连续点位就全都省掉地址。
  • 点位不连续就显式写地址;它后面那些省略地址的段会跟着整体后移。

连续读时,段的长度决定它占几个寄存器:FLOAT 占 2 个,UINT16 占 1 个,DOUBLE 占 4 个。

4.2 配置示例:读电压 ​

项目填写
指令名称读取电压
指令编码get_read_voltage
指令模板HR:0;FLOAT:CDAB
指令说明DEMO_PM100 电压,2 个寄存器,字交换浮点

测试指标(1 条):

指标名称指标编码指标类型指标分类指标单位小数位
电压voltage数值电压V2

读数值一定要写类型段(;FLOAT、;UINT16)。不写解析段时,指标拿到的是空格分隔的大写十六进制串(如 41 48 00 00),不是数字。

4.3 一次读多个量 ​

分号分隔的每个占指标的段对应一条测试指标,顺序一一对应。TMO、LEN、FC16、FC22 这些选项不占指标。

示例——读电压、电流并算功率,共 3 条指标:

项目填写
指令名称读取电压电流及功率
指令编码get_read_vi_p
指令模板HR:0;FLOAT:CDAB;FLOAT:CDAB;EXPR:voltage*current
顺序指标名称指标编码指标类型单位
1电压voltage数值V
2电流current数值A
3功率power数值W

规则要点:

  • 占指标的段数必须等于测试指标条数,否则发送前报「模板解析段数与 replys 数量不匹配」。
  • EXPR 里的变量名优先取指标编码,其次指令原始键;变量必须是前面已经出现的指标。
  • 表达式支持 + - * / % **、括号、一元负号,以及 abs、round、min、max、sqrt。
  • 指标的 scale 和小数位只作用于十进制数值指标,字符串、十六进制显示不参与缩放。

5. 解析段详解 ​

text
<类型>[:<地址>][:<字节序>]
段占用说明
INT16 UINT16 BCD161 个寄存器BCD 任一半字节大于 9 则解码失败,报错带原始字节
INT32 UINT32 FLOAT BCD322 个寄存器
INT64 UINT64 DOUBLE4 个寄存器
STRING:<地址>:<字节数>[:BA]字节数 ÷ 2 向上取整ASCII,去掉尾部 00 和空格。地址必填;BA 先把每个寄存器内两字节对调,字节数必须是偶数
HEX[:<地址>[:<字节数>]]同上空格分隔的大写十六进制。全省略时是整个数据区;只写地址时从该地址取到本次读取末尾
BIT:<地址>.<位>1 个寄存器,不推进顺延位置位 0 是该寄存器最低位,结果为 0 或 1
BIT:<地址>.<高>-<低>同上位域,高位必须大于等于低位,结果为整数
BIT[:<地址>]1 个线圈或离散输入不写地址时从读起点向后顺延;线圈按字节打包,最低位是第一个线圈
EXPR:<表达式>不占位置用前面的指标计算

5.1 位、位域、字符串、原始字节 ​

需求模板指标类型说明
读寄存器内第 5 位HR:0x100;BIT:0x100.5数值结果是 0 或 1
读状态字第 7 ~ 5 位HR:0x100;BIT:0x100.7-5数值位域,结果是整数
位域带文字含义HR:0x100;BIT:0x100.2-0:0=OFF,1=ON,2=ERR字符串编码不在表里则该指标失败
读线圈第 0 个CO:0:8;BIT:0数值线圈用 BIT 不带点号
连续几个线圈CO:0:8;BIT;BIT数值不写地址自动顺延
读 8 字节 ASCIIHR:0x10;STRING:0x10:8字符串地址必填
同上,寄存器内字节对调HR:0x10;STRING:0x10:8:BA字符串字节数必须偶数
读原始字节HR:0:4;HEX:0:8字符串输出 41 4C 52 这种大写十六进制
  • BIT 段占 1 个寄存器但不推进顺延位置,所以同一个寄存器要拆两个位域时,写两段、地址各写一遍即可。
  • 对照表写在位号后,给文字指标(类型选「字符串」)用;数值指标的对照值必须是数字。
  • STRING、HEX 里的数字都是字节数,不是寄存器数。
  • 不写解析段时,整个数据区的十六进制串会填进每一个指标。

5.2 字节序写法 ​

字节序写在类型后面,缺省取绑定里的设置(再缺省 ABCD):

text
FLOAT:CDAB        字节序 CDAB,地址从读起点开始
FLOAT:102         地址 102
FLOAT:102:CDAB    地址 102,字节序 CDAB

ABCD、CDAB 这些是字母,不会被当成地址,所以 FLOAT:CDAB 不会被理解成「地址 0xCDAB」。

6. 设置指令 ​

写操作在 「设置指令」 页面创建,= 一出现就是写,请求类型由平台置为 2;IR、DI 以及 Modicon 的 1 区、3 区不能写。

设置指令一般不加测试指标,把要写的值开放成测试参数(模板里写 {{value}},参数编码填 value)。

6.1 常用写法 ​

模板功能码说明
HR:100=5FC6缺省 16 位,范围 -32768 ~ 65535,负数取补码
HR:100=1,2,3FC16连续写多个寄存器
HR:100:FLOAT:CDAB=3.3,4.4FC16类型可写整数、BCD、FLOAT、DOUBLE
HR:100=5;FC16FC16设备不支持 FC6 时,单个 16 位值也走 FC16
HR:100:STRING:16=ABCFC16不足补 00,超长失败;BA 在补齐后对调字节
HR:100:HEX=01 02 03 04FC16原始字节,必须是偶数个
CO:0=1FC51 发 FF00(ON),0 发 0000(OFF)
CO:0=1,0,1FC15多线圈,最低位是第一个线圈
HR:100.3=1FC3 + FC6按位写,见 6.2
HR:100.3=1;FC22FC22屏蔽写,从站一次完成
40101=5、40101.0=1FC6 / FC3+FC6与 HR: 等价,区号决定数据区

写请求只要 PDU 不超过 253 字节就发送,不按标准里「一次最多写多少个」拒绝——例如线圈一次写 1976 个是允许的。

6.2 按位写:默认是读-改-写 ​

HR:100.3=1 的实际动作是在同一把总线锁内:先 FC3 读 1 个寄存器 → 改第 3 位 → 再 FC6 写回。读失败就不写。位号范围 0 ~ 15。

中间那一刻的值可能被别的主站改掉,所以设备支持 FC22 时优先加 ;FC22,交给从站一次原子完成:

text
HR:100.0=1          读-改-写
HR:100.0=1;FC22     屏蔽写

6.3 写入值换算(;EXPR:) ​

寄存器数值写可以在末尾加 ;EXPR:<表达式>,变量名固定为 value,每个写入值先换算再编码:

text
HR:10=12.5;EXPR:value*10       写入 125
HR:0:FLOAT=1.5;EXPR:value*10   写入 15.0

整数类型(含缺省的 16 位和 BCD)结果必须是整数,出小数会报「整数类型的换算结果必须是整数」。HEX、字符串、线圈、按位写不能加 EXPR。

6.4 配置示例:设置输出电压 ​

项目填写
指令名称设置输出电压
指令编码set_voltage
指令模板HR:0x200:FLOAT:CDAB={{value}}
指令说明写 2 个寄存器,字交换浮点

测试参数:参数名称「输出电压」,参数编码 value,参数类型「数值」,参数形式「自定义」,范围 0 ~ 60,单位 V。

6.5 设置指令能带什么 ​

只允许这些:TMO(覆盖本条超时);寄存器数值写另可带 EXPR、FC16;按位写另可带 FC22;FC: 另可带 LEN。带类型段、BIT 之类会在发送前报「写指令不支持解析段」——写操作的响应不解码。

7. 读写组合(先写后读) ​

text
RW:<读地址>:<读数量>:<写地址>[:<类型>][:<字节序>]=<值>[,<值>...][;解析段...]

功能码 23,先写后读,按读指令处理:类型不能是 2,必须配测试指标。

  • 三个地址写法与前面一致,都是寄存器;读数量 1 ~ 125。
  • 解析段地址落在读区间内;不能写字符串。
text
RW:3:6:14:UINT16=255,255,255;UINT16    先往 14 写 3 个寄存器,再读 3 起的 6 个

8. 设备标识 ​

text
ID[:<读码>][;ID:<对象>]...

走功能码 43(MEI 类型 14),按读指令处理。读码缺省 1,可取 1 ~ 4(1 基本、2 常规、3 扩展、4 单个对象);读码填 4 时只能有一个 ID: 段,连接器就用那个对象号发请求。

对象可以写名称或编号:

对象名称编号
VENDOR0
PRODUCT1
VERSION2
URL3
NAME4
MODEL5
APP6

0x80 及以上的厂商自定义对象没有名称,直接写编号。

  • 值是 ASCII,去掉尾部空白;响应里没有该对象,对应指标就失败。
  • 响应提示还有后续对象时,连接器在同一条指令内接着读,最多 8 帧;超出则返回已读到的对象,并在日志里告警。
text
ID;ID:VENDOR;ID:PRODUCT
ID:4;ID:MODEL

9. 自定义功能码 ​

text
FC:<功能码>[:<字节串>][;段...]

功能码沿用第 1.3 节的数字规则:FC:0x41 和 FC:41H 都是 65,而 FC:41 是十进制 41(0x29)。不在规范定义范围内、也不在保留区(65 ~ 72、100 ~ 110)的功能码照常发送,日志里会记一条警告。

  • 数据区原样发送,每个字节十六进制、位数偶数。
  • 响应取功能码之后的全部字节,段里的位置是字节偏移(从 0 起):FLOAT;UINT16 依次占 4 字节和 2 字节,等价于 FLOAT:0;UINT16:4。
  • BIT:<偏移>.<位> 在这一段里是从该偏移起的 2 个字节中取位。
  • ;LEN:<字节数> 是响应数据区的字节数(不含功能码)。RTU 下读满即返回,不写就靠帧间静默判断结束;TCP 的长度由报文头决定,LEN 只做发送前的范围检查。能确定长度时请写上。
  • 放在设置指令里(类型 2)不能带解析段,响应不解码,LEN 只用于 RTU 切帧。
  • FC: 不核对功能码与指令类型是否匹配:FC:3:00 00 00 02 在设置指令里也能发,但响应当原始字节,不会按保持寄存器解析。
text
FC:8:00 00 12 34
FC:0x41:01 02;LEN:6;FLOAT;UINT16
FC:0x41:01;LEN:2;TMO:100            设置指令里合法

10. 选项段 ​

不占指标,每种最多一段:

段用于说明
TMO:<毫秒>全部模板覆盖这一条的响应超时,必须大于 0;按位写、设备标识的每一帧都用它
LEN:<字节数>FC:响应数据区字节数,1 ~ 250
FC16寄存器数值写单个 16 位值也改用 FC16
FC22HR:<地址>.<位>=用屏蔽写代替读-改-写

11. 常用指令速查 ​

同一点位既能读又能写时拆成两条,分别在「读取指令」「设置指令」里建。模板请原样复制,不要改写成指令编码。

11.1 常用读取 ​

指令名称指令编码指令模板测试指标(编码 / 名称 / 类型)
读保持寄存器get_read_regHR:0;UINT16value / 读数 / 数值
读有符号寄存器get_read_reg_intHR:0;INT16value / 读数 / 数值
读 32 位寄存器get_read_reg32HR:0;UINT32value / 读数 / 数值
读浮点get_read_floatHR:0;FLOATvalue / 读数 / 数值
读浮点(字交换)get_read_float_cdabHR:0;FLOAT:CDABvalue / 读数 / 数值
读 BCD 32 位get_read_bcdHR:200;BCD32value / 读数 / 数值
读输入寄存器get_read_inputIR:0;UINT16value / 读数 / 数值
读线圈get_read_coilCO:0;BITstate / 线圈状态 / 数值
读离散输入get_read_diDI:0;BITstate / 输入状态 / 数值
读连续 4 个线圈get_read_coils4CO:0:4;BIT;BIT;BIT;BIT4 条:coil0 ~ coil3
读状态字拆位域get_read_statusHR:0x100;BIT:0x100.7-5;BIT:0x100.2-0:0=OFF,1=ON2 条:mode、fault
读 ASCII 名称get_read_nameHR:0x10;STRING:0x10:8name / 名称 / 字符串
读原始字节get_read_rawHR:0:4;HEX:0:8raw / 原始数据 / 字符串
读电压电流功率get_read_vi_pHR:0;FLOAT:CDAB;FLOAT:CDAB;EXPR:voltage*current3 条:voltage、current、power
先写后读get_read_after_writeRW:3:6:14:UINT16=255,255,255;UINT16value / 读数 / 数值
读厂商与型号get_read_idID;ID:VENDOR;ID:MODEL2 条:vendor、model(字符串)

11.2 常用写入 ​

指令名称指令编码指令模板测试参数
写单个寄存器set_regHR:0={{value}}value(数值)
写固定十六进制值set_reg_hexHR:0=0x1234无(固定值)
写多个寄存器set_regsHR:0:UINT16={{v1}},{{v2}}v1、v2(数值)
写浮点(字交换)set_float_cdabHR:0:FLOAT:CDAB={{value}}value(数值)
写字符串set_stringHR:0x10:STRING:16={{text}}text(字符串)
写单个线圈set_coilCO:0={{value}}value(选项:0=断开,1=闭合)
写多个线圈set_coilsCO:0={{b0}},{{b1}},{{b2}}b0 ~ b2(0/1)
只改一位set_bitHR:100.3=1无(固定值)
只改一位(屏蔽写)set_bit_maskHR:100.3=1;FC22无(固定值)
写原始字节set_raw_bytesHR:0:HEX=12 34无(固定值)
带缩放写入set_scaledHR:0={{value}};EXPR:value*10value(填 25.5 实际写 255)
动态地址写set_addr_valueHR:{{addr}}={{value}}addr、value
覆盖本条超时set_slowHR:0x10={{value}};TMO:2500value(数值)

模板里出现 {{xxx}},测试参数就必须有编码为 xxx 的参数,否则发送前报「参数列表中缺少模板中引用的参数」,并列出全部缺失的名称。

12. 填错了怎么查 ​

现象 / 提示关键词可能原因处理建议
旧语法模板里还是 MB:FC…、READ:、WRITE:按本文第 3 章改写
参数列表中缺少模板中引用的参数占位符和测试参数编码对不上补齐同名参数,编码区分大小写
含十六进制字符,请写 0x1A 或 1AH写成了 1A、FF 这种不带前缀的十六进制加 0x 前缀或 H 后缀
应以 HR、IR、CO、DI… 开头地址既不是数据区,也不是 5 位/6 位 Modicon 编号补数据区前缀,或按 Modicon 写
段地址应写 Modicon 编号请求用了 40101,解析段却写 105段地址改成同区的 Modicon 编号
不在 … 内 / 需要寄存器解析段超出读取数量(HR:0:1;FLOAT)数量盖住全部段,或让连接器自动推数量
读到的数和手册差 1、和 4x41098 对不上把 4x 后面的地址当成了 5 位 Modicon 编号4x41098 写 HR:41098,不要写 41098
请求 type 必须是 2 / type 不能是 2写模板当成读、读模板当成写有 = 的是写,RW/ID 按读处理
输入寄存器不可写 / 离散输入不可写对 IR、DI 写值(含 Modicon 1 区、3 区)写操作用 CO 或 HR
写指令不支持解析段设置指令带了类型段、BIT只留 TMO,数值写可加 EXPR/FC16,按位写可加 FC22
模板解析段数与 replys 数量不匹配占指标的段数与指标条数不同一段一条指标,选项段不算
读操作必须提供响应定义读指令没配测试指标至少配 1 条指标
从站地址 0 是广播地址unit=0 用在了读或按位写上广播只能写;读和按位写改成 1 ~ 247
整数类型的换算结果必须是整数EXPR 出小数,而类型不是 FLOAT/DOUBLE换成浮点类型,或调整表达式
异常码 0x02:非法数据地址地址超设备映射,或往只读区写核对点表;0x0A 是网关路径不可用,0x0B 是网关目标无响应
响应超时设备无响应:接线、串口参数、从站号、IP/端口先用最简单的单点读验证通路,或调大超时
日志提示「未在 Modbus 中定义」FC:41 是十进制 41,不是 0x41手册的十六进制功能码写 FC:0x41 或 FC:41H

自查顺序:

  1. 模板是不是按「数据区:地址」写的,有没有残留旧语法
  2. 地址有没有撞上 Modicon 编号(41098 vs HR:41098),地址基准选得对不对
  3. 读取指令:指标条数 = 占指标的段数
  4. 先用最简单的单点读(已知地址的 UINT16)验证通路,再上多段、位域、浮点
  5. 数值离谱:换字节序(ABCD/CDAB/BADC/DCBA),再核对地址
  6. 仍失败看工位日志:请求发出去没有、设备回了什么异常码

13. 配置流程速览 ​

text
抄点表:数据区(HR/IR/CO/DI)+ 地址 + 类型 + 字节序
        ↓
工位绑定:RTU(串口 + 波特率 + 校验 + 停止位)
       或 TCP(IP + 端口)
       统一填:从站地址、地址基准、字节序、超时
        ↓
确认地址:手册 40001 → 40101(Modicon)或 HR:0
         手册 4x200 → HR:200(去掉 4x)
        ↓
读取指令:HR:<地址>;<类型>[:<字节序>](段数 = 指标条数)
   或设置指令:HR:<地址>=<值> / HR:<地址>:FLOAT:CDAB=<值>
        ↓
一次读多个量 → 多个解析段 + EXPR(变量用前面的指标编码)
厂商私有功能码 → FC:0x41:…;LEN:<n>,能确定长度就写 LEN
        ↓
读不到或读不对 → 按第 12 章排查(模板 → 地址 → 段 → 字节序 → 通路)

基于 CC-BY-4.0 协议发布