tjhowse / modbus4mqtt

Modbus TCP <-> MQTT glue. YAML configuration. Robust.
Other
78 stars 34 forks source link

self._mb.write_register is only valid for 16 bit values - 32 bit values require writing 2 addresses at once #42

Open JPSteindlberger opened 1 year ago

JPSteindlberger commented 1 year ago

In https://github.com/tjhowse/modbus4mqtt/blob/d563879da1608c2757b74978d48cce48e946d05f/modbus4mqtt/modbus_interface.py#L149 self._mb.write_register is used. But this writes only one address at once, which is only valid for devices expecting 16 bit values. Devices with values like int32 or int64 expect writing all relevant addresses at once and not in sequence. Hence self._mb.write_registers (plural) is required. Sure, this might require code changes at many other positions.

oxytu commented 1 year ago

This issue also just occured to me. My heating unit provides only int32 registers and I can perfectly read everything and publish to MQTT - but the way back does not work. When using the pymodbus.console-application and calling write_registers as you proposed, I can set new values, so I assume that is the same issue.

> client.read_holding_registers address=1036 count=2 unit=1
{
    "registers": [
        0,
        420
    ]
}

> client.write_registers address=1036 values=0,500 unit=1
{
    "address": 1036,
    "count": 2
}

> client.read_holding_registers address=1036 count=2 unit=1
{
    "registers": [
        0,
        500
    ]
}
kommando828 commented 5 months ago

You can get round this issue by converting your two 32 bit into two 16 bits. These two 16 bits are not the values you would expect but have to be converted in a special way. I don't fully understand how it works but if you play around on this website with conversions from 16bit to 32 bit and then back again it may become clearer to you.

https://cryptii.com/pipes/integer-converter

If you have Node-red then this flow I use shows the nodes where I convert a 16 bit value into 32 bit values that work.

https://flows.nodered.org/flow/7db69e532e4c58eb8078724092c4308a

Just don't ask me to explain, it just works.

What you must understand is that your modbus server does not have any 32 bit registers, it just has 2 concurrent 16 bit registers that when jointly read can be processed and converted to a 32 bit register but all this happens outside the server. So to write backwards you also need to reverse this conversion.