If you’re working on an industrial automation project or building a data-acquisition system, mastering Arduino Modbus RTU communication is an essential skill. Modbus RTU is one of the oldest and most widely-used serial communication protocols in industrial automation — found in PLCs, energy meters, temperature controllers, VFDs, and countless industrial sensors. This tutorial walks you through everything you need to know to read real industrial sensors using an Arduino and an RS485 transceiver.
Table of Contents
- What Is Modbus RTU?
- RS485 Physical Layer Basics
- Hardware Setup for Arduino Modbus RTU
- Choosing a Modbus Library
- Reading a Modbus RTU Sensor: Step-by-Step Code
- Controlling a Modbus RTU Relay Module
- Troubleshooting Modbus RTU Issues
- Frequently Asked Questions
What Is Modbus RTU?
Modbus is a communication protocol developed by Modicon in 1979 and remains the de-facto standard for industrial serial communication to this day. Modbus RTU (Remote Terminal Unit) is the binary variant that operates over a serial bus — typically RS485 or RS232.
The protocol follows a master-slave (now often called controller-responder) architecture:
- Master (Controller): Initiates all communication. Only one master exists on the bus.
- Slave (Responder): Responds only when addressed by the master. Up to 247 slaves can share a single RS485 bus.
Modbus Data Types
Modbus organises data into four primary register types:
| Type | Access | Data | Function Code |
|---|---|---|---|
| Coils (0x) | Read/Write | Single bits (ON/OFF) | FC01, FC05, FC15 |
| Discrete Inputs (1x) | Read only | Single bits | FC02 |
| Input Registers (3x) | Read only | 16-bit words | FC04 |
| Holding Registers (4x) | Read/Write | 16-bit words | FC03, FC06, FC16 |
RTU framing encodes each byte as 8 bits of data, uses a CRC-16 checksum, and relies on silent intervals (3.5 character times) to delimit frames. This is why timing is critical in Modbus RTU implementations.
RS485 Physical Layer Basics
Modbus RTU most commonly runs over an RS485 differential serial bus. Unlike RS232 (which is single-ended and limited to about 15 metres), RS485 uses differential signalling (+/- pair) which gives it:
- Cable runs up to 1,200 metres
- Up to 32 standard loads (247 Modbus addresses)
- Excellent noise immunity in industrial environments
- Half-duplex (shared TX and RX lines) or full-duplex (4-wire)
The RS485 bus uses two wires typically labelled A (or D+) and B (or D-). When A is more positive than B, the bit is a logical 1; when B is more positive, it’s a logical 0. This differential signalling cancels out common-mode noise picked up along the cable run.
Termination resistors: For long cable runs (over 10–15 metres), place a 120 Ω resistor between A and B at each end of the bus. Most commercial Modbus devices have switchable termination built in.
Hardware Setup for Arduino Modbus RTU
You need three components to connect an Arduino to a Modbus RTU network:
- Arduino board — Uno, Mega, or Nano all work. The Mega is preferred for projects where you need to keep the hardware serial port free for debugging.
- RS485 transceiver module — A module based on the MAX485 or similar IC, which converts the Arduino’s UART signals to RS485 differential levels.
- Modbus RTU device — A sensor, relay module, energy meter, etc. with an RS485 port.
Wiring the MAX485 Module to Arduino
MAX485 Pin → Arduino Pin
VCC → 5V
GND → GND
DI (Data In) → TX pin (e.g., D1 or Serial1 TX on Mega)
RO (Recv Out) → RX pin (e.g., D0 or Serial1 RX on Mega)
DE (Driver Enable) → D2
RE (Receiver Enable) → D2 (tie DE and RE together)
RS485 A → Modbus Device A (D+)
RS485 B → Modbus Device B (D−)
Important: DE and RE are active-high and active-low respectively. Tie them together and connect to a single Arduino pin. Pull this pin HIGH to transmit, LOW to receive. This is the half-duplex direction control that many Modbus libraries handle automatically.
Choosing a Modbus Library
Several Modbus libraries exist for Arduino. The most popular choices are:
- ArduinoModbus (by Arduino) — Official library, clean API, built on the RS485 library. Easiest for beginners.
- ModbusMaster (by Doc Walker) — Lightweight, widely used, good for master-only projects. Install from Arduino Library Manager.
- Modbus-esp8266 — Works on both ESP8266/ESP32 and Arduino, supports Modbus TCP and RTU.
For this tutorial we’ll use the ModbusMaster library as it provides the most direct control and is the most commonly referenced in industrial Arduino projects.
Install it: Arduino IDE → Tools → Manage Libraries → Search “ModbusMaster” → Install
Reading a Modbus RTU Sensor: Step-by-Step Code
Let’s read temperature from a common Modbus RTU temperature/humidity transmitter (slave address 1, holding register 0x0000 for temperature, scale factor 0.1).
#include <ModbusMaster.h>
#define RS485_DE_PIN 2 // Direction control pin
ModbusMaster node;
void preTransmission() {
digitalWrite(RS485_DE_PIN, HIGH); // Enable driver
}
void postTransmission() {
digitalWrite(RS485_DE_PIN, LOW); // Enable receiver
}
void setup() {
Serial.begin(115200); // Debug output
Serial1.begin(9600); // Modbus RTU @ 9600 baud (check your device datasheet)
pinMode(RS485_DE_PIN, OUTPUT);
digitalWrite(RS485_DE_PIN, LOW);
// node.begin(slaveAddress, serialPort)
node.begin(1, Serial1);
// Attach DE/RE toggle callbacks
node.preTransmission(preTransmission);
node.postTransmission(postTransmission);
}
void loop() {
uint8_t result;
uint16_t data;
// Read 1 holding register starting at address 0x0000
result = node.readHoldingRegisters(0x0000, 1);
if (result == node.ku8MBSuccess) {
data = node.getResponseBuffer(0);
float temperature = data / 10.0; // Scale factor 0.1
Serial.print("Temperature: ");
Serial.print(temperature);
Serial.println(" °C");
} else {
Serial.print("Modbus error: 0x");
Serial.println(result, HEX);
}
delay(2000);
}
Understanding the Result Codes
When readHoldingRegisters() returns something other than ku8MBSuccess, check these common error codes:
0xE0— Response timed out. Check baud rate, wiring, and slave address.0xE1— Data not complete. Usually a framing or noise issue.0xE2— CRC error. Noise on the bus or incorrect wiring.0x01— Illegal function. The slave doesn’t support this function code.0x02— Illegal data address. The register address doesn’t exist on the slave.
Controlling a Modbus RTU Relay Module
Writing to coils (individual output bits) is done with writeSingleCoil(). For the common 4-channel Modbus relay module:
// Turn ON relay 1 (coil address 0x0000)
result = node.writeSingleCoil(0x0000, 0xFF00); // 0xFF00 = ON, 0x0000 = OFF
if (result == node.ku8MBSuccess) {
Serial.println("Relay 1 ON");
} else {
Serial.print("Write error: 0x");
Serial.println(result, HEX);
}
delay(2000);
// Turn OFF relay 1
result = node.writeSingleCoil(0x0000, 0x0000);
For writing to holding registers (used by some relay modules and by configuration registers on many Modbus devices):
// Write value 1 to holding register 0x0001
result = node.writeSingleRegister(0x0001, 1);
Troubleshooting Modbus RTU Issues
1. Always timeout (0xE0)
- Verify baud rate matches the slave device datasheet (common values: 9600, 19200, 38400)
- Verify slave address matches what’s configured on the device (check DIP switches or device menu)
- Check A/B polarity — some devices label them differently. Swap A and B if timeouts persist.
- Ensure DE/RE toggling is fast enough — the
preTransmissioncallback must fire before bytes are sent
2. CRC errors (0xE2)
- Add termination resistors (120 Ω between A and B) if cable is over 10 metres
- Check for ground loops — ensure device ground and Arduino GND are connected
- Reduce baud rate to 9600 as a test; if CRC errors disappear, the cable is too noisy for higher speeds
3. Wrong data values
- Double-check the register address in the device datasheet — Modbus addresses are often listed as 1-indexed (40001 = register 0x0000 in 0-indexed API calls)
- Check byte order: some devices send big-endian, others little-endian for 32-bit floating point values spread across two registers
- Verify the scale factor — energy meters often multiply values by 10, 100, or 1000
4. Using SoftwareSerial instead of hardware serial
If you’re using an Arduino Uno (which has only one hardware serial port shared with USB), use SoftwareSerial for the RS485 communication and keep Serial for debug. However, SoftwareSerial is unreliable above 9600 baud and can miss bytes — prefer hardware serial whenever possible, which is why the Mega is recommended for serious Modbus projects.
Frequently Asked Questions
What’s the difference between Modbus RTU and Modbus TCP?
Modbus RTU runs over a serial bus (RS485/RS232) using binary framing with CRC. Modbus TCP runs over Ethernet using TCP/IP and replaces the CRC with TCP’s built-in error checking. The register map and function codes are identical — only the transport layer differs. For Ethernet-connected devices, use an Arduino Ethernet shield with a Modbus TCP library.
How many Modbus devices can I connect to one Arduino?
The RS485 standard supports up to 32 unit loads per segment (extendable with repeaters to 247 Modbus addresses). You address each device by its slave ID (1–247) in your master code. All devices share the same A and B wires; only one talks at a time.
Can I use ESP32 instead of Arduino for Modbus RTU?
Yes, and it’s often a better choice for IoT applications. The ESP32 has two hardware serial ports, runs the ModbusMaster library without modification, and can send Modbus data to the cloud over Wi-Fi. Use Serial2 for the RS485 port and Serial for debug.
My device has a 32-bit float register — how do I read it?
Read two consecutive 16-bit registers and combine them. The standard way is to read two holding registers with readHoldingRegisters(startAddr, 2), then use a union or memcpy to reinterpret the two 16-bit words as a 32-bit float, paying attention to byte order (big-endian vs little-endian per the device datasheet).
What baud rate should I use?
The most common Modbus RTU baud rate is 9600. Many industrial devices default to this. Check your device’s datasheet or configuration menu. If you have multiple devices on the same bus, all must use the same baud rate.
Ready to build your industrial sensor network? Shop Arduino boards and RS485 Modbus modules at Zbotic — all essential components for your industrial automation project, shipped across India.
Add comment