首页 > 解决方案 > 通过 tcp/ip 使用 modbus 读取 SDM120 kwh 电表

问题描述

我想通过 tcp/ip 读取带有 modbus 的 SDM120 kwh 仪表的寄存器。我有一个可以运行的 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, FC4
Slave configuration...: address = 1, start reference = 30001, 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...
Reply time-out!

我究竟做错了什么?

标签: modbus-tcp

解决方案


我发现的SDM120 文档使用“ Modicon Convention Notation ”(也称为其他名称)。Modpoll 使用更新的标准,因此您需要将 '30001' 转换过来;前导 3 表示它的保持寄存器,“0001”表示寄存器 1(我可以从 SDM120 文档中的“Modbus 协议 StartAddress Hex”列中看到这是正确的)。

Simply Modbus 发送的原始字节串00 01 00 00 00 06 01 04 00 00 00 01可以解析为

|-------|------------------------|---------------------------------|
| 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”,但我看不到任何关于字节序的提及。

我本来希望收到一个“非法数据地址”来响应您的第二个查询,但这些并不总是返回。因此,为了完整起见,两个不同命令发送不同“字节串”的原因是它们不同(一个请求寄存器 1,另一个请求不存在的寄存器 30000)。

Modbus 寻址可能非常令人困惑 - 我建议阅读本文中的“Modbus:当 40001 真正意味着 1,或 0 真正意味着 1”部分,其中解释了一些问题。


推荐阅读