I am trying to implement a pymodbus server. I am using ModbusSparseDataBlocks in the ModbusSlaveContext. This works so far. The client can write and read vales from every register instantiated.
But I have problems with negative values. The client needs 16bit signed integer format and he can not interpret my negative values.
This is how I fill the register with values:
#write positive value (100) to IR[0x10] --> client interprets this correctly
context[0x00].setValues(4, 0x10, 100)
#write negative value (-100) to IR[0x10] --> client can't read this, throws failure
context[0x00].setValues(4, 0x10, -100)
How can I write a valid 16bit signed integer to the register?
(I am using python 2.7 and pymodbus version 1.2.0)
It looks like your library only understands unsigned 16-bit numbers. If you bitwise-AND the signed value with 0xFFFF (a 16-bit mask) in Python, you'll get the same result:
What you're doing:
>>> import struct
>>> struct.unpack('<H',struct.pack('<h',-100))[0]
65436
Bitwise-AND:
>>> -100 & 0xFFFF
65436
So you can do:
context[0x00].setValues(4, 0x10, -100 & 0xFFFF)
Positive values will be unaffected, and negative values result in the unsigned 16-bit 2's complement value.
To convert an unsigned 2's complement 16-bit value back to signed, test for the sign bit (2 15 ) and subtract 2 16 if present:
value = value-2**16 if value & 2**15 else value
or equivalently:
value = value-0x10000 if value & 0x8000 else value
I found out that following works for me, but I don't know if this is the correct and safe way.
import struct
def signed(value):
packval = struct.pack('<h',value)
return struct.unpack('<H',packval)[0]
#write positive value (100) to IR[0x10] --> client interprets this correctly
context[0x00].setValues(4, 0x10, signed(100))
#write negative value (-100) to IR[0x10] --> client interprets this correctly
context[0x00].setValues(4, 0x10, signed(-100))
You could also simply calculate it manually:
if value < 0:
value = 2**16 + value
context[0x00].setValues(4, 0x10, signed(value))
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.