pymodbus icon indicating copy to clipboard operation
pymodbus copied to clipboard

Decoding Holding Registers to 16bit binary format

Open Pietro395 opened this issue 3 years ago • 5 comments

Versions

  • Python: 3.9.13
  • OS: Ubuntu 22.04
  • Pymodbus: 2.5.3
  • Modbus Hardware (if used):

Pymodbus Specific

  • Server: tcp
  • Client: tcp

Description

In reference to the issue #634

I am simulating a real case in which in a modbus server I have to read a holding register in binary format.

Reading the register and using the decode_bits() function I expect to receive a list of 16 bits. decode_bits() only converts 1 byte.

Code and Logs

# register: 1101000000000000
result = self.connection.read_holding_registers(register, 1, unit=self.slave_unit)
decoder = BinaryPayloadDecoder.fromRegisters(result.registers, Endian.Big, wordorder=Endian.Little)
print(decoder.decode_bits())
# Result: [False, False, False, False, True, False, True, True]
# Expected: [False, False, False, False, False, False, False, False, False, False, False, False, True, False, True, True]

Pietro395 avatar Aug 11 '22 15:08 Pietro395

A holding register contains bytes (2 pr register) and not bits. Normally you interpret a holding register as an int.

You should be able to use result.registers directly, of course unless you want to do some special conversions.

janiversen avatar Aug 11 '22 15:08 janiversen

A holding register contains bytes (2 pr register) and not bits. Normally you interpret a holding register as an int.

You should be able to use result.registers directly, of course unless you want to do some special conversions.

Yes, I know this is not standard, but for what reason does decode_bits() only have to convert one byte?

Pietro395 avatar Aug 11 '22 15:08 Pietro395

Because that is how it is programmed 😃

consider using e.g. decoder.decode_16bit_uint(), or make 2 calls to BinaryPayloadDecoder / decoder.decode_bits.

janiversen avatar Aug 11 '22 15:08 janiversen

Because that is how it is programmed smiley

consider using e.g. decoder.decode_16bit_uint(), or make 2 calls to BinaryPayloadDecoder / decoder.decode_bits.

Mine was not meant to be a provocation! I expected to receive 2 bytes :)

Thank you

Pietro395 avatar Aug 11 '22 15:08 Pietro395

I did not take it as a provocation, hence my smiley.

I suspect it is code that was not touched since the beginning of time....please keep the issue open, and I will see if I can get it fixed, but I cannot promise you a timeline since I am pretty busy with a major rewrite of the whole client structure.

Ps. if/when I fix it, it will be on dev and not on 2.5.3.

janiversen avatar Aug 11 '22 16:08 janiversen

AFAIK, decode_bits is historically used dealing with single byte registers and does not support multiple bytes. It should be trivial to patch it support multiple bytes but not a hight priority task IMHO. PR's are welcome

dhoomakethu avatar Aug 17 '22 04:08 dhoomakethu