MicroPython PLC

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)