Closed WernerFettke closed 2 months ago
Hi,
To write a 32-bit value using Modbus, split it into two 16-bit words (native format of modbus address space) and write it as a list of two items. For example, to write 120889 (=0x0001_d839), set [0x0001, 0xd839] at address 123.
# convert 32 bits -> 2 x 16 bits
i = 120_889
high_part = (i>> 16) & 0xFFFF
low_part = i & 0xffff
# this will update words at @123 and @124
server.data_bank.set_holding_registers(123, [high_part , low_part])
# since 32-bit writing is not in modbus standard, some devices may require the reverse order
server.data_bank.set_holding_registers(123, [low_part , high_part])
Hi,
Many thanks for getting back to me, I really appreciate it !!
If I take your code as is, without changing anything (including the value of i), and run the code, on the other end if I read the modbus, I get the attached image: The highlighted row, 55353 and -10183 ? I have also tried hard coding the hex value: 0x0001_d839 for i but this also returns the same as in the screen shot ?
If I swop the low and high parts around, I just get a 1 on the output.
Any other ideas where I'm going wrong ?
Much appreciated.
Regards
Werner
Hi,
55353, -10183 and 0xd839 are the same 16-bit value. The first is a decimal representation, the second is a two's complement and the last is a hexadecimal representation.
For the rest, it's difficult to help you based on this image.
Hi,
Something interesting I noticed, instead of using: i = 120_889
If I made it the full number: i = 120889
I get the following, I'm assuming it has something to do with the format of i
Hi,
55353, -10183 and 0xd839 are the same 16-bit value. The first is a decimal representation, the second is a two's complement and the last is a hexadecimal representation.
For the rest, it's difficult to help you based on this image.
Thanks for getting back to me, I just want to confirm, if I used your code: i = 120_889 high_part = (i>> 16) & 0xFFFF low_part = i & 0xffff
server.data_bank.set_holding_registers(123, [high_part , low_part])
I should be getting 120889 when I read the modbus value ?
Regards
Werner
Maybe you could try to configure your client to read 2 registers since the "uint32" and "int32" columns are marked as incomplete.
To see 120889 you need 2 16-bit registers.
I think I found the problem, I was setting the value for the next register, which was in essence overwriting the value we where calculating, If I don't do that I get:
Thanks so much for your help !!!
Glad to read this, have a nice day.
Hi All,
I hope someone can assist, I'm still pretty new to modbus and pyModbusTCP.
I'm trying to write holding register values to the databank using for example:
x = 120889 server.data_bank.set_holding_registers(123, [x])
So in other words writing x (120889) to register number 123
This works, however when I try read the value from the modbus server where this has been written to I get: 55353
I figured out this is 120889 - 65536 = 55353 (the response I'm getting)
I'm assuming I need to convert x or specify the type before doing ? server.data_bank.set_holding_registers(123, [x])
I have checked the documentation to see if I can set the value type (possibly a double or a float ?) when setting the holding_registers but I don't see anything there. The value of x will always be an integer, I'm sure it's something simple, but any assistance would really be appreciated.
Many Thanks !
Werner