Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
JPSteindlberger opened this issue Apr 16, 2023 · 2 comments · May be fixed by #43

Comments

@JPSteindlberger
Copy link

In

self._mb.write_register(addr, value, unit=0x01)
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
Copy link

oxytu commented Apr 22, 2023

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
    ]
}

@oxytu oxytu linked a pull request Apr 22, 2023 that will close this issue
@kommando828
Copy link

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants