The Arduino Opta RS485 and Arduino Opta WiFi include a built-in half-duplex RS-485 interface that can be used directly for Modbus RTU.
You do not need an external USB-to-RS485 converter or separate transceiver.
The important details are:
|
1 2 3 4 5 6 7 8 9 10 11 |
A(-) B(+) GND half-duplex RS-485 external termination when required Modbus address 1-247 baud / parity / stop bits must match |
Opta Lite does not include the RS-485 interface, so native Modbus RTU wiring requires either Opta RS485 or Opta WiFi.
Which Opta Models Support Modbus RTU?
| Opta model | RS-485 | Native Modbus RTU |
|---|---|---|
| Opta Lite | No | No |
| Opta RS485 | Half-duplex | Yes |
| Opta WiFi | Half-duplex | Yes |
All three Opta versions still support Modbus TCP through their built-in Ethernet port.
Opta RS-485 Terminal Pinout
The RS-485 terminal block is labelled:
|
1 2 3 4 5 6 |
A(-) B(+) GND |
For another Opta, connect:
|
1 2 3 4 5 6 |
Opta 1 A(-) → Opta 2 A(-) Opta 1 B(+) → Opta 2 B(+) Opta 1 GND → Opta 2 GND |
A/B Naming Is Not Consistent Between Manufacturers
This is one of the most common RS-485 problems.
Arduino follows:
|
1 2 3 4 5 |
A → A(-) B → B(+) |
but other manufacturers may use:
|
1 2 3 4 5 6 7 |
A / B D+ / D- + / - 485+ / 485- |
and some vendors reverse the A/B convention.
If an Opta is wired to a third-party device and there is no communication, one of the first checks should be the data-line polarity.
Arduino specifically notes that reversing A(-) and B(+) will not normally damage the RS-485 hardware, but communication will fail until polarity is correct.
Use a Common Reference Ground
For short same-cabinet links, connect:
|
1 2 3 4 |
GND ↔ GND |
as shown in Arduino’s Opta wiring diagrams.
On long industrial links, cable shielding, equipotential bonding and galvanic-isolation requirements depend on the installation.
Do not assume that connecting two distant cabinet grounds is automatically safe just because both devices use RS-485.
Opta Has No Built-In RS-485 Termination
This is critical.
Arduino explicitly states that Opta:
|
1 2 3 4 5 |
does not contain an internal RS-485 termination resistor |
so termination must be added externally where required by the bus topology.
Typical Termination
A normal RS-485 trunk uses a termination resistor at:
|
1 2 3 4 5 6 |
physical end 1 and physical end 2 |
of the main cable.
Common values are around:
|
1 2 3 4 |
120 Ω |
but the correct value should match the cable characteristic impedance and the Modbus/RS-485 network design.
Do Not Terminate Every Device
If five devices are installed on one bus, you normally do not fit five 120 Ω resistors.
Termination is normally located only at the two physical ends of the trunk.
Too much termination loads the bus and can reduce the differential voltage.
Cable Recommendations
Arduino’s current Opta Modbus tutorial recommends twisted-pair cable in the general range of:
|
1 2 3 4 5 6 |
24-18 AWG or 22-16 AWG |
with cable impedance in the region of:
|
1 2 3 4 |
100-130 Ω |
depending on whether the cable assembly already includes termination.
For longer runs, use proper twisted-pair industrial RS-485 cable rather than loose hookup wire.
Half-Duplex Operation
Opta RS485 and Opta WiFi use:
|
1 2 3 4 |
half-duplex RS-485 |
which means the same differential pair is used alternately for transmit and receive.
A device cannot transmit and receive simultaneously.
Modbus RTU Client and Server Roles
Modern Modbus terminology uses:
|
1 2 3 4 5 6 7 8 |
Client → sends requests Server → replies to requests |
Older documentation often uses:
|
1 2 3 4 5 |
Master Slave |
for the same basic relationship.
Arduino PLC IDE currently exposes both modern and legacy terminology in different parts of the interface and documentation.
Server Address Range
Arduino PLC IDE allows an Opta Modbus RTU server address in the range:
|
1 2 3 4 |
1 to 247 |
Each server on the bus must have a unique address.
Baud Rate and Serial Format
Every device on the Modbus RTU segment must use the same:
- baud rate;
- data bits;
- parity;
- stop bits.
Arduino PLC IDE currently offers baud rates from:
|
1 2 3 4 5 6 |
600 to 115200 bit/s |
with:
|
1 2 3 4 5 6 |
8 data bits No / Even / Odd parity 1 or 2 stop bits |
Typical Modbus Settings
Common configurations include:
|
1 2 3 4 5 6 7 |
9600 8N1 19200 8N1 19200 8E1 38400 8N1 |
There is no universal setting.
The Opta must match the device it is communicating with.
Arduino’s PLC IDE Example Uses 19200 8N1
Arduino’s current Opta-to-Opta PLC IDE tutorial demonstrates:
|
1 2 3 4 5 6 7 |
19200 bit/s No parity 8 data bits 1 stop bit |
with one Opta configured as the Modbus RTU server and another as the client.
Modbus Data Types
Modbus defines four main data tables:
| Data type | Typical notation | Access |
|---|---|---|
| Coils | 0xxxx | Read/write bits |
| Discrete Inputs | 1xxxx | Read-only bits |
| Input Registers | 3xxxx | Read-only 16-bit registers |
| Holding Registers | 4xxxx | Read/write 16-bit registers |
Register Addressing Causes Frequent Errors
A manual may describe a value as:
|
1 2 3 4 |
40001 |
while a software library expects:
|
1 2 3 4 |
address 0 |
because the leading:
|
1 2 3 4 |
4xxxx |
is a documentation convention rather than part of the transmitted Modbus address.
Always check whether the manufacturer’s register table is:
|
1 2 3 4 5 6 |
0-based or 1-based |
before assuming the first register is address 0 or 1.
Modbus Function Codes
Common functions include:
|
1 2 3 4 5 6 7 8 9 10 11 |
FC01 → Read Coils FC02 → Read Discrete Inputs FC03 → Read Holding Registers FC04 → Read Input Registers FC05 → Write Single Coil FC06 → Write Single Holding Register FC15 → Write Multiple Coils FC16 → Write Multiple Holding Registers |
Arduino Libraries
For Arduino IDE development, two official libraries are relevant:
|
1 2 3 4 5 |
ArduinoRS485 ArduinoModbus |
ArduinoRS485 handles the physical RS-485 serial link.
ArduinoModbus implements Modbus RTU and Modbus TCP protocol operations.
Raw RS-485 Test Before Modbus
When commissioning a new installation, it can be useful to test the physical layer first.
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
#include <ArduinoRS485.h> void setup() { RS485.begin(115200); } void loop() { RS485.beginTransmission(); RS485.endTransmission(); delay(1000); } |
This does not send valid Modbus frames.
It simply confirms that the RS-485 transmitter, wiring and receiving equipment are functioning.
RS-485 Turnaround Delay
Arduino’s current Opta RS-485 example calculates pre- and post-transmission delays based on approximately:
|
1 2 3 4 |
3.5 character times |
which is also important in Modbus RTU because frame separation is timing-based.
The official Arduino RS485 library provides:
|
1 2 3 4 |
RS485.setDelays(...) |
for this purpose.
Simple Modbus RTU Client Example
The following pattern reads one holding register from server ID 10:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
#include <ArduinoRS485.h> #include <ArduinoModbus.h> const int serverId = 10; const int registerAddress = 0; void setup() { Serial.begin(115200); if (!ModbusRTUClient.begin(19200, SERIAL_8N1)) { Serial.println("Failed to start Modbus RTU client"); while (1); } } void loop() { long value = ModbusRTUClient.holdingRegisterRead( serverId, registerAddress ); if (value < 0) { Serial.print("Modbus error: "); Serial.println(ModbusRTUClient.lastError()); } else { Serial.println(value); } delay(500); } |
Reading an Input Register
For a sensor documented as an input register, use:
|
1 2 3 4 5 6 7 |
ModbusRTUClient.inputRegisterRead( serverId, registerAddress ); |
Do not use a holding-register read simply because both are 16-bit values.
Writing a Holding Register
|
1 2 3 4 5 6 7 8 |
ModbusRTUClient.holdingRegisterWrite( serverId, registerAddress, 1500 ); |
This typically produces Modbus function code:
|
1 2 3 4 5 |
FC06 Write Single Register |
Simple Opta Modbus RTU Server Example
An Opta can also expose its own registers:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
#include <ArduinoRS485.h> #include <ArduinoModbus.h> const int serverId = 10; void setup() { if (!ModbusRTUServer.begin( serverId, 19200, SERIAL_8N1)) { while (1); } ModbusRTUServer.configureHoldingRegisters( 0, 10 ); ModbusRTUServer.holdingRegisterWrite( 0, 1234 ); } void loop() { ModbusRTUServer.poll(); // Application logic can update the register. ModbusRTUServer.holdingRegisterWrite( 0, analogRead(A0) ); } |
Why poll() Matters
The server must repeatedly call:
|
1 2 3 4 |
ModbusRTUServer.poll(); |
so incoming requests are processed.
A blocking loop that prevents regular polling can make the server appear unreliable.
Mapping Opta Inputs to Modbus Registers
A typical application might expose:
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
Input Register 0 → I1 analogue value Input Register 1 → I2 analogue value Discrete Input 0 → I3 digital state Holding Register 0 → remote setpoint Coil 0 → Relay 1 command |
This keeps the external Modbus interface independent from the physical pin names.
Using PLC IDE Instead of Arduino C++
Arduino PLC IDE can configure the Opta as:
|
1 2 3 4 5 6 |
Modbus RTU Client or Modbus RTU Server |
without writing low-level Modbus frame code.
The configuration is under:
|
1 2 3 4 5 6 |
Resources → RS485 SerialPort → Modbus Configuration |
PLC IDE Client Configuration
For client mode you define:
- baud rate;
- parity;
- stop bits;
- remote Modbus node address;
- polling time;
- register/function type;
- word-swap mode where required.
PLC IDE Server Configuration
Server mode additionally requires a unique:
|
1 2 3 4 5 |
Modbus address 1-247 |
and variables/registers to expose to clients.
Arduino’s Official PLC IDE Example
The current Arduino tutorial demonstrates:
|
1 2 3 4 5 6 |
Server ID: 10 Baud: 19200 Format: 8N1 |
with a server-side counter exposed through an input register and a second Opta polling it as a client.
Modbus RTU Polling Time
Do not poll every device as fast as the CPU allows.
A practical network may contain:
- drives;
- energy meters;
- temperature controllers;
- remote I/O;
- multiple Opta controllers.
Each request and response consumes bus time.
Choose polling intervals according to how quickly each value actually changes.
Example Polling Strategy
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
Motor status → 100 ms Temperature → 500 ms Energy totals → 1-5 s Configuration → only when needed |
Timeouts
A Modbus client should always have a timeout strategy.
If a drive is disconnected, the Opta should not freeze indefinitely waiting for it.
The ArduinoModbus client API provides timeout/error reporting support that can be used to:
- retry;
- raise an alarm;
- mark a device offline;
- fall back to a safe operating mode.
Data Width: Modbus Registers Are 16 Bit
A Modbus register contains:
|
1 2 3 4 |
16 bits |
but industrial values are often:
- 32-bit integers;
- 32-bit IEEE-754 floats;
- 64-bit energy counters;
- packed bit fields.
Those values span multiple registers.
Word Order Can Differ
A 32-bit value may be transmitted as:
|
1 2 3 4 5 6 |
high word first or low word first |
and byte order may also differ between devices.
Arduino PLC IDE includes a word-swap setting for this reason.
Example: Float Across Two Registers
If a manual says:
|
1 2 3 4 5 6 |
Register 100 Register 101 → IEEE-754 float |
you must know:
- which register contains the high word;
- which contains the low word;
- byte endianness inside each word.
Do not assume that all Modbus float implementations use the same order.
Common Mistake 1: Using Opta Lite
Opta Lite has Ethernet and can run Modbus TCP, but it does not have the RS-485 terminal hardware required for native Modbus RTU.
Common Mistake 2: Forgetting Termination
Opta has no built-in RS-485 termination.
If the Opta is at a physical end of the trunk, termination may need to be installed externally.
Common Mistake 3: Terminating Every Node
Only the physical ends of the main RS-485 trunk should normally be terminated.
Common Mistake 4: A/B Reversed
If the bus is silent, verify:
|
1 2 3 4 5 |
Opta A(-) Opta B(+) |
against the other manufacturer’s polarity notation.
Common Mistake 5: Wrong Serial Format
These must match exactly:
|
1 2 3 4 5 6 7 |
baud parity data bits stop bits |
A device using 19200 8E1 will not communicate correctly with an Opta configured for 19200 8N1.
Common Mistake 6: Wrong Device Address
Each server must have a unique address from:
|
1 2 3 4 |
1-247 |
Common Mistake 7: Register Off-by-One Error
If the manual says:
|
1 2 3 4 |
Holding Register 40001 |
the library may expect:
|
1 2 3 4 |
address 0 |
Check the vendor’s addressing convention before changing the wiring or baud rate.
Common Mistake 8: Wrong Register Type
FC03 and FC04 both return 16-bit words, but:
|
1 2 3 4 5 6 7 8 |
FC03 → Holding Registers FC04 → Input Registers |
are different Modbus tables.
Common Mistake 9: Polling Too Fast
A client hammering multiple servers continuously can create:
- timeouts;
- bus collisions from badly behaved devices;
- unnecessary CPU load;
- slow response for important devices.
Common Mistake 10: Assuming RS-485 Means Modbus
RS-485 is only the electrical layer.
The same Opta RS-485 port can carry:
- Modbus RTU;
- custom binary protocols;
- ASCII protocols;
- vendor-specific serial communication.
Both ends must speak the same protocol.
RS-485 vs Modbus TCP on Opta
| Feature | Modbus RTU | Modbus TCP |
|---|---|---|
| Physical layer | RS-485 | Ethernet |
| Opta variants | RS485 / WiFi | All Opta variants |
| Topology | Multi-drop serial bus | Ethernet network |
| Addressing | Device ID 1-247 | IP + Modbus unit ID |
| CRC | Yes | No RTU CRC; TCP/IP framing instead |
| Typical use | VFDs, meters, field devices | SCADA, PLCs, Ethernet gateways |
When Modbus RTU Is the Better Choice
Use Modbus RTU when the field devices already use:
- RS-485;
- long daisy-chain cable runs;
- simple low-cost serial interfaces;
- legacy drives and meters.
When Modbus TCP Is Better
Use Modbus TCP when:
- Ethernet is already available;
- higher throughput is useful;
- SCADA or servers are IP-based;
- devices are distributed through an Ethernet infrastructure.
Quick Wiring Reference
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
Opta RS485 / WiFi A(-) → RS-485 negative / A side B(+) → RS-485 positive / B side GND → reference ground Termination: external normally at each physical end of bus Mode: half-duplex Server address: 1-247 PLC IDE baud range: 600-115200 bit/s |
Final Thoughts
Modbus RTU on Opta is straightforward once the physical layer and addressing conventions are understood.
The hardware already includes the RS-485 transceiver, so the main installation tasks are:
|
1 2 3 4 5 6 7 8 9 |
wire A(-), B(+) and GND correctly add termination only where required match baud/parity/stop bits assign unique server addresses use the correct Modbus register type verify 0-based vs 1-based addressing |
For Arduino IDE projects, the official:
|
1 2 3 4 5 6 |
ArduinoRS485 + ArduinoModbus |
libraries provide the physical and protocol layers.
For automation engineers, Arduino PLC IDE provides graphical Modbus RTU client/server configuration without manually constructing Modbus frames.
For the complete terminal layout, see our Arduino Opta pinout and I/O guide. For choosing the correct Opta hardware first, see Arduino Opta Lite vs RS485 vs WiFi.