Skip to content
Back to resources

Modbus RTU on Industrial Arduino: A Practical Guide

Wire RS-485, run a Modbus RTU master and slave on MPINO controllers with the ILIB library, and integrate with HMIs and SCADA.

9 min read

What Modbus RTU Is and Why It Dominates Industrial Networks

Modbus RTU is a serial communication protocol introduced by Modicon in 1979 and is still the de facto standard for connecting field devices, PLCs, HMIs, and SCADA systems in industrial automation. It defines a compact, binary, request-response message format transmitted over a serial physical layer, most commonly RS-485. A single master polls one or more slaves, each identified by a unique 1-247 address, and every transaction is protected by a 16-bit CRC so that electrical noise on a factory floor does not corrupt your process data.

The protocol organizes device memory into four address spaces: discrete inputs (read-only bits), coils (read/write bits), input registers (read-only 16-bit words), and holding registers (read/write 16-bit words). This simple model maps cleanly onto the physical I/O of an ILOGICS MPINO controller: digital inputs become discrete inputs, relay and transistor outputs become coils, and analog channels become input registers.

For an industrial Arduino such as the MPINO-8A8R or MPINO-16A8R8T, Modbus RTU is the bridge between low-cost, openly programmable hardware and the existing instrumentation an integrator already owns. Because virtually every HMI and SCADA package ships a Modbus RTU driver, exposing your MPINO as a Modbus slave means it interoperates with equipment from dozens of vendors without custom protocol work.

RS-485 Physical Wiring for Modbus RTU

Modbus RTU on the MPINO family rides on a two-wire (plus common) RS-485 bus. All devices connect in a daisy-chained multi-drop topology: A to A, B to B, and a shared signal ground (GND/COM) running alongside the data pair. Avoid star or stub wiring; long stubs create reflections that corrupt the bit timing the CRC depends on.

The MPINO uses an auto-direction RS-485 transceiver, which means the firmware does not need to toggle a separate driver-enable (DE/RE) pin before and after each transmission. The transceiver senses the UART transmit line and switches between drive and receive automatically, eliminating a common source of timing bugs where the master releases the bus too early or too late.

Terminate both physical ends of the bus with a 120Ω resistor across A and B to match the characteristic impedance of the cable, and add fail-safe bias resistors so the idle line sits in a defined state. Use shielded twisted-pair cable rated for RS-485, bond the shield to ground at one end only, and keep the run away from VFD and motor power cabling. The MPINO-8A8R-S and MPINO-16A16R expose RS-485 plus I²C, while the ATmega2560-based MPINO-8A8R, MPINO-16A8R8T, and MPINO-16A8R add RS-232 and UART alongside RS-485 for additional connectivity options.

Master versus Slave: Choosing the MPINO Role

In Modbus RTU exactly one device is the master and initiates every transaction; all other devices are slaves that respond only when addressed. The MPINO can operate in either role, and the ILOGICS ILIB library implements both a Modbus RTU master and a Modbus RTU slave stack.

Configure the MPINO as a slave when an existing HMI, SCADA front-end, or PLC must read its inputs and command its relays. The HMI becomes the master, polling holding registers and coils on a fixed scan interval. This is the most common deployment: the MPINO behaves like a remote I/O block that any Modbus master can address.

Configure the MPINO as a master when it must orchestrate other field devices, for example reading a Modbus power meter, a temperature transmitter, or a variable-frequency drive and reacting locally. In master mode the MPINO sketch issues read and write function codes on a schedule and processes the responses. A single MPINO can even act as a slave to an upstream SCADA system on one port while mastering downstream devices, though on a single RS-485 segment a device holds one role at a time.

Register and Coil Mapping for MPINO I/O

A clean, documented register map is the contract between your MPINO firmware and every client that talks to it. Decide the mapping once and keep it stable across firmware revisions. A typical convention for an MPINO-8A8R exposes the 8 digital inputs as discrete inputs 10001-10008, the 8 relay outputs as coils 00001-00008, and the 4 analog inputs as input registers 30001-30004.

Analog values deserve special care. The MPINO analog front end requires analogReference(EXTERNAL); the 10-bit ADC then returns a 0-1023 count that you can publish raw in an input register or scale to engineering units in firmware. Document the scaling factor in the register map so the HMI integrator knows whether register 30001 carries raw counts, millivolts, or a process value.

For a larger controller such as the MPINO-16A8R8T, extend the map to cover 16 digital inputs, 8 relay plus 8 transistor outputs as coils, the 4 analog inputs and 2 analog outputs as registers, and the 2 NTC temperature channels as additional input registers. Publishing the full map as a one-page document alongside the product turns the MPINO into a drop-in remote I/O node for any Modbus master.

