Modbus RTU Slave for MicroPython

An open-source Modbus RTU slave for MicroPython, with a working example on the IoTextra Octal2 digital I/O module. Your IoTsmart or IoTbase PICO board answers a PLC, SCADA system, Node-RED or any other Modbus master over RS485. The code is MIT licensed and has no external Modbus dependencies.

This is an example you can copy and adapt: the register map is written by hand in the example script.

What it does

  • Modbus RTU slave: function codes 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x0F and 0x10.
  • Broadcast (address 0): the write is applied, no reply is sent.
  • The engine knows nothing about IoTextra hardware: your code builds the register map and applies writes to the real I/O.
  • Works with a standard isolated UART-RS485 adapter with automatic direction control (no DE/RE pin needed).

Example: IoTextra Octal2 as a Modbus slave

Octal2 has 4 digital inputs and 4 digital outputs. In the example they appear to the Modbus master as follows:

Modbus table Address Octal2
Discrete inputs (FC02) 0–3 Digital inputs 0–3
Coils (FC01, FC05, FC0F) 0–3 Digital outputs 4–7 (LED 1–4)

A PC master script from the same repository switches the outputs on and off one by one and shows input changes. Analog modules are not covered.

Tested hardware

Tested with an external isolated Waveshare UART-RS485 adapter, one slave on the bus, slave address 1, 8N1.

Board UART TX / RX 9600 115200
IoTsmart RP2040 UART0 GPIO0 / GPIO1 pass pass
IoTbase PICO with Raspberry Pi Pico 2 W (RP2350) UART0 GPIO0 / GPIO1 pass pass
IoTsmart ESP32-S3 UART1 GPIO43 / GPIO44 pass pass*

Each board: 500 of 500 consecutive reads at both baud rates, 0% errors. Masters used: pymodbus, QModMaster and minimalmodbus. IoTsmart RP2350A and multi-drop buses (several slaves on one line) have not been tested yet.

* On ESP32-S3 at 115200, detach the MicroPython REPL from the Modbus UART first: import os; os.dupterm(None).

Quick start

  1. Flash MicroPython on your IoTsmart or IoTbase PICO board.
  2. Copy modbus_slave.py from the repository to the board (for example into lib/).
  3. Copy the files from examples/octal2/ (except octal2_master.py) to the board and run main_octal2.py, or save it as main.py.
  4. Connect the board to the RS485 adapter: 3V3 to 3V3, GND to GND, board TX to adapter RX, board RX to adapter TX. Connect the adapter A/B lines to your Modbus master.
  5. On the PC: pip install -r requirements.txt, then python examples/octal2/octal2_master.py --port YOUR_PORT --baud 115200.

Get the code

modbus-rtu-slave-example on GitHub — the engine, the Octal2 example, PC test scripts and the full bring-up report with wiring and timing results.

Hardware used in the example