The following UF2 file is a fork of MicroPython for the Raspberry Pi Pico 2 with a Modbus RTU module that runs on the Pico's 2nd core.
Download micropython-plc-2026-01-23.uf2
Example Code:
from machine import UART import modbus import array import time # UART configuration #-------------------------------------------------------------------------------------------------- UART_ID = 0 # UART0 or UART1 BAUD_RATE = 9600 # Common: 9600, 19200, 38400, 115200 PARITY = None # None, 0 (Even), or 1 (Odd) DATA_BITS = 8 # 5-8 STOP_BITS = 1 # 1 or 2 uart = UART(UART_ID, baudrate=BAUD_RATE, bits=DATA_BITS, parity=PARITY, stop=STOP_BITS) # Modbus configuration #-------------------------------------------------------------------------------------------------- SLAVE_ADDRESS = 1 NUM_COILS = 16 NUM_DISCRETE_INPUTS = 16 NUM_REGISTERS = 8 # Coils: binary outputs (bits), stored as bytes # Each byte contains 8 coils coil_memory = bytearray((NUM_COILS + 7) // 8) # 2 bytes for 16 coils # Discrete Inputs: binary inputs (bits), stored as bytes # Each byte contains 8 discrete inputs discrete_input_memory = bytearray((NUM_DISCRETE_INPUTS + 7) // 8) # 2 bytes for 16 discrete inputs # Registers: 16-bit unsigned integers register_memory = array.array('H', [0] * NUM_REGISTERS) # Start Modbus RTU slave on the UART modbus.start_modbus(SLAVE_ADDRESS, coil_memory, discrete_input_memory, register_memory, uart) # Main program #-------------------------------------------------------------------------------------------------- # Helper function to print bits from bytearray def print_bits(label, byte_memory, num_bits): print(f"{label}[{num_bits}]: ", end="") for i in range(num_bits): byte_index = i // 8 bit_index = i % 8 bit = (byte_memory[byte_index] >> bit_index) & 0x1 print("1" if bit else "0", end="") print(" ", end="") # Main loop try: while True: # Print modbus memory contents print_bits("Coils", coil_memory, NUM_COILS) print_bits("DI", discrete_input_memory, NUM_DISCRETE_INPUTS) print("Regs[{}]: ".format(NUM_REGISTERS), end="") for i in range(NUM_REGISTERS): print("{0:05d} ".format(register_memory[i]), end="") # print to the same line print("\r", end="") time.sleep_ms(250)