The Modbus Protocol was originally developed by Modicon (now part of Schneider Electric). Modbus was developed as a communication protocol for Modicon PLC Devices. The original Modbus Protocol specification, published in 1979, describes Serial Communications where data is transmitted one bit at a time. A later update to the standard, called Modbus TCP, describes how to use Modbus in TCP/IP networks.
The rest of this article describes the Modbus protocol is more detail:
The Modbus Protocol supports these data types:
Data Type | Access | Description |
---|---|---|
Coil | Read-write | Single bit outputs. |
Discrete Input | Read-only | Single bit inputs. |
Input Register | Read-only | 16-bit input registers. |
Holding Register | Read-write | 16-bit output registers. |
Modbus is a request-response protocol where:
The structure of a Modbus message is the same for both requests and responses:
Unit Address | Modbus PDU | Error Check |
The exact format of the message depends on the variant of Modbus protocol used:
Modbus ASCII uses a subset of the ASCII character set to send Modbus messages over Serial Communications.
Modbus ASCII messages start with the colon (:) character (ASCII 58). Modbus ASCII messages end with carriage return (ASCII 13) and line feed (ASCII 10) characters. Between the start and end characters only hexadecimal characters 0 to 9 and A to F are allowed.
The structure of a Modbus ASCII message is:
Start | Unit Address | Message | LRC | End |
ASCII 58 | 2 characters | N characters | 2 characters | ASCII 13 + ASCII 10 |
Where:
Modbus RTU uses 8-bit Serial Communications to send Modbus messages.
The structure of a Modbus RTU message is:
Unit Address | Message | CRC |
1 Byte | N Bytes | 2 Bytes |
Where:
Modbus TCP uses a TCP/IP link to send and receive Modbus messages.
The structure of a Modbus TCP message is:
Transaction Id | Protocol | Length | Unit Address | Message |
2 Bytes | 2 Bytes | 2 Bytes | 1 Byte | N Bytes |
Where:
Note: Real Modbus TCP devices use the Unit Address field in different ways:
Modbus RTU over Modbus TCP is rarely used. It is a non-standard variant of Modbus TCP that includes the Modbus RTU CRC at the end of the message.
The structure of a Modbus RTU over Modbus TCP message is:
Transaction Id | Protocol | Length | Unit Address | Message | CRC |
2 Bytes | 2 Bytes | 2 Bytes | 1 Byte | N Bytes | 2 Bytes |
Where:
The Modbus Protocol supports these PDU:
Modbus Read Coils, function code 01, reads between 1 and 2000 output coils (bits) from the PLC.
The request PDU consists of 5 bytes:
Offset | Length | Description | Values |
---|---|---|---|
0 | Byte | Function Code | 01 |
2 | Word | First coil address | 0000h - FFFFh |
4 | Word | Coil count | 0001 - 07D0h |
The normal response varies in length from 3 bytes up to 252 bytes depending on the number of coils requested:
Offset | Length | Description | Values |
---|---|---|---|
0 | Byte | Function Code | 01 |
1 | Byte | Byte Count | (CoilCount + 7) / 8 |
2 | N Bytes | Coil data | ... |
Note: The total number of bytes returned is 2 + (CoilCount + 7) / 8, where CoilCount is the number of coils requested. For example:
The largest request possible is for 2000 coils, which will return 252 bytes.
If the PLC detects an error in the request, for example an address that is not available, an error response will be sent:
Offset | Length | Description | Values |
---|---|---|---|
0 | Byte | Function Code | 81h |
1 | Byte | Exception Code | See Exception Codes |
Example: Read 12 coils starting at 00033 from a PLC at address 2. Response with coils 00040 and 00042 set and all others clear :
Request | Response | |
---|---|---|
Modbus ASCII | 3A 30 32 30 31 30 30 32 30 30 30 30 43 44 31 0D 0A | 3A 30 32 30 31 30 32 38 30 30 32 37 39 0D 0A |
Modbus RTU | 02 01 00 20 00 0C 3D F6 | 02 01 02 80 02 1D FD |
Modbus TCP | 00 05 00 00 00 06 02 01 00 20 00 0C | 00 05 00 00 00 05 02 01 02 80 02 |
Note: The PDU part of each request and response is shown in Blue.
Modbus Read Discrete Inputs, function code 02, reads between 1 and 2000 inputs from the PLC.
The request PDU consists of 5 bytes:
Offset | Length | Description | Values |
---|---|---|---|
0 | Byte | Function Code | 02 |
2 | Word | First input address | 0000h - FFFFh |
4 | Word | Input count | 0001 - 07D0h |
The normal response varies in length from 3 bytes up to 252 bytes depending on the number of inputs requested:
Offset | Length | Description | Values |
---|---|---|---|
0 | Byte | Function Code | 02 |
1 | Byte | Byte Count | (InputCount + 7) / 8 |
2 | N Bytes | Input data | ... |
Note: The total number of bytes returned is 2 + (InputCount + 7) / 8. InputCount is the number of inputs requested. For example a request for 1 input, will return 3 bytes. A request for 8 inputs will also return 3 bytes. A request for 9 inputs will return 4 bytes. The largest request possible is for 2000 inputs, which will return 252 bytes.
If the PLC detects an error in the request, for example an address that is not available, an error response will be sent:
Offset | Length | Description | Values |
---|---|---|---|
0 | Byte | Function Code | 82h |
1 | Byte | Exception Code | See Exception Codes |
Example: Read 16 inputs starting at 10501 from a PLC at address 1. Response with inputs 10501 and 10503 set and all others clear :
Request | Response | |
---|---|---|
Modbus ASCII | 3A 30 31 30 32 30 31 46 34 30 30 32 30 45 38 0D 0A | 3A 30 31 30 32 30 32 30 35 30 30 46 36 0D 0A |
Modbus RTU | 01 02 01 F4 00 20 39 DC | 01 02 02 05 00 BA E8 |
Modbus TCP | 00 0A 00 00 00 06 01 02 01 F4 00 20 | 00 0A 00 00 00 05 01 02 02 05 00 |
Note: The PDU part of each request and response is shown in Blue.
Modbus Read Holding Registers, function code 03, reads between 1 and 125 holding registers from the PLC.
The request PDU consists of 5 bytes:
Offset | Length | Description | Values |
---|---|---|---|
0 | Byte | Function Code | 03 |
2 | Word | First input address | 0000h - FFFFh |
4 | Word | Register count | 0001 - 007Dh |
The normal response varies in length from 4 bytes up to 252 bytes depending on the number of holding registers requested:
Offset | Length | Description | Values |
---|---|---|---|
0 | Byte | Function Code | 03 |
1 | Byte | Byte Count | RegisterCount * 2 |
2 | N Bytes | Register data | ... |
Note: The total number of bytes returned is 2 + 2 * RegisterCount, where RegisterCount is the number of holding registers requested. For example a request for 1 holding register, will return 4 bytes. A request for 2 holding registers will return 6 bytes. A request for 125 holding registers will return 252 bytes.
If the PLC detects an error in the request, for example an address that is not available, an error response will be sent:
Offset | Length | Description | Values |
---|---|---|---|
0 | Byte | Function Code | 83h |
1 | Byte | Exception Code | See Exception Codes |
Example: Read 2 holding registers starting at address 40601 from a PLC at address 1. Response returns register 40601 value 1000, and register 40602 value 5000:
Request | Response | |
---|---|---|
Modbus ASCII | 3A 30 31 30 33 30 32 35 38 30 30 30 32 41 30 0D 0A | 3A 30 31 30 33 30 34 30 33 45 38 31 33 38 38 37 32 0D 0A |
Modbus RTU | 01 03 02 58 00 02 44 60 | 01 03 04 03 E8 13 88 77 15 |
Modbus TCP | 00 0F 00 00 00 06 01 03 02 58 00 02 | 00 0F 00 00 00 07 01 03 04 03 E8 13 88 |
Note: The PDU part of each request and response is shown in Blue.
Modbus Read Input Registers, function code 04, reads between 1 and 125 input registers from the PLC.
The request PDU consists of 5 bytes:
Offset | Length | Description | Values |
---|---|---|---|
0 | Byte | Function Code | 04 |
2 | Word | First input address | 0000h - FFFFh |
4 | Word | Register count | 0001 - 007Dh |
The normal response varies in length from 4 bytes up to 252 bytes depending on the number of input registers requested:
Offset | Length | Description | Values |
---|---|---|---|
0 | Byte | Function Code | 04 |
1 | Byte | Byte Count | RegisterCount * 2 |
2 | N Bytes | Register data | ... |
Note: The total number of bytes returned is 2 + 2 * RegisterCount, where RegisterCount is the number of input registers requested. For example a request for 1 input register, will return 4 bytes. A request for 2 input registers will return 6 bytes. A request for 125 input registers will return 252 bytes.
If the PLC detects an error in the request, for example an address that is not available, an error response will be sent:
Offset | Length | Description | Values |
---|---|---|---|
0 | Byte | Function Code | 84h |
1 | Byte | Exception Code | See Exception Codes |
Example: Read 2 input registers starting at address 30201 from a PLC at address 1. Response returns register 30201 value 10000, and register 30202 value 50000:
Request | Response | |
---|---|---|
Modbus ASCII | 3A 30 31 30 34 30 30 43 38 30 30 30 32 33 31 0D 0A | 3A 30 31 30 34 30 34 32 37 31 30 43 33 35 30 41 44 0D 0A |
Modbus RTU | 01 04 00 C8 00 02 F0 35 | 01 04 04 27 10 C3 50 A0 39 |
Modbus TCP | 00 14 00 00 00 06 01 04 00 C8 00 02 | 00 14 00 00 00 07 01 04 04 27 10 C3 50 |
Note: The PDU part of each request and response is shown in Blue.
Modbus Write Single Coil, function code 05, writes a single coil to the PLC.
The request PDU consists of 5 bytes:
Offset | Length | Description | Values |
---|---|---|---|
0 | Byte | Function Code | 05 |
2 | Word | First coil address | 0000h - FFFFh |
4 | Word | Coil value | 0x0000 or 0xFF00 |
The normal response is the request reflected back:
Offset | Length | Description | Values |
---|---|---|---|
0 | Byte | Function Code | 05 |
2 | Word | First coil address | 0000h - FFFFh |
4 | Word | Coil value | 0x0000 or 0xFF00 |
If the PLC detects an error, for example an address that is not available, an error response will be sent:
Offset | Length | Description | Values |
---|---|---|---|
0 | Byte | Function Code | 85h |
1 | Byte | Exception Code | See Exception Codes |
Example: Set coil 00101 in device with address 1 to 1.
Request | Response | |
---|---|---|
Modbus ASCII | 3A 30 31 30 35 30 30 36 34 46 46 30 30 39 37 0D 0A | 3A 30 31 30 35 30 30 36 34 46 46 30 30 39 37 0D 0A |
Modbus RTU | 01 05 00 64 FF 00 CD E5 | 01 05 00 64 FF 00 CD E5 |
Modbus TCP | 00 19 00 00 00 06 01 05 00 64 FF 00 | 00 19 00 00 00 06 01 05 00 64 FF 00 |
Note: The PDU part of each request and response is shown in Blue.
Modbus Write Single Register, function code 06, writes a single register to the PLC.
The request PDU consists of 5 bytes:
Offset | Length | Description | Values |
---|---|---|---|
0 | Byte | Function Code | 06 |
2 | Word | First register address | 0000h - FFFFh |
4 | Word | Register value | 0000h - FFFFh |
The normal response is the request reflected back:
Offset | Length | Description | Values |
---|---|---|---|
0 | Byte | Function Code | 06 |
2 | Word | First register address | 0000h - FFFFh |
4 | Word | Register value | 0000h - FFFFh |
If the PLC detects an error in the request, for example an address that is not available, an error response will be sent:
Offset | Length | Description | Values |
---|---|---|---|
0 | Byte | Function Code | 86h |
1 | Byte | Exception Code | See Exception Codes |
Example: Set Holding Register 40101 in device with address 1 to 15000.
Request | Response | |
---|---|---|
Modbus ASCII | 3A 30 31 30 36 30 30 36 34 33 41 39 38 43 33 0D 0A | 3A 30 31 30 36 30 30 36 34 33 41 39 38 43 33 0D 0A |
Modbus RTU | 01 06 00 64 3A 98 98 DB | 01 06 00 64 3A 98 98 DB |
Modbus TCP | 00 1E 00 00 00 06 01 06 00 64 3A 98 | 00 1E 00 00 00 06 01 06 00 64 3A 98 |
Note: The PDU part of each request and response is shown in Blue.
Modbus Write Multiple Registers, function code 16, writes between 1 and 123 registers to the PLC.
The request PDU consists of between 8 and 252 bytes:
Offset | Length | Description | Values |
---|---|---|---|
0 | Byte | Function Code | 10h |
2 | Word | First register address | 0000h - FFFFh |
4 | Word | Register Count | 0000h - 007Bh |
5 | Byte | Byte Count | 0000h - 007Bh |
6 | N Words | Register values | ... |
The normal response consists of 5 bytes:
Offset | Length | Description | Values |
---|---|---|---|
0 | Byte | Function Code | 10h |
2 | Word | First register address | 0000h - FFFFh |
4 | Word | Register Count | 0000h - 007Bh |
If the PLC detects an error in the request, for example an address that is not available, an error response will be sent:
Offset | Length | Description | Values |
---|---|---|---|
0 | Byte | Function Code | 90h |
1 | Byte | Exception Code | See Exception Codes |
Example: In the PLC at address 28, set register 40101 to 1000 and register 40102 to 2000.
Request | Response | |
---|---|---|
Modbus ASCII | 3A 31 43 31 30 30 30 36 34 30 30 30 32 30 34 30 33 45 38 30 37 44 38 41 30 0D 0A | 3A 31 43 31 30 30 30 36 34 30 30 30 32 36 45 0D 0A |
Modbus RTU | 1C 10 00 64 00 02 04 03 E8 07 D8 19 02 | 1C 10 00 64 00 02 03 9A |
Modbus TCP | 00 23 00 00 00 0B 1C 10 00 64 00 02 04 03 E8 07 D8 | 00 23 00 00 00 06 1C 10 00 64 00 02 |
Note: The PDU part of each request and response is shown in Blue.
An exception code is a single byte providing an explanation of an error:
Code | Description |
---|---|
01h | Illegal function |
02h | Illegal data address |
03h | Illegal data value |
04h | Slave device failure |
To learn how Modbus data addresses are presented in human readable form.
To learn about Modbus Register Block Tags.
For an overview of the Modbus Driver.
For the meaning of terms used in Fernhill SCADA.