Modbus read two register into one opc tag


I’m trying to read some values from a modbus TCP device. Some of the values are described as 2 word Long Interger in manual. When I set up OPC Ithem Path for the register that hold these values I use prefix HRI, but do not get the correct value. But if I read these two registers separately with the prefix HR, I get two numbers that will represent the correct value if I put them together.

HRI129 -> 2163896
HR129 -> 33
HR130 -> 1208

The correct value is 331208.

I see how this arises with how the binary values are put together. But is there a way to get around this, or do I have to read all the register separately and then concat them together in a memory tag.

Regards Stian

I believe you’re going to have to put them together using an expression tag or a derived tag. The Modbus specification will always put them together using binary.

Agreed, what a strange device… You could create an expression tag (data type Integer) with stringFormat("%d%d", {[~]HR129}, {[~]HR130}) and achieve what you’re looking for. It will concatenate the values together and the cast back to Integer will handle converting it back to a number.

New crown for worst representation of a 32-bit value in Modbus.


If you are on 8.0+, you can also use a derived tag against the source HRI129 that will help you guarantee an atomic read:

Read Expression
stringFormat("%d%d", ({source} >> 16), {source} & 0xFFFF)
Write Expression

1 Like

It’s called “modulo 10000” and is common with old Modicon PLCs. A counter would automatically reset at 10000 and increment the next holding register.

For the strangest Modbus data format award, I submit the 16-bit floating point words used in some Morningstar solar charge controllers.

Thank you all for the clarification and help in solving this.

1 Like