1

I want to read the registers of an SDM120 kwh meter with modbus over tcp/ip. I have one Windows program Simply Modbus that works. The byte string that is send to the meter is "00 01 00 00 00 06 01 04 00 00 00 01".

And I get results from register 30001

But when I try to do this with modpoll the same byte string results in an another answer.

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

When I add the begin register 30001, the bytestring is different 00 01 00 00 00 06 01 04 75 30 00 01 and I get an timeout:

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!

What am I doing wrong?

user3511320
  • 119
  • 1
  • 1
  • 10

1 Answers1

1

The SDM120 docs I found use the 'Modicon Convention Notation' (also referred to by other names). Modpoll uses a more recent standard so you need to convert '30001' over; the leading 3 means its a holding register and "0001" means register 1 (I can see that is correct from the 'Modbus Protocol StartAddress Hex' column in the SDM120 doc).

The original byte string sent by Simply Modbus 00 01 00 00 00 06 01 04 00 00 00 01 can be 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)                      |
|-------|------------------------|---------------------------------|

So the first command you ran modpoll.exe -m tcp -c 1 -r 1 -t 3 -1 -p 26 10.40.3.209 should retrieve the register you need (however the SDM120 doc also notes that "Each parameter is held in two consecutive 16 bit register" so you will need to retrieve two registers; I'd try -t 3:float but you may also need -f). The Modbus protocol works with 16 bit registers (input/holding registers) but does not specify how these can be combined to hold larger integers or floating point numbers; the SDM 120 doc states that these are encoded as '32 bit IEEE754' but I could not see any mention of endianness.

I would have expected to receive an 'Illegal Data Address' in response to your second query but these are not always returned. So for completeness the reason that the two different commands are sending differing "bytestrings" is that they are different (one is requesting register 1, the other a non-existant register 30000).

Modbus addressing can be quite confusing - I recommend reading the "Modbus: When 40001 Really Means 1, or 0 Really Means 1 " section in this article which explains some of the issues.

Brits
  • 14,829
  • 2
  • 18
  • 31