Complete Modbus Guide
Introduction
Modbus is the world's most widely used industrial communication protocol. Created in 1979, it is used in millions of PLCs, drives, controllers, meters, and industrial sensors. Eziwan natively supports Modbus RTU (over RS-485) and Modbus TCP (over Ethernet).
Modbus RTU over RS-485
RS-485 Wiring: A Complete Guide
RS-485 is a two-wire differential interface (A and B). The voltage difference between A and B encodes the signal, giving it excellent immunity to electromagnetic interference in industrial environments.
⚠️ In-line topology (A↔A, B↔B, common GND). 120 Ω terminating resistors only at both ends of the bus—already integrated on the Eziwan side; must be placed on the last slave. Never place a resistor in the middle of the line.
Eziwan RS-485 Terminal Connection Chart:
| Eziwan Terminal | RS-485 Signal | Recommended Cable Color |
|---|---|---|
| A (or D+) | Differential positive | White or red |
| B (or D-) | Differential negative | Blue or black |
| GND | Reference ground | Green or gray |
RS-485 Communication Settings
The settings must be identical on the gateway and all slaves:
| Parameter | Common Values | Eziwan Default |
|---|---|---|
| Speed (baud rate) | 1200, 2400, 4800, 9600, 19200, 38400, 57600, 115200 | 9600 |
| Parity | N (none), E (even), O (odd) | N |
| Data bits | 7, 8 | 8 |
| Stop bits | 1, 2 | 1 |
| Inter-message delay | 3.5 character times (Modbus standard) | Auto |
Most Common Standard Configuration: 9600 8N1 (9,600 baud, 8 data bits, no parity, 1 stop bit)
Maximum Distance and Number of Slaves
| Baud rate | Maximum distance | Max. slaves (electrical) |
|---|---|---|
| 9,600 bps | 1,200 m | 32 (unit loads) |
| 19,200 bps | 800 m | 32 |
| 57,600 bps | 200 m | 32 |
| 115,200 bps | 50 m | 32 |
To exceed 32 slaves or 1,200 m, use an RS-485 repeater.
Modbus TCP
Ethernet Connection
Modbus TCP encapsulates the Modbus protocol in TCP/IP frames. The connection is made directly via an RJ45 Ethernet port.
| Parameter | Value |
|---|---|
| TCP Port | 502 (standard), sometimes 503 or another port depending on the manufacturer |
| Unit ID | Slave address (1 to 247), or 255 for direct access |
| Recommended timeout | 500 ms to 2000 ms depending on the network |
| TCP keep-alive | Recommended for long-duration connections |
Network Configuration
The Eziwan gateway must be able to connect to the Modbus TCP controller via the Ethernet network. Check the following:
- The gateway and the PLC are on the same subnet (or there is a router between them)
- There is no firewall blocking TCP port 502 between the gateway and the PLC
- The Modbus TCP PLC is configured to accept connections (PUT/GET enabled on Siemens)
The Four Types of Modbus Registers
The Modbus specification defines four distinct data spaces:
| Type | Modbus Code | Addresses | Master Access | Size | Description |
|---|---|---|---|---|---|
| Coils | 0x (1x) | 00001–09999 | Read/Write | 1 bit | Digital outputs (relays, coils) |
| Discrete Inputs | 1x (2x) | 10001–19999 | Read-only | 1 bit | Digital inputs (digital sensors) |
| Input Registers | 3x | 30001–39999 | Read-only | 16 bits | Measured values (analog sensors) |
| Holding Registers | 4x | 40001–49999 | Read/Write | 16 bits | Parameters and setpoints |
Important Note: Modbus addresses start at 1 in "functional" notation (40001 to 49999), but Modbus functions use 0-based addresses (the FC03 request for register 40001 uses the address 0x0000). Eziwan supports both notations.
Standard Modbus Functions
| Function Code | Name | Target Registers |
|---|---|---|
| FC01 | Read Coils | Coils (0x) |
| FC02 | Read Discrete Inputs | Discrete Inputs (1x) |
| FC03 | Read Holding Registers | Holding Registers (4x) |
| FC04 | Read Input Registers | Input Registers (3x) |
| FC05 | Write Single Coil | Coils (0x) |
| FC06 | Write Single Register | Holding Registers (4x) |
| FC15 | Write Multiple Coils | Coils (0x) |
| FC16 | Write Multiple Registers | Holding Registers (4x) |
Configuring Mapping in Eziwan
JSON Configuration Interface
The Modbus mapping defines how the PLC's registers are collected and published:
{
"device": {
"name": "Compresseur_Atlas_GA75",
"description": "Compresseur d'air atelier principal",
"protocol": "modbus_rtu",
"connection": {
"port": "/dev/ttyS0",
"baudrate": 9600,
"parity": "N",
"databits": 8,
"stopbits": 1,
"slave_id": 1
}
},
"polling": {
"interval_ms": 5000,
"timeout_ms": 500,
"retry_count": 3,
"retry_delay_ms": 200
},
"registers": [
{
"name": "Pression_Service",
"address": "3x0001",
"count": 1,
"type": "uint16",
"scale_factor": 0.1,
"unit": "bar",
"description": "Pression de service sortie compresseur",
"alarm_low": 6.0,
"alarm_high": 12.0,
"publish_on_change": true
},
{
"name": "Temperature_Huile",
"address": "3x0002",
"count": 1,
"type": "uint16",
"scale_factor": 0.1,
"unit": "°C",
"alarm_high": 95.0
},
{
"name": "Heures_Fonctionnement",
"address": "4x0010",
"count": 2,
"type": "uint32_ab",
"unit": "h",
"description": "Compteur d'heures moteur"
},
{
"name": "Debit_Air",
"address": "3x0005",
"count": 2,
"type": "float32_abcd",
"unit": "m³/h"
},
{
"name": "Alarme_Active",
"address": "1x0001",
"count": 1,
"type": "bool",
"description": "Au moins une alarme active"
},
{
"name": "Code_Alarme",
"address": "4x0020",
"count": 1,
"type": "uint16",
"description": "Code alarme (voir tableau constructeur)"
}
]
}
Complete example: 10 temperature registers, 5 status registers
Here is a typical mapping for a production line with 10 temperature points and 5 machine states:
{
"registers": [
{ "name": "Temp_Zone1", "address": "4x0001", "count": 2, "type": "float32_abcd", "unit": "°C" },
{ "name": "Temp_Zone2", "address": "4x0003", "count": 2, "type": "float32_abcd", "unit": "°C" },
{ "name": "Temp_Zone3", "address": "4x0005", "count": 2, "type": "float32_abcd", "unit": "°C" },
{ "name": "Temp_Zone4", "address": "4x0007", "count": 2, "type": "float32_abcd", "unit": "°C" },
{ "name": "Temp_Zone5", "address": "4x0009", "count": 2, "type": "float32_abcd", "unit": "°C" },
{ "name": "Temp_Zone6", "address": "4x0011", "count": 2, "type": "float32_abcd", "unit": "°C" },
{ "name": "Temp_Zone7", "address": "4x0013", "count": 2, "type": "float32_abcd", "unit": "°C" },
{ "name": "Temp_Zone8", "address": "4x0015", "count": 2, "type": "float32_abcd", "unit": "°C" },
{ "name": "Temp_Zone9", "address": "4x0017", "count": 2, "type": "float32_abcd", "unit": "°C" },
{ "name": "Temp_Zone10", "address": "4x0019", "count": 2, "type": "float32_abcd", "unit": "°C" },
{ "name": "Etat_EnMarche", "address": "1x0001", "count": 1, "type": "bool" },
{ "name": "Etat_EnChauffe", "address": "1x0002", "count": 1, "type": "bool" },
{ "name": "Etat_Production", "address": "1x0003", "count": 1, "type": "bool" },
{ "name": "Etat_Defaut", "address": "1x0004", "count": 1, "type": "bool" },
{ "name": "Etat_ArretUrgence", "address": "1x0005", "count": 1, "type": "bool" }
]
}
Data Types Supported by Eziwan
| JSON Type | Description | Size (registers) | Example Value |
|---|---|---|---|
uint16 | 16-bit unsigned integer | 1 | 0 to 65535 |
int16 | 16-bit signed integer | 1 | -32768 to 32767 |
uint32_ab | 32-bit big-endian integer | 2 | 0 to 4,294,967,295 |
uint32_ba | 32-bit integer, little-endian | 2 | — |
float32_abcd | IEEE 754 floating-point, ABCD | 2 | 23.456 |
float32_cdab | IEEE 754 floating-point, CDAB (Schneider) | 2 | — |
float32_badc | IEEE 754 floating-point, BADC | 2 | — |
float64_abcdefgh | Double precision | 4 | — |
bool | Boolean (Coil or Discrete Input) | 1 | true/false |
Debugging Modbus
Modbus Poll Tool (Windows)
Modbus Poll is the go-to tool for testing and debugging Modbus connections:
- Download from modbustools.com
- Free trial version (30 days)
- Configuration: Connection → Connect → Modbus TCP (IP + Port 502) or Serial (COM + baud rate)
- Define the registers to read: Setup → Read/Write Definition
Modbus Poll - Read Configuration
─────────────────────────────────────
Slave ID: 1
Function: 03 Read Holding Registers
Address: 0 (= registre 40001)
Quantity: 10
Scan Rate: 1000 ms
Eziwan Logs for Modbus Debugging
In the Eziwan portal → Gateway → Logs → Modbus:
2026-06-04 14:32:00.123 [[INFO] Modbus RTU: FC03 request, slave=1, address=0, count=10
2026-06-04 14:32:00.145 [[INFO] Modbus RTU: Response received in 22 ms, 10 registers
2026-06-04 14:32:00.145 [DATA] Reg[0001]=0x4529 (23.4°C FLOAT32), Reg[0003]=0x42C6 (99.2 rpm)
2026-06-04 14:32:01.123 [[WARN] Modbus RTU: timeout after 500 ms, slave=2 (attempt 1/3)
2026-06-04 14:32:01.623 [[WARN] Modbus RTU: timeout after 500 ms, slave=2 (attempt 2/3)
2026-06-04 14:32:02.123 [[ERROR] Modbus RTU: Slave 2 unreachable after 3 attempts
Enable the DEBUG log level to obtain the raw hexadecimal frames:
2026-06-04 14:32:00.100 [DEBUG] TX: 01 03 00 00 00 0A C5 CD
│ │ ├──────┤ ├──────┤ └── CRC16
│ │ addr=0 count=10
│ FC03
slave=1
2026-06-04 14:32:00.122 [DEBUG] RX: 01 03 14 45 29 ... (20 octets + 2 CRC)
Troubleshooting
Problem 1: Modbus RTU Timeout
Symptoms: timeout messages, no response from the slave.
Causes and Solutions:
| Cause | Diagnosis | Solution |
|---|---|---|
| Incorrect slave ID | Manually test slave IDs 1 through 10 | Check equipment documentation |
| Incorrect baud rate | — | Test 9600, 19200, and 57600 one at a time |
| A/B wiring reversed | Measure voltage between A and B: +1.5V to 5V = correct | Reverse the A and B wires |
| Missing termination resistor | Measure R between A and B with power off: ~60Ω if 2 resistors | Add a 120Ω resistor at the end of the bus |
| Cable too long | Calculate total length | Reduce baud rate or add a repeater |
| RS-485 power supply missing | Measure slave power supply voltage | Check slave 24VDC |
Problem 2: CRC Errors
Symptoms: CRC error in the Eziwan logs; incorrect data.
Causes:
- Electromagnetic interference on the RS-485 cable (route the cable away from power cables)
- Unshielded cable (use a shielded cable; connect the shield to ground on the gateway side only)
- Poor cable quality (use RS-485-specified cable, 120Ω impedance)
- Transmission speed too high for the cable length (reduce the baud rate)
Problem 3: Slave ID Conflict
Symptoms: One slave responds instead of another; data is mixed up.
Cause: Two slaves have the same slave ID on the same RS-485 bus.
Solution:
- Disconnect all slaves from the bus except one
- Scan the bus using Modbus Poll to find that slave's ID
- Change the ID if there is a conflict (via the device's configuration interface)
- Reconnect the slaves one by one
Problem 4: Unreadable Registry (Exception Code 02)
Symptom: Illegal Data Address (Exception Code 02).
Cause: The requested address does not exist in the PLC or is not accessible via Modbus.
Solutions:
- Check the manufacturer's documentation for supported addresses
- Some devices expose only a limited range of registers
- For Siemens devices, verify that the memory area is within the data block exposed via PUT/GET
Rapid Diagnosis Checklist
□ 24 VDC power supply voltage present at the Eziwan power terminals
□ The Eziwan RS-485 LED flashes during transmission (TX)
□ A/B wiring: A = positive, B = negative (non-inverted)
□ 120Ω resistors at both ends of the bus only
□ Correct slave ID (check the device display or documentation)
□ Same baud rate on the gateway and the device
□ Identical parity on the gateway and device (N, E, or O)
□ Correct IP address and port 502 for Modbus TCP
□ PUT/GET enabled on S7-1500/1200 if necessary
□ No firewall blocking port 502 on the OT local network
Frequently Asked Questions
Modbus RTU or Modbus TCP: Which One Should You Use?
RTU if your devices are connected via an RS-485 serial bus (sensors, meters, older PLCs); TCP if the devices are already connected via Ethernet. The Eziwan gateway supports both protocols simultaneously and acts as an RTU ↔ TCP bridge.
Which Modbus functions are used for monitoring?
Primarily FC03 (reading holding registers) and FC04 (input registers) for data collection; FC06/FC16 for writing setpoints. Exception codes (02 illegal address, 0B target unreachable) guide troubleshooting.
How do you read a 32-bit value or a floating-point number?
On two consecutive registers, specifying the word order (big/little endian, word swap) in the gateway mapping. A single device may use a mix of conventions: check the manufacturer's documentation register by register.
Can Modbus be transmitted over the Internet?
Never in the clear: the protocol uses neither authentication nor encryption. The gateway confines Modbus traffic to the local network and transmits the data to the cloud through an encrypted VPN tunnel.
Related Resources
- Modbus to the cloud — the data collection solution
- Modbus RTU to the cloud — for serial buses
- Modbus TCP to the cloud — for Ethernet networks
- Modbus RTU vs. TCP — a detailed comparison
- RS485 / Modbus RTU — detailed information on wiring and polling