Replies: 4 comments 8 replies
|
Please see the examples. |
|
Hi I have a device that has a large amount of registers, I can't read and decode each register one by one. u16 = client.convert_from_registers(rr.registers[offset:offset+1] ...
offset += 1
# un uint32
u32 = client.convert_from_registers(rr.registers[offset:offset+2] ....
offset += 2
# un float32
f32 = client.convert_from_registers(rr.registers[offset:offset+2] ....Thank you |
|
Yes—decode the block once, then slice it according to each field's register width. Your old rr = client.read_holding_registers(
address=0x0200,
count=15,
device_id=1, # use slave=1 on older PyModbus versions
)
if rr.isError():
raise RuntimeError(f"Modbus read failed: {rr}")
regs = rr.registers
offset = 0
def take(data_type):
global offset
width = data_type.value[1] # registers: 1 for 16-bit, 2 for 32-bit, 4 for 64-bit
value = client.convert_from_registers(
regs[offset : offset + width],
data_type=data_type,
word_order="little",
)
offset += width
return value
voltage = take(client.DATATYPE.INT32)
current = take(client.DATATYPE.INT32)
temperature = take(client.DATATYPE.INT16)
# Example of the mixed layout from the follow-up:
u16 = take(client.DATATYPE.UINT16)
u32 = take(client.DATATYPE.UINT32)
f32 = take(client.DATATYPE.FLOAT32)
u64 = take(client.DATATYPE.UINT64)So the intuition in the follow-up is correct. The important details are:
I checked this against the current implementation and examples: |
|
If the purpose is to make clear and understandable code, it can be done a lot easier: ´´´ where 1,3,5 are the relevant register offsets. Calling client.from_registers one time with all registers or multiple times each with one register set actually use the same amount of CPU. |
Uh oh!
There was an error while loading. Please reload this page.
How to use convert_from_registers instead of BinaryPayloadDecoder with multiple different data types?
Old code:
All reactions