Implementing Modbus RTU with the ILIB Library

The ILOGICS ILIB library provides a Modbus RTU implementation tuned for MPINO hardware and the auto-direction RS-485 transceiver, so you write application logic rather than protocol plumbing. You program the board in the standard Arduino IDE with the MegaCore core selected for the ATmega128 or ATmega2560 target.

The snippet below configures an MPINO-8A8R as a Modbus RTU slave at address 1, 19200 baud, mapping the 8 digital inputs and 8 relay coils so an HMI master can read live input states and command the relays. Because the transceiver is auto-direction, the sketch never touches a DE/RE pin.

After flashing, point any Modbus RTU master at slave address 1 and poll the mapped coils and discrete inputs to confirm the wiring and CRC are healthy before integrating with the wider control system.

#include <ILIB.h>

// MPINO-8A8R as Modbus RTU slave, address 1, 19200 baud
ModbusSlave mb;

const uint8_t DI_PINS[8] = {22,23,24,25,26,27,28,29};
const uint8_t RELAY_PINS[8] = {30,31,32,33,34,35,36,37};

void setup() {
  analogReference(EXTERNAL);          // required for MPINO analog
  for (uint8_t i = 0; i < 8; i++) {
    pinMode(DI_PINS[i], INPUT);
    pinMode(RELAY_PINS[i], OUTPUT);
  }
  mb.begin(1, 19200);                 // slave id 1, RS-485 auto-direction
}

void loop() {
  // Map 8 digital inputs -> discrete inputs 1..8
  for (uint8_t i = 0; i < 8; i++)
    mb.setDiscreteInput(i, digitalRead(DI_PINS[i]));

  mb.poll();                          // service master requests

  // Apply coils 1..8 -> 8 relays
  for (uint8_t i = 0; i < 8; i++)
    digitalWrite(RELAY_PINS[i], mb.getCoil(i));
}

Integrating with HMI and SCADA

Once the MPINO answers Modbus RTU correctly, integration with an HMI or SCADA platform is a configuration exercise. In the HMI driver, create a Modbus RTU serial channel matching the MPINO baud rate, parity, and stop bits, then add the slave at its configured address. Bind screen objects to the coils, discrete inputs, and registers from your published map.

Keep the poll rate realistic. An ATmega128 or ATmega2560 servicing a few dozen points responds comfortably to scan intervals of 100-500 ms; aggressive sub-50 ms polling of many registers can starve the application loop. Group related points into contiguous register blocks so the master reads them in a single function call, reducing bus traffic and latency.

For SCADA tags that drive alarms or interlocks, confirm the MPINO publishes real values, never a placeholder while it boots. Initialize registers to a known safe state in setup() and only mark a point valid once its source has been read. This discipline keeps the MPINO a trustworthy node in a production control network.

Controllers covered

MPINO-8A8R-S industrial Arduino controller — front view

MPINO-8A8R-S

MPINO-8A8R-S Industrial Arduino Controller

8 DI / 8 Relay / 4 AI / 2 NTC / RS-485 / I²C
$86.00
MPINO-8A8R industrial Arduino controller — front view

MPINO-8A8R

MPINO-8A8R Industrial Arduino Controller

8 DI / 8 Relay / 4 AI / RS-232 / RS-485 / UART / I²C
$92.00
MPINO-16A8R8T industrial Arduino controller — front view

MPINO-16A8R8T

MPINO-16A8R8T Industrial Arduino Controller

16 DI / 8 Relay / 8 Transistor / 4 AI / 2 AO / 2 NTC / RS-232 / RS-485 / UART / I²C
$115.00

Related guides

FAQ

Which MPINO models support Modbus RTU over RS-485?

All listed MPINO controllers expose RS-485 and run Modbus RTU through the ILIB library. The MPINO-8A8R-S and MPINO-16A16R use the ATmega128 with RS-485 and I²C; the MPINO-8A8R, MPINO-16A8R8T, and MPINO-16A8R use the ATmega2560 and add RS-232 and UART alongside RS-485.

Do I need to control a DE/RE pin for RS-485 transmit direction?

No. The MPINO uses an auto-direction RS-485 transceiver that switches between drive and receive automatically based on the UART transmit line. Your sketch and the ILIB library never toggle a driver-enable pin, which removes a frequent source of Modbus timing errors.

Can one MPINO be both a Modbus master and a slave?

On a single RS-485 segment a device holds one role at a time. ILIB supports both master and slave stacks, so an MPINO with multiple serial ports can act as a slave to an upstream SCADA master while mastering downstream devices on a separate port.