Modbus Protocol Specification
Introduction
- Modbus is a software layer bus communication protocol. He does not depend on the hardware bus, Modbus protocol supports a variety of electrical interfaces, including RS232, RS-422, RS485, TCP/IP and so on.
- Modbus transmission mode is also divided into several versions, the common ones are Modbus ASCII, Modbus RTU, Modbus TCP and so on.
- Modbus protocol can choose RTU or ASCII mode when using serial port transmission. Modbus RTU is a compact, hexadecimal representation of data, and Modbus ASCII is a representation that uses Ascii code to represent the data and sends each 8Bit byte as two ASCII characters. subsequent commands/data in RTU format RTU format subsequent commands/data have a checksum with cyclic redundancy check, while the ASCII format uses a checksum with longitudinal redundancy check.
- The Modbus protocol uses Ethernet transmission with the option of TCP mode, which does not use checksums.
- Modbus is a master-multi-slave communication protocol, a request/answer protocol in which only one device in Modbus communication can send a request. The other slave devices receive the data sent by the host to respond. That is to say, the host can only send a request to a slave in the same time, can not Modbus synchronized communication, the bus each time there is only one data transmission, that is, the host sends, the slave to answer, the host does not send, there is no data communication on the bus.
Description
The MODBUS protocol defines a simple protocol data unit (PDU) independent of the underlying communication layers. The mapping of MODBUS protocol on specific buses or network can introduce some additional fields on the application data unit (ADU).
The above figure represents the relationship between ADUs and PDUs. Taking the Modbus RTU protocol as an example, a complete application data unit (ADU) is shown below:
<------- ADU --------> 01 05 00 00 FF 00 DD FA <---- PDU ---->
Frame structure = Device address (1 byte) + function code (1 byte) + data (N bytes) + Checksum (2 bytes).
01: indicates device address 05: function code, indicates single coil 00 00 FF 00: request data, 00 00 indicates the coil address, and FF 00 indicates value DD FF: indicates CRC checksum
This frame of data represents a set one to coil 1 of the 01 device. the PDU consists of function codes and data. The Modbus protocol is described below, describing only the protocol data unit (PDU).
A complete data operation is shown in the figure below, the host (client) sends a data request, the slave (server) performs the operation and returns the response data, and if there is an error, an exception code is returned, and the host reads whether the operation is normal by receiving the response data.
Taking the above request of 05 00 00 FF 00 as an example, it returns 05 00 00 FF 00 if the response is normal and 85 03 if the illegal data is abnormal. this is only the protocol data unit (PDU).
A frame of Modbus RTU application data unit (ADU) is as follows.
Request data: 01 05 00 00 FF 00 8C 3A Normal response: 01 05 00 00 FF 00 8C 3A Exception response: 01 85 03 02 91
Normal response: Response function code = Request function code
Exception response: Response function code = Exception function code = Request function code + 0x80
Exception code is a single byte value for indicating the error types.
Common abnormal code in Modbus protocol:
Exception Code | Name | Description |
---|---|---|
0x01 | illicit function | do not support the requested function code |
0x02 | illicit data address | Error in the requested data address |
0x03 | illicit data value | The requested data value or operation could not be performed |
0x04 | Server error | Server device error |
0x05 | Response | Request received and being processed |
0x06 | Device Busy | The device is currently busy and cannot perform the requested operation |
The following is the Modbus server-side transaction status chart, Modbus has been waiting to receive data, and it receives data after identifying the function code.
If it is abnormal, it returns 01; and if it is normal, it continues to check the data address. If the data address is abnormal, it returns 02; and if it is normal, it will judge the value; If the value is abnormal, it returns 04, 05 or 06; If it is normal, it returns response and wait for the next data.
Modbus Data Types
The Modbus protocol respectively specifies four memory areas, with 0x, 1x, 3x, and 4x representing the four address types.
Address Types | Address Range | Data Type | Read/Write | Function Code |
---|---|---|---|---|
Coils | 0x0000~0xFFFF | Bit,1 bit | Read/Write Boolean | 01H,05H, 0FH |
Discrete Inputs | 1x0000~1xFFFF | Bit, 1 bit | Read-only Boolean | 02H |
Input Registers | 3x0000~3xFFFF | Bit, 16 bit | Read-only Boolean | 04H |
Holding Registers | 4x0000~4xFFFF | Bit, 16 bit | Read/Write Boolean | 03H,06H, 10H |
0x: coil (D0) address, 1x: contact point (DI) address, 3x: the input register (AI) address, 4x: the output register (AO) address.
Different address types of data can be accessed through different Modbus function codes.
Modbus Function Code
Modbus protocol specifies a variety of function codes, different function codes can realize different operations, read and write to different data types. The commonly used function codes are shown in the table below.
Function Code | Description |
---|---|
01 | Read Coils |
02 | Read Discrete Inputs |
03 | Read Holding Registers |
04 | Read Input Registers |
05 | Write Single Coil |
06 | Write Single Register |
0F | Write Multiple Coils |
10 | Write Multiple Holding Registers |
0x01 Read Coil
This function code is used to read from 1 to 2000 contiguous status of coils in a remote device. The Request PDU specifies the starting address, i.e. the address of the first coil specified, and the number of coils. In the PDU Coils are addressed starting at zero. Therefore coils numbered 1-16 are addressed as 0-15.
- Request:
Function Code | 1 Byte | 0x01 |
---|---|---|
Initial Address | 2 Bytes | 0x0000 ~ 0xFFFF |
Quantity of Coils | 2 Bytes | 1 ~ 2000(0x7D0) |
- Response:
The coils in the response message are packed as one coil per bit of the data field. Status is indicated as 1= ON and 0= OFF.
The LSB of the first data byte contains the output addressed in the query. The other coils follow toward the high order end of this byte, and from low order
to high order in subsequent bytes.
If the returned output quantity is not a multiple of eight, the remaining bits in the final data byte will be padded with zeros (toward the high order end of the byte). The Byte Count field specifies the quantity of complete bytes of data.
Function Code | 1 Byte | 0x01 |
---|---|---|
Byte Count | 1 Byte | N* |
Coil Status | N Bytes | n = N or N+1 |
(*) N = Quantity of Input / 8, if the remainder is different of 0, then N = N+1
- Abnormal.
Error Code | 1 Byte | 0x81 |
---|---|---|
Exception Code | 1 Byte | 01, 02, 03, 04 |
- For example:
Here is an example of a request to read discrete outputs 20–38:
Request: 01 01 00 13 00 13 8C 02
01: Slave address 01: Function code 01 (read coil) 00 13: Data address of the first coil to be read. (00 13 HEX = 19, +1 offset = coil 20) 00 13: Quantity of requested coils (00 13 HEX = 19, coil 20 - 38) 8C 02: CRC (cyclic redundancy check)
Response: 01 01 03 CD 6B 05 42 82
01: Slave address 01: Function code 01 (Read coil) 03: Byte count (19 coil = 2 bytes + 3 bits + 5 idle bits = 3 bytes) CD: coil 27 - 20 (1100 1101) 6B: coil 35 - 28 (0110 1011) 05: coil 38 - 36 (0000 0101) 42 82: CRC (cyclic redundancy check)
Note: The five remaining bits (toward the high order end) are zero filled.
0x02 Read Discrete Input States
This function code is used to read from 1 to 2000 contiguous status of discrete inputs in a remote device. The Request PDU specifies the starting address, i.e. the address of the first input specified, and the number of inputs. In the PDU Discrete Inputs are addressed starting at zero. Therefore Discrete inputs numbered 1-16 are addressed as 0-15.
- Request
Function Code | 1 Byte | 0x02 |
---|---|---|
Starting Address | 2 Bytes | 0x0000 ~ 0xFFFF |
Quantity of Inputs | 2 Bytes | 1~2000(0x7D0) |
The discrete inputs in the response message are packed as one input per bit of the data field. Status is indicated as 1= ON; 0= OFF.
The LSB of the first data byte contains the input addressed in the query. The other inputs follow toward the high order end of this byte, and from low order to high order in subsequent bytes.
If the returned input quantity is not a multiple of eight, the remaining bits in the final data byte will be padded with zeros (toward the high order end of the byte). The Byte Count field specifies the quantity of complete bytes of data.
- Response:
Function Code | 1 Byte | 0x02 |
---|---|---|
Byte Count | 1 Byte | N* |
Input Status | N Bytes | n = N or N+1 |
(*) N = Quantity of Inputs / 8, if the remainder is different of 0, then N = N+1
- Exception code
Error Code | 1 Byte | 0x82 |
---|---|---|
Exception code | 1 Byte | 01, 02, 03, 04 |
Example:
Here is an example of a request to read discrete inputs 197 – 218:
Request: 01 02 00 C4 00 16 B8 39
01: Slave address 02: Function code 02 (read coil) 00 C4: Data address of the first coil to be read. (00 C4 HEX = 196, +1 offset = input 197) 00 16: Quantity of requested coils (00 16 HEX = 22, input 197 to 218) B8 39: CRC (cyclic redundancy check)
Response: 01 02 03 AC DB 35 22 88
01: Slave address 02: Function code 01 (read coil) 03: Byte count (22 input = 2 bytes + 6 bits + 2 idle bits = 3 bytes) CD: Discrete input 204 - 197(1010 1100) 6B: Discrete input 212 - 205(0110 1011) 05: Discrete input 218 - 213(0011 0101) 22 88: CRC (cyclic redundancy check)
Note: The two remaining bits (toward the high order end) are zero filled.
0x03 Read Holding Register
This function code reads the contents of the Holding Register Contiguous Block, and the request data describes the starting register address and the number of registers.
Registers are addressed from zero. Therefore, registers numbered 1-16 are addressed 0-15.
- Request
Function Code | 1 Byte | 0x03 |
---|---|---|
Initial Address | 2 Bytes | 0x0000 ~ 0xFFFF |
Quantity of Coils | 2 Bytes | 1~125(0x7D) |
The register data in the response message is packaged as two-byte values per register. For each register, the first byte contains the high order bit and the second byte contains the low order bit.
- Response:
Function Code | 1 Byte | 0x03 |
---|---|---|
Byte Count | 1 Byte | 2×N* |
Register Value | N×2 Bytes |
(*) N = Quantity of Registers
- Exception code
Error Code | 1 Byte | 0x83 |
---|---|---|
Exception code | 1 Byte | 01, 02, 03, 04 |
Example:
This command requests reading registers 108 through 110. Each register contains 2 words, 16 bits.
Request: 01 03 00 6B 00 03 74 17
01: Slave address 03: Function code 03 (Read multiple holding registers) 00 6B: Request the data address of the first register (006B HEX = 107, +1 offset = register 108) 00 03: Requested register numbers (Read three registers from 108 to 110) 74 17: CRC (cyclic redundancy check)
Response: 01 03 06 02 2B 00 00 00 64 05 7A
01: Slave address 03: Function code 03 (Read multiple holding registers) 06: Byte count (3 register x 2 bytes of each register = 6 bytes) 02 2B: Register 108 content (Hi Lo) 00 00: Register 109 content (Hi Lo) 00 64: Register 110 content (Hi Lo) 05 7A: CRC (cyclic redundancy check)
0x04 Read Input Register
This function code is used to read from 1 to 125 contiguous input registers in a remote device. The Request PDU specifies the starting register address and the number of registers.
Input registers are addressed from zero. Therefore, input registers numbered 1-16 are addressed as 0-15.
- Request
Function Code | 1 Byte | 0x04 |
---|---|---|
Starting Address | 2 Bytes | 0x0000 ~ 0xFFFF |
Input Register Value | 2 Bytes | 1~125(0x7D) |
The register data in the response message is packed in two bytes per input register. For each register, the first byte contains the high bits and the second byte contains the low bits.
- Response:
Function Code | 1 Byte | 0x04 |
---|---|---|
Byte Count | 1 Byte | 2×N* |
Input Register Value | N×2 Bytes |
(*) N = Quantity of Input Registers
- Exception code
Error Code | 1 Byte | 0x84 |
---|---|---|
Exception Code | 1 Byte | 01, 02, 03, 04 |
For example:
This command requests to read the input register 9.
Request: 01 04 00 08 00 01 B0 08
01: slave address 04: function code 04 (read input register) 00 08: Data address of the first register requested (0008 HEX = 8, + 1 offset = input register 9) 00 01: Quantity of Requested Coils (read 1 register) B0 08: CRC (cyclic redundancy check)
Response: 01 04 02 00 0A 39 37
01: Slave address 04: Function code 04 (read input register) 02: Byte count (1 register x 2 bytes of each register = 2 bytes) 00 0A: Register content 39 37: CRC (cyclic redundancy check)
0x05 Write Single Coil
This function code is used to write a single output in the device to "on" or "off". The requested On/Off state is specified by a constant in the Request Data field. The request specifies the address of the coil to be forced.
Coils are addressed from zero. Therefore the coil numbered 1 is addressed as 0.
The value 0xFF00 requests that the coil be in the On state. The value 0x0000 requests that the coil be in the Off state. All other values are illegal and do not affect the coil.
- Request:
Function Code | 1 Byte | 0x05 |
---|---|---|
Coil Address | 2 Bytes | 0x0000 ~ 0xFFFF |
Status Value | 2 Bytes | 0x0000 or 0xFF00 |
- Response
Function Code | 1 Byte | 0x05 |
---|---|---|
Coil Address | 2 Bytes | 0x0000 ~ 0xFFFF |
Status Value | 2 Bytes | 0x0000 or 0xFF00 |
- Exception
Error code | 1 Byte | 0x85 |
---|---|---|
Exception Function Code | 1 Byte | 01, 02, 03, 04 |
For example:
This command requests that coil 173 be written ON.
Request: 01 05 00 AC FF 00 4C 1B
01: Slave address 05: Function code 05 (write single coil) 00 AC: data address of coil (00 AC HEX = 172, + 1 offset = coil 173) FF 00: the status to be written (FF00 = ON, 0000 = OFF) 4C 1B: CRC (cyclic redundancy check)
Response: 01 05 00 AC FF 00 4C 1B
01: Slave address 05: Function code 05 (write single coil) 00 AC: the data address of coil (00 AC HEX = 172, + 1 offset = coil 173) FF 00: the status to be written (FF00 = ON, 0000 = OFF) 4C 1B: CRC (cyclic redundancy check)
0x06 Write Single Register
This function code writes a single holding register to the device, and the request data describes the address of the register to be written, and the register value.
Registers are addressed starting at zero. Therefore register numbered 1 is addressed as 0.
- Request
Function Code | 1 Byte | 0x06 |
---|---|---|
Register Address | 2 Bytes | 0x0000 ~ 0xFFFF |
Register Value | 2 Bytes | 0x0000 ~ 0xFFFF |
- Response:
Function Code | 1 Byte | 0x06 |
---|---|---|
Register Address | 2 Bytes | 0x0000 ~ 0xFFFF |
Register Value | 2 Bytes | 0x0000 ~ 0xFFFF |
- Error
Error Code | 1 Byte | 0x86 |
---|---|---|
Exception Function Code | 1 Byte | 01, 02, 03, 04 |
For example:
This command requests that hex 00 03 be written to register 2.
Request: 01 06 00 01 00 03 98 0B
01: slave address 06: function code 06 (write single holding register) 00 01: the data address of register (00 01 HEX = 1, +1 offset = register 2) 00 13: the value of registers to be written 98 0B: CRC (cyclic redundancy check)
Response: 01 01 03 CD 6B 05 42 82
01: slave address 06: function code 06 (write single holding register) 00 01: the data address of register (00 01 HEX = 1, +1 offset = register 2) 00 13: the value of registers to be written 98 0B: CRC (cyclic redundancy check)
0x0F Write Multiple Coils
This function code is used to force each coil in a sequence of coils to either ON or OFF in a remote device. The Request PDU specifies the starting address of coils, quantity of coils, and coil state.
Register addressing starts at zero. Thus, register number 1 is addressed as 0.
The on/off state of the request is specified by the contents of the request data field. A logical "1" in a bit position in the field requests the corresponding output to be on. A logical "0" requests that it be turned off.
- Request
Function Code | 1 Byte | 0x0F |
---|---|---|
Initial Address | 2 Bytes | 0x0000 ~ 0xFFFF |
Quantity of Coil | 2 Bytes | 0x0001 ~ 0x07B0 |
Byte Count | 1 Byte | N* |
Output Value | N x 1 Byte |
(*) N = Quantity of Outputs/ 8, If the remainder is not 0, then N = N+1
- Response:
Function Code | 1 Byte | 0x0F |
---|---|---|
Initial Address | 2 Bytes | 0x0000 ~ 0xFFFF |
Quantity of Coils | 2 Bytes | 0x0001 ~ 0x07B0 |
- Exception
Error Code | 1 Byte | 0x8F |
---|---|---|
Exception Function Code | 1 Byte | 01, 02, 03, 04 |
For example:
This command requests that 10 coils be written from coil 20.
Request: 01 0F 00 13 00 0A 02 CD 01 72 CB
01: slave address 0F: function code 0F (write multiple coils) 00 13: the data address of the first coil to be read. (00 13 HEX = 19, +1 offset = coil 20) 00 0A: the quantity of coils to be written (0A HEX =10) 02: the data bytes to be followed (10 coils = 1 byte + 2 bits + 6 idle bits = 2 bytes) CD: coil 27 - 20 (1100 1101) 01: coil 29 - 28 (0100 0001) 72 CB: CRC (cyclic redundancy check)
Response: 01 0F 00 13 00 0A 24 09
01: slave address 0F: function code 0F (write multiple coils) 00 13: the data address of the first coil to be read (00 13 HEX = 19, +1 offset = coil 20) 00 0A: the quantity of coils to be written (0A HEX =10) 24 09: CRC (cyclic redundancy check)
0x10 Write Multiple Registers
This function code writes a contiguous set of registers (1 to 123 registers) to the device. The request data describes the register start address, and the requested written value is specified in the request data field. The data is packed in two bytes per register.
- Request:
Function Code | 1 Byte | 0x10 |
---|---|---|
Starting Address | 2 Bytes | 0x0000 ~ 0xFFFF |
Quantity of Registers | 2 Bytes | 0x0001 ~ 0x007B |
Byte Count | 1 Byte | 2×N* |
Register Value | N2 x Byte |
(*) N = Quantity of Registers
- Response:
Function code | 1 byte | 0x10 |
---|---|---|
Starting Address | 2 Bytes | 0x0000 ~ 0xFFFF |
Quantity of Registers | 2 Bytes | 0x0001 ~ 0x007B |
- Exception
Error Code | 1 Byte | 0x90 |
---|---|---|
Exception Function Code | 1 Byte | 01, 02, 03, 04 |
For example:
This command requests that hex 00 0A and 01 02 be written to registers 2 and 3.
Request: 01 10 00 01 00 02 04 00 0A 01 02 92 30
01: slave address 01: function code 10 (write multiple holding registers) 00 01: the data address of the first register (00 11 HEX = 1, +1 offset = register 2) 00 02: the quantity of register to be written 04: the data byte numbers to be follow (2 registers x 2 bytes of each register = 4 bytes) 00 0A: the value to be written in register 2 01 02: the value to be written in register 3 92 30: CRC (cyclic redundancy check)
Response: 01 01 10 00 01 00 02 1B D3
01: slave address 01: function code 10 (write multiple holding registers) 00 01: the data address of the first register (00 11 HEX = 1, +1 offset = register 2) 00 02: the quantity of the written register 1B D3: CRC (cyclic redundancy check)
- for more details, you can refer to Modbus_Application_Protocol_V1_1b3, Modbus Function Codes.