Modbus is one of the most common communication protocols in industrial automation. It is used by PLCs, HMIs, SCADA systems, power meters, drives, temperature controllers, remote I/O modules, sensors, and many other field devices.
The idea behind Modbus is simple: a client asks a device to read or write data from a known address, and the device replies. The protocol defines how the request and response are formatted, but the meaning of each register is defined by the device manufacturer in a register map.
Client and Server
Modbus uses a client-server model. Older documents often use the words master and slave. In modern terminology, the client starts the transaction and the server answers it.
- Client: PLC, SCADA software, HMI, gateway, or test tool that sends requests.
- Server: Field device that owns the registers and responds to requests.
A normal Modbus server does not send data by itself. The client polls the server by asking for specific coils, inputs, or registers.
Modbus RTU
Modbus RTU is the serial version of Modbus. It is commonly used over RS-485 because RS-485 allows multiple devices to share the same pair of wires and works well in electrically noisy industrial environments.
A typical Modbus RTU frame contains a device address, a function code, the request or response data, and a CRC checksum.
Slave Address | Function Code | Data | CRC
Example RTU request:
01 03 00 00 00 02 C4 0B
01is the server address.03means read holding registers.00 00is the starting address.00 02asks for two registers.C4 0Bis the CRC.
Modbus TCP
Modbus TCP carries Modbus messages over Ethernet using TCP/IP. The standard port is
502. Instead of the RTU CRC, Modbus TCP uses an MBAP header before the
function code and data.
MBAP Header | Function Code | Data
The MBAP header includes the transaction ID, protocol ID, length, and unit ID. The unit ID is especially useful when a Modbus TCP gateway forwards requests to Modbus RTU devices behind it.
| Feature | Modbus RTU | Modbus TCP |
|---|---|---|
| Transport | Serial, usually RS-485 | Ethernet TCP/IP |
| Addressing | Slave address, usually 1 to 247 | IP address plus unit ID |
| Error check | CRC in the Modbus frame | Handled by Ethernet and TCP layers |
| Typical use | Field devices, meters, drives, remote I/O | PLCs, HMIs, SCADA, gateways, Ethernet devices |
The Four Modbus Data Areas
Modbus defines four logical data areas. These are often called registers, although technically coils and discrete inputs are single-bit values, not 16-bit registers.
| Data area | Access | Size | Classic address range | Typical meaning |
|---|---|---|---|---|
| Coils | Read and write | 1 bit | 00001 to 09999 |
Digital outputs or command bits |
| Discrete Inputs | Read only | 1 bit | 10001 to 19999 |
Digital input states |
| Input Registers | Read only | 16 bits | 30001 to 39999 |
Measured analog values |
| Holding Registers | Read and write | 16 bits | 40001 to 49999 |
Configuration, setpoints, status words, parameters |
The classic address ranges are human-readable conventions. Inside the Modbus
message, the address is normally zero-based. For example, holding register
40001 is usually sent as address 0, and holding register
40010 is usually sent as address 9.
Coils
Coils are single-bit read/write values. They are often used for digital outputs or commands.
0means off, false, or inactive.1means on, true, or active.
| Function code | Name | Purpose |
|---|---|---|
01 |
Read Coils | Read one or more coil states. |
05 |
Write Single Coil | Write one coil on or off. |
15 |
Write Multiple Coils | Write a group of coil states. |
Discrete Inputs
Discrete inputs are single-bit read-only values. They usually represent physical input states or feedback signals, such as limit switches, fault contacts, door sensors, emergency stop state, or motor running feedback.
Discrete inputs are read with function code 02. They are not written by
the client.
Input Registers
Input registers are 16-bit read-only values. They are commonly used for live measurements: voltage, current, temperature, pressure, flow, speed, frequency, and other process values.
Input registers are read with function code 04. If a value is larger
than 16 bits, the device combines multiple consecutive registers.
Holding Registers
Holding registers are 16-bit values that can usually be read and written. They are the most commonly used Modbus data area because they can hold configuration values, setpoints, control words, status words, counters, and calculated process data.
| Function code | Name | Purpose |
|---|---|---|
03 |
Read Holding Registers | Read one or more holding registers. |
06 |
Write Single Holding Register | Write one 16-bit register. |
16 |
Write Multiple Holding Registers | Write multiple consecutive registers. |
Register Size and Data Types
One Modbus register is always 16 bits, or 2 bytes. Real devices often need larger values, so they store one value across multiple registers.
| Data type | Register count | Size | Example |
|---|---|---|---|
| Boolean | Bit value | 1 bit | Coil or discrete input |
| Unsigned 16-bit integer | 1 | 16 bits | 0 to 65535 |
| Signed 16-bit integer | 1 | 16 bits | -32768 to 32767 |
| 32-bit integer | 2 | 32 bits | Counter, energy total, long value |
| 32-bit float | 2 | 32 bits | Pressure, power, speed, temperature |
| 64-bit value | 4 | 64 bits | Large counter or double precision value |
| String | Multiple | Variable | Device name, serial number, firmware version |
Byte Order and Word Order
Inside one 16-bit register, Modbus sends the high byte first. For example, the
register value 0x1234 is sent as 12 34.
When a value uses two or more registers, word order can vary between manufacturers.
A 32-bit value such as 0x12345678 might be stored as:
40001 = 0x1234
40002 = 0x5678
Or it might be stored with the two 16-bit words swapped:
40001 = 0x5678
40002 = 0x1234
This is why Modbus tools often include options such as word swap, byte swap, big endian, little endian, or float swap. The correct option must come from the device manual or from a known test value.
Scaling
Many Modbus devices store decimal engineering values as integers. A register may
contain 2305, while the real value is 230.5 V because the
scale factor is 0.1.
Raw register value = 2305
Scale factor = 0.1
Engineering value = 230.5 V
A good register map should define the address, function code, data type, unit, scale factor, valid range, and whether the value is read-only or writable.
Addressing Example
Suppose a manual gives the following holding register map.
| Register | Name | Type | Scale |
|---|---|---|---|
40001 |
Voltage | UInt16 | 0.1 V |
40002 |
Current | UInt16 | 0.01 A |
40003 |
Frequency | UInt16 | 0.1 Hz |
40004 |
Power | UInt32 | 1 W |
To read voltage, current, and frequency with function code 03, the
client usually sends start address 0 and quantity 3. To
read power, the client sends start address 3 and quantity
2, because the UInt32 value uses registers 40004 and
40005.
Exception Responses
If a request is invalid, the server returns an exception response. Common exception codes include:
| Exception code | Meaning |
|---|---|
01 |
Illegal Function: the device does not support that function code. |
02 |
Illegal Data Address: the requested address does not exist. |
03 |
Illegal Data Value: the request value is outside the allowed range. |
04 |
Server Device Failure: the device could not complete the request. |
06 |
Server Device Busy: the device is temporarily unable to respond normally. |
Common Problems in Real Projects
- Using address
1when the device expects zero-based address0. - Reading holding registers with function code
04instead of03. - Using the wrong byte order or word order for 32-bit integers and floats.
- Forgetting the scale factor and displaying the raw integer value directly.
- Writing to a read-only register.
- Using the wrong RTU baud rate, parity, stop bits, or server address.
- Swapping RS-485 A and B wires, or missing the 120 Ohm termination at the bus ends.
- Using the wrong unit ID when communicating through a TCP-to-RTU gateway.
- Reading more registers than the device allows in one request.
Conclusion
Modbus is popular because it is simple and practical. The client sends a request, the server answers, and the data is organized into coils, discrete inputs, input registers, and holding registers.
Modbus RTU is used on serial networks, typically RS-485. Modbus TCP is used over Ethernet. In both cases, successful integration depends on reading the register map carefully, choosing the correct function code, handling zero-based addressing, and applying the right data type, byte order, and scale factor.