brainelectronics / micropython-modbus

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

not able to read more than 57 holding register (03 illegal data value) #94

Open Invtsol opened 2 months ago

Invtsol commented 2 months ago

Description

I am using W5100S-EVB-PICO with micropython modbus my controller is connected with modpoll software. every thing in ok until I write holding register less then 57 from modpoll. as soon as I write holding register 58 or greater then getting error (03 illegal data value) I am actually controlling ws2812b led over modbus tcp/ip, any help is much appriciated. here is my main.py

Reproduction steps

  1. cant handle holding register more than 57
  2. ...

MicroPython version

2.3.7

MicroPython board

Raspberry Pico

MicroPython Modbus version

Installed version: 2.3.7
Installed to: /lib

Latest stable version: 2.3.7

Relevant log output

firmware version
v1.19.1 (2022-06-18) .uf2

User code

from machine import Pin, SPI
from umodbus.tcp import ModbusTCP
import time
import network
from neopixel import NeoPixel

# Setup WS2812B LEDs
NUM_LEDS = 88
PIN_LED = 15  # Pin for WS2812B LED
led = NeoPixel(Pin(PIN_LED), NUM_LEDS)

# Global variable to store the holding register values
holding_registers = [0] * NUM_LEDS

# W5x00 chip init
def w5x00_init():
    try:
        spi = SPI(0, 2_000_000, mosi=Pin(19), miso=Pin(16), sck=Pin(18))
        nic = network.WIZNET5K(spi, Pin(17), Pin(20))  # spi, cs, reset pin
        nic.active(True)
        nic.ifconfig(('192.168.1.20', '255.255.255.0', '192.168.1.1', '8.8.8.8'))
        while not nic.isconnected():
            time.sleep(1)
        return nic
    except Exception as e:
        return None

# Function to update LEDs based on holding register values
def update_leds():
    for i in range(NUM_LEDS):
        val = holding_registers[i]
        if val == 1:
            led[i] = (0, 10, 0)  # Green color
        elif val == 2:
            led[i] = (10, 0, 0)  # Red color
        else:
            led[i] = (0, 0, 0)  # Turn off LED
    led.write()

# Callback function to control WS2812B LEDs based on register value
def LED_cb(reg_type, address, val):
    if address < NUM_LEDS:
        num_values_to_update = min(NUM_LEDS - address, len(val))
        for i in range(num_values_to_update):
            holding_registers[address + i] = val[i]
        update_leds()

def main():
    nic = w5x00_init()
    if nic is None:
        return

    tcp_port = 502
    local_ip = '192.168.1.20'

    server = ModbusTCP()
    if not server.get_bound_status():
        server.bind(local_ip=local_ip, local_port=tcp_port)

    register_definitions = {
        "HREGS": {
            f"LED_{i}": {"register": i, "len": 1, "val": 0, "on_set_cb": LED_cb}
            for i in range(NUM_LEDS)
        }
    }

    server.setup_registers(registers=register_definitions)

    while True:
        try:
            server.process()
        except KeyboardInterrupt:
            break
        except Exception as e:
            pass

if __name__ == "__main__":
    main()

Additional informations

please help