brainelectronics / micropython-modbus

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

Bug: `write_single_coil()` is settting all other coils to `False` #24

Closed beyonlo closed 1 year ago

beyonlo commented 2 years ago

This bug was extracted from PR #10 report, in this reply:

I suppose that write_single_coil(), without use a list of coils, will write just on the first position, like as I asked on the #15

When I try to use write_single_coil() to write on the first position, all others coils positions are changed to False.

>>> host.read_coils(slave_addr=10, starting_addr=123, coil_qty=1)
[False, True, True, False, False, False, False, False]   <---- See that is (False, True, True..) like as on the "definitions"
>>> host.write_single_coil(slave_addr=10, output_address=123, output_value=1)
False
>>> host.read_coils(slave_addr=10, starting_addr=123, coil_qty=1)
[True, False, False, False, False, False, False, False] <---- Here all coils after first position was changed to "False"
>>> 

Using this register_definitions: {'ISTS': {'EXAMPLE_ISTS': {'register': 67, 'len': 1, 'val': 0}}, 'IREGS': {'EXAMPLE_IREG': {'register': 10, 'len': 2, 'val': 60001}}, 'HREGS': {'EXAMPLE_HREG': {'register': 93, 'len': 1, 'val': 19}}, 'COILS': {'EXAMPLE_COIL': {'register': 123, 'len': 3, 'val': [0, 1, 1]}}}

brainelectronics commented 2 years ago

Relates to #21 and #15 see also #18

brainelectronics commented 1 year ago

Relates to #36

brainelectronics commented 1 year ago

@beyonlo i think this issue can be closed as well after #33 was merged

beyonlo commented 1 year ago

@brainelectronics I don't thing so, because this problem still exists on the 2.1.0-rc15.dev39 version:

register_definitions = {
    "COILS": {
        "RESET_REGISTER_DATA_COIL": {
            "register": 42,
            "len": 1,
            "val": 0
        },
        "RESET_REGISTER_DATA_COIL_2": {
            "register": 45,
            "len": 1,
            "val": 0
        },
        "EXAMPLE_COIL": {
            "register": 123,
            "len": 16,
            "val": [1,0,0,1,1,0,1,1,1,1,1,1,1,1,0,1]
        },
...

Slave:

$ mpremote run tcp_client_example.py
Waiting for WiFi connection...
Waiting for WiFi connection...
Waiting for WiFi connection...
Waiting for WiFi connection...
Connected to WiFi.
('192.168.1.4', '255.255.255.0', '192.168.1.1', '192.168.1.1')
Setting up registers ...
Register setup done
Running ModBus version: 2.1.0-rc15.dev39
Serving as TCP client on 192.168.1.4:502

Master:

>>> from umodbus.tcp import TCP as ModbusTCPMaster
>>> host = ModbusTCPMaster(slave_ip='192.168.1.4', slave_port=502, timeout=5)
>>> from umodbus import version
>>> version.__version__
'2.1.0-rc15.dev39'
>>> host.read_coils(slave_addr=10, starting_addr=123, coil_qty=16)
[True, False, False, True, True, False, True, True, True, True, True, True, True, True, False, True]
>>> host.write_single_coil(slave_addr=10, output_address=123, output_value=0)
True
>>> host.read_coils(slave_addr=10, starting_addr=123, coil_qty=16)
[False, False, False, False, False, False, False, False] <---- Here all coils after first position was changed to "False"
>>> 

As the address 123 is a list of values with all 16 bits set. When I write just a single COIL (output_value=0) in that address happen:

  1. Firstly that is not anymore 16 bits, but it turn to just 8 bits now
  2. And that 8 bits now are all False

So, that is a problem right?

And there is a far relation with the #15 where I still curious how I do to write a single COIL in a different position than just first - that is default when I do output_value=0 right?

This will write a single COIL in the first bit on the address 123 right? >>> host.write_single_coil(slave_addr=10, output_address=123, output_value=0)

How I do to write a single COIL in the second bit on the address 123?

Edit:

I see the new register usage docs, where the 0x05 write_single_coil talk about how to write single COIL just on the first position, but do not talk about how to write a COIL in a different position than the first one, like as the second position and so on.

brainelectronics commented 1 year ago

Relates to #35

brainelectronics commented 1 year ago

Fixed in 2.3.1