问题描述
我想通过tcp / ip使用Modbus读取SDM120千瓦时电度表的寄存器。我有一个可以正常运行的Windows程序Simply Modbus。发送到仪表的字节字符串是“ 00 01 00 00 00 06 01 04 00 00 00 01”。
我从寄存器30001中得到结果
但是当我尝试使用modpoll来执行此操作时,相同的字节字符串会导致另一个答案。
C:\modpoll-3.9\win>modpoll.exe -m tcp -c 1 -r 1 -t3 -1 -p 26 10.40.3.209
modpoll 3.9 - FieldTalk(tm) Modbus(R) Master Simulator
copyright (c) 2002-2020 proconX Pty Ltd
Visit https://www.modbusdriver.com for Modbus libraries and tools.
Protocol configuration: MODBUS/TCP,FC4
Slave configuration...: address = 1,start reference = 1,count = 1
Communication.........: 10.40.3.209,port 26,t/o 1.00 s,poll rate 1000 ms
Data type.............: 16-bit register,input register table
-- Polling slave...
[1]: 17245
当我添加开始寄存器30001时,字节串不同了00 01 00 00 00 06 01 04 75 30 00 01,我得到了超时:
C:\Users\adm_ago\Downloads\modpoll-3.9\win>modpoll.exe -m tcp -c 1 -r 30001 -t3 -1 -p 26 10.40.3.209
modpoll 3.9 - FieldTalk(tm) Modbus(R) Master Simulator
copyright (c) 2002-2020 proconX Pty Ltd
Visit https://www.modbusdriver.com for Modbus libraries and tools.
Protocol configuration: MODBUS/TCP,start reference = 30001,input register table
-- Polling slave...
Reply time-out!
我在做什么错了?
解决方法
SDM120 docs I found使用'Modicon Convention Notation'(也称为其他名称)。 Modpoll使用more recent standard,因此您需要将'30001'转换过来;前导3表示其保持寄存器,“ 0001”表示寄存器1(我从SDM120文档的“ Modbus协议StartAddress Hex”列中看到正确的信息。)
Simply Modbus 00 01 00 00 00 06 01 04 00 00 00 01
发送的原始字节字符串可以为parsed to:
|-------|------------------------|---------------------------------|
| Bytes | Description | Value |
|-------|------------------------|---------------------------------|
| 00 01 | Transaction identifier | 0x0001 (1) |
| 00 00 | Protocol identifier | 0 = MODBUS protocol |
| 00 06 | Length | 0x0006 (6) |
| 01 | Unit identifier | 0x01 (1) |
| 04 | Function code | 0x04 (4) - Read Input Registers |
| 00 00 | Starting address | 0x0001 (1) |
| 00 01 | Quantity | 0x0001 (1) |
|-------|------------------------|---------------------------------|
因此,您运行的第一个命令modpoll.exe -m tcp -c 1 -r 1 -t 3 -1 -p 26 10.40.3.209
应该检索所需的寄存器(但是SDM120文档还指出“每个参数都保存在两个连续的16位寄存器中”,因此您将需要检索两个寄存器;我请尝试-t 3:float
,但您可能还需要-f
)。 Modbus协议可与16位寄存器(输入/保持寄存器)一起使用,但是未指定如何将它们组合起来以容纳更大的整数或浮点数。 SDM 120文档指出它们被编码为“ 32位IEEE754”,但我看不到endianness的任何提及。
我希望收到第二个查询的“非法数据地址”,但并非总是返回。因此,为了完整起见,两个不同的命令发送不同的“字节串”的原因是它们是不同的(一个请求寄存器1,另一个请求不存在的寄存器30000)。
Modbus寻址可能会造成很大的混乱-我建议阅读this article中的“ Modbus:40001实际为1或0实际为1”部分,其中介绍了一些问题。