brainelectronics / micropython-modbus

MicroPython Modbus RTU Slave/Master and TCP Server/Slave library
GNU General Public License v3.0
115 stars 47 forks source link

Reading holding registers does always return all registers #37

Closed brainelectronics closed 1 year ago

brainelectronics commented 1 year ago

Related to #25, similar to #36, contributes to #35, found during https://github.com/brainelectronics/micropython-modbus/pull/33#issuecomment-1336274272 section "Problem 4"

Defining a holding register with more than one element, but requesting only 1 element, returns all elements of the register.

register_definitions = {
    "HREGS": {
        "ANOTHER_EXAMPLE_HREG": {
            "register": 94,
            "len": 9,
            "val": [29, 38, 0, 1600, 2150, 5067, 2564, 8450, 3456],
            "description": "Example HREGS registers with length of 9, Hregs (setter+getter) [0, 65535]",
            "range": "",
            "unit": ""
        }
    }
}
>>> host.read_holding_registers(slave_addr=10, starting_addr=94, register_qty=1, signed=False)
(29, 38, 0, 1600, 2150, 5067, 2564, 8450, 3456)
# expectation would be (29,)

Reason/root cause: The response quantity is defined as the length of the returned byte list, see https://github.com/brainelectronics/micropython-modbus/blob/2f1e307fa087e2f97fa6031a4bfb5b8d8bdddcd2/umodbus/functions.py#L379-L380 not taking into account the actual amount of requested data. Thereby the format to unpack the data is >hhhhhhhhh instead of >h as the response byte array lenght is 9, but the register quantity of interest is 1

brainelectronics commented 1 year ago

@beyonlo I think this is also solved with #53 and release 2.3.1

beyonlo commented 1 year ago

@beyonlo I think this is also solved with #53 and release 2.3.1

@brainelectronics exactly, this issue is solved!

Master:

>>> from umodbus import version
>>> print('Running ModBus version: {}'.format(version.__version__))
Running ModBus version: 2.3.1-rc26.dev53
>>> host.read_holding_registers(slave_addr=10, starting_addr=93, register_qty=3, signed=False)
(29, 38, 0)
>>> host.read_holding_registers(slave_addr=10, starting_addr=93, register_qty=5, signed=False)
(29, 38, 0, 1600, 2150)
>>> host.read_holding_registers(slave_addr=10, starting_addr=93, register_qty=1, signed=False)
(29,)
>>>