Modbus RTU made simple with detailed descriptions and examples

26 April 2024 Knowledge Base
Modbus RTU article header

From this article, you will learn about the Modbus RTU protocol, which is widely used in process control systems.

Contents:

Modbus RTU protocol description

Modbus is a communication protocol based on a master–slave architecture. It uses RS-485, RS-422, and RS-232 interfaces, as well as Ethernet TCP/IP networks (Modbus TCP) for data transfer.

The Modbus RTU message consists of the SlaveID (device address), the function code, special data (depending on the function), and the CRC checksum.

SlaveID Function code Special data CRC

If you discard the SlaveID address and the CRC checksum, you get the PDU (Protocol Data Unit).

SlaveID is the address of the device. It can take a value from 0 to 247; addresses from 248 to 255 are reserved.

Data in a module is stored in four tables.

Two tables are read-only and two are read-write.

9,999 values are placed in each table.

REGISTER NUMBER REGISTER ADDRESS (HEX) ACCESS NAME TYPE
1–9,999 0000 to 270E read–write Discrete Output Coils DO
10,001–19,999 0000 to 270E read Discrete Input Contacts DI
30,001–39,999 0000 to 270E read Analog Input Registers AI
40,001–49,999 0000 to 270E read–write Analog Output Holding Registers AO

The Modbus message uses the register address.

For example, the first AO holding register has the number 40001, but its address is 0000.

The difference between these two quantities is the “offset”.

Each table has its own offset: 1, 10001, 30001, and 40001.

The following is an example of a Modbus RTU request for obtaining holding register values (AO) from registers #40108 to #40110 with device address 17.

11 03 006B 0003 7687

11 Device address (SlaveID). 17 = 11 hex
03 Function code
006B Address of the first register (40108 − 40001 = 107 = 6B hex)
0003 Number of registers requested (read 3 registers from 40108 to 40110)
7687 CRC checksum

In response, the Modbus RTU slave returns:

11 03 06 AE41 5652 4340 49AD

Where:

11 Device address (17 = 11 hex) SlaveID
03 Function code Function Code
06 Number of following bytes (6 bytes follow) Byte Count
AE High byte of register value (AE hex) Register value Hi (AO0)
41 Low byte of register value (41 hex) Register value Lo (AO0)
56 High byte of register value (56 hex) Register value Hi (AO1)
52 Low byte of register value (52 hex) Register value Lo (AO1)
43 High byte of register value (43 hex) Register value Hi (AO2)
40 Low byte of register value (40 hex) Register value Lo (AO2)
49 Checksum CRC value Hi
AD Checksum CRC value Lo

The analog output register AO0 has the value AE 41 (hex) or 44,609 in decimal notation.

The analog output register AO1 has the value 56 52 (hex) or 22,098 in decimal.

The analog output register AO2 has the value 43 40 (hex) or 17,216 in decimal.

The AE 41 (hex) value is the 16-bit pattern 1010 1110 0100 0001, which can represent different quantities depending on the interpretation.

The value of register 40108, when combined with register 40109, yields a 32-bit value.

An example of representations:

View type Value range Example in HEX In decimal form
16-bit unsigned integer 0 to 65,535 AE41 44,609
16-bit signed integer −32,768 to 32,767 AE41 −20,927
two-character ASCII string 2 char AE41 ® A
discrete on/off value 0 and 1 0001 0001
32-bit unsigned integer 0 to 4,294,967,295 AE41 5652 2,923,517,522
32-bit signed integer −2,147,483,648 to 2,147,483,647 AE41 5652 −1,371,449,774
32-bit single-precision IEEE floating-point number 1.2×10−38 to 3.4×10+38 AE41 5652 −4.395978 E−11
four-character ASCII string 4 char AE41 5652 ® A V R

Back to contents

What are Modbus RTU commands?

Here is a table with the codes for reading and writing Modbus RTU registers.

FUNCTION CODE WHAT THE FUNCTION DOES VALUE TYPE ACCESS TYPE
01 (0x01) Read DO Read Coil Status Discrete Read
02 (0x02) Read DI Read Input Status Discrete Read
03 (0x03) Read AO Read Holding Registers 16 bit Read
04 (0x04) Read AI Read Input Registers 16 bit Read
05 (0x05) Write one DO Force Single Coil Discrete Write
06 (0x06) Write one AO Preset Single Register 16 bit Write
15 (0x0F) Multiple DO recording Force Multiple Coils Discrete Write
16 (0x10) Multiple AO recording Preset Multiple Registers 16 bit Write

Back to contents

How can I send a Modbus RTU command to read a discrete output? Command 0x01

This command is used to read the values of DO (digital outputs).

The PDU request specifies the start address of the first DO register and the number of required DO values thereafter. In the PDU, DO values are addressed starting from zero.

The DO values in the response are packed into bytes and correspond to bit values.

Bit values are defined as 1 = ON and 0 = OFF.

The least significant bit of the first data byte contains the DO value whose address was specified in the request. The remaining DO values follow in ascending order toward the most significant bit of the byte (i.e., from right to left).

If fewer than eight DO values are requested, the remaining bits in the last byte of the response are filled with zeros (from low to high bit). Byte Count indicates the number of full data bytes in the response.

Example of a DO query from 20 to 56 for device address 17. The address of the first register will be 0013 hex = 19, because addressing starts from 0 (0014 hex = 20; minus one offset gives 0013 hex = 19).

BYTE (Hex) REQUEST — Field name BYTE (Hex) ANSWER — Field name
11 Device address 11 Device address
01 Function code 01 Function code
00 Address of first register (Hi) 05 Number of following bytes
13 Address of first register (Lo) CD Register value DO 27–20 (1100 1101)
00 Number of registers (Hi) 6B Register value DO 35–28 (0110 1011)
25 Number of registers (Lo) B2 Register value DO 43–36 (1011 0010)
0E CRC 0E Register value DO 51–44 (0000 1110)
84 CRC 1B Register value DO 56–52 (0001 1011)
45 CRC
E6 CRC

The output states of DO 27–20 are represented by the byte value CD hex (binary 1100 1101).

For DO 56–52, five rightmost bits were requested; the remaining bits are filled with zeros to complete the byte (0001 1011).

Channels - - - DO 56 DO 55 DO 54 DO 53 DO 52
Bits 0 0 0 1 1 0 1 1
Hex 1B

Back to contents

How can I send a Modbus RTU command to read a digital input? Command 0x02

This command is used to read the values of digital inputs (DI).

Example of a DI request from registers #10197 to #10218 for device address 17. The address of the first register will be 00C4 hex = 196, because addressing starts from 0.

BYTE (Hex) REQUEST — Field name BYTE (Hex) ANSWER — Field name
11 Device address 11 Device address
02 Function code 02 Function code
00 Address of first register (Hi) 03 Number of following bytes
C4 Address of first register (Lo) AC Register value DI 10204–10197 (1010 1100)
00 Number of registers (Hi) DB Register value DI 10212–10205 (1101 1011)
16 Number of registers (Lo) 35 Register value DI 10218–10213 (0011 0101)
BA CRC 20 CRC
A9 CRC 18 CRC

Back to contents

How can I send a Modbus RTU command to read an analog output? Command 0x03

This command is used to read the values of analog outputs (AO).

Example of an AO request from registers #40108 to #40110 for device address 17. The address of the first register will be 006B hex = 107, because addressing starts from 0.

BYTE (Hex) REQUEST — Field name BYTE (Hex) ANSWER — Field name
11 Device address 11 Device address
03 Function code 03 Function code
00 Address of first register (Hi) 06 Number of following bytes
6B Address of first register (Lo) AE Register value Hi #40108
00 Number of registers (Hi) 41 Register value Lo #40108
03 Number of registers (Lo) 56 Register value Hi #40109
76 CRC 52 Register value Lo #40109
87 CRC 43 Register value Hi #40110
40 Register value Lo #40110
49 CRC
AD CRC

Back to contents

How can I send a Modbus RTU command to read an analog input? Command 0x04

This command is used to read the values of analog inputs (AI).

Example of an AI request for register #30009 with device address 17. The address of the first register is 0008 hex = 8, because addressing starts from 0.

BYTE (Hex) REQUEST — Field name BYTE (Hex) ANSWER — Field name
11 Device address 11 Device address
04 Function code 04 Function code
00 Address of first register (Hi) 02 Number of following bytes
08 Address of first register (Lo) 00 Register value Hi #30009
00 Number of registers (Hi) 0A Register value Lo #30009
01 Number of registers (Lo) F8 CRC
B2 CRC F4 CRC
98 CRC

Back to contents

How can I send a Modbus RTU command to write a discrete output? Command 0x05

This command is used to write one value to a DO (digital output).

The value FF 00 (hex) sets the output to ON.

The value 00 00 (hex) sets the output to OFF.

All other values are invalid and will not affect the output value.

The normal response to such a request is an echo (the request is repeated in the response) and is returned after the DO state has been changed.

Example of a DO write to register #173 for device address 17. The register address will be 00AC hex = 172, because addressing starts from 0.

BYTE (Hex) REQUEST — Field name BYTE (Hex) ANSWER — Field name
11 Device address 11 Device address
05 Function code 05 Function code
00 Address of first register (Hi) 00 Address of first register (Hi)
AC Address of first register (Lo) AC Address of first register (Lo)
FF Value (Hi) FF Value (Hi)
00 Value (Lo) 00 Value (Lo)
4E CRC 4E CRC
8B CRC 8B CRC

The DO173 output state has changed from OFF to ON.

Back to contents

How can I send a Modbus RTU command to write an analog output? Command 0x06

This command is used to write one value to an analog output (AO).

Example of writing to AO register #40002 for device address 17. The address of the first register will be 0001 hex = 1, because addressing starts from 0.

BYTE (Hex) REQUEST — Field name BYTE (Hex) ANSWER — Field name
11 Device address 11 Device address
06 Function code 06 Function code
00 Address of first register (Hi) 00 Address of first register (Hi)
01 Address of first register (Lo) 01 Address of first register (Lo)
00 Value (Hi) 00 Value (Hi)
03 Value (Lo) 03 Value (Lo)
9A CRC 9A CRC
9B CRC 9B CRC

Back to contents

How can I send a Modbus RTU command to write multiple discrete outputs? Command 0x0F

This command is used to write multiple values to DO (digital outputs).

Example of writing to several DOs for registers #20 to #29 with device address 17. The register address will be 0013 hex = 19, since addressing starts from 0.

BYTE (Hex) REQUEST — Field name BYTE (Hex) ANSWER — Field name
11 Device address 11 Device address
0F Function code 0F Function code
00 Address of first register (Hi) 00 Address of first register (Hi)
13 Address of first register (Lo) 13 Address of first register (Lo)
00 Number of registers (Hi) 00 Number of recorded registers (Hi)
0A Number of registers (Lo) 0A Number of recorded registers (Lo)
02 Number of following bytes 26 CRC
CD Byte value DO 27–20 (1100 1101) 99 CRC
01 Byte value DO 29–28 (0000 0001)
BF CRC
0B CRC

The answer returns the number of registers recorded.

Back to contents

How can I send a Modbus RTU command to write multiple analog outputs? Command 0x10

This command is used to write multiple values to analog outputs (AO).

Example of writing to AO registers #40002 and #40003 for device address 17. The address of the first register will be 0001 hex = 1, because addressing starts from 0.

BYTE (Hex) REQUEST — Field name BYTE (Hex) ANSWER — Field name
11 Device address 11 Device address
10 Function code 10 Function code
00 Address of first register (Hi) 00 Address of first register (Hi)
01 Address of first register (Lo) 01 Address of first register (Lo)
00 Number of registers (Hi) 00 Number of recorded registers (Hi)
02 Number of registers (Lo) 02 Number of recorded registers (Lo)
04 Number of following bytes 12 CRC
00 Value Hi 40002 98 CRC
0A Value Lo 40002
01 Value Hi 40003
02 Value Lo 40003
C6 CRC
F0 CRC

Back to contents

What are Modbus request errors?

If the device receives a request but cannot process it, the device responds with an error code.

The response contains the modified function code: the high-order bit is set to 1.

Example:

IT WAS IT BECOME
FUNCTIONAL CODE IN REQUEST Functional error code in response
01 (01 hex) 0000 0001 129 (81 hex) 1000 0001
02 (02 hex) 0000 0010 130 (82 hex) 1000 0010
03 (03 hex) 0000 0011 131 (83 hex) 1000 0011
04 (04 hex) 0000 0100 132 (84 hex) 1000 0100
05 (05 hex) 0000 0101 133 (85 hex) 1000 0101
06 (06 hex) 0000 0110 134 (86 hex) 1000 0110
15 (0F hex) 0000 1111 143 (8F hex) 1000 1111
16 (10 hex) 0001 0000 144 (90 hex) 1001 0000

Sample request and response with error:

BYTE (Hex) REQUEST — Field name BYTE (Hex) ANSWER — Field name
0A Device address 0A Device address
01 Function code 81 Function code with changed high bit
04 Address of first register (Hi) 02 Error code
A1 Address of first register (Lo) B0 CRC
00 Number of registers (Hi) 53 CRC
01 Number of registers (Lo)
AC CRC
63 CRC

Explanation of error codes:

01 Function code accepted but cannot be processed.
02 The data address specified in the request is not available.
03 The value contained in the request data field is invalid.
04 An unrecoverable error occurred while the slave attempted to perform the requested action.
05 The slave has accepted the request and is processing it, but it takes a long time. This response prevents a timeout on the host.
06 The slave is busy processing the command. The master must repeat the message later when the slave is free.
07 The slave cannot execute the program function specified in the request (applies to function codes 13 or 14). The master should request diagnostic or error information.
08 The slave detected a parity error when reading extended memory. The master can repeat the request, but repair is usually required.

Back to contents

Programs for working with the Modbus RTU protocol

The following programs make it easier to work with Modbus.

DCON Utility Pro — supports Modbus RTU, ASCII, DCON. Download

DCON Utility Pro screenshot

Modbus Master Tool — supports Modbus RTU, ASCII, TCP. Download

Modbus Master Tool screenshot

Modbus TCP client — supports Modbus TCP. Download

Modbus TCP client screenshot

Back to contents

Equipment with Modbus RTU support

Back to contents



Contact us!