Description taken from the website: https://ipc2u.com/articles/knowledge-base/modbus-rtu-made-simple-with-detailed-descriptions-and-examples/
Information about setting up devices to work with Modbus is given in the guide Modbus RTU.
List of functions for working with Modbus via Complex Events
Modbus — communication protocol is based on the master-slave architecture. It uses RS-485, RS-422, RS-232 interfaces, as well as Ethernet TCP / IP networks (Modbus TCP protocol) for data transfer.
Modbus RTU message consists of the address of the SlaveID device, the function code, the special data, depending on the function code and the CRC of the checksum.
SlaveID Function_code Special_data CRC
If you discard the SlaveID address and the CRC checksum, you get the PDU (Protocol Data Unit).
ID | PDU | CRC | |
---|---|---|---|
SlaveID | Function_code | Special_data | CRC |
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 the module is stored in 4 tables.
Two tables are read-only and two are read-write.
9999
values are placed in each table.
Register Number | Register Address HEX | Type | Name | Type |
---|---|---|---|---|
1 -9999 |
0x0000 to0x270E |
read-write | Discrete Output Coils | DO |
10001 -19999 |
0x0000 to0x270E |
read | Discrete Input Contacts | DI |
30001 -39999 |
0x0000 to0x270E |
read | Analog Input Registers | AI |
40001 -49999 |
0x0000 to0x270E |
read-write | Analog Output Holding Registers | AO |
Here is a table with the codes for reading and writing the Modbus RTU registers.
Function Code | What the Function Does | Value Type | Access Type |
---|---|---|---|
1 (0x01 ) |
Read DO | Discrete | Read |
2 (0x02 ) |
Read DI | Discrete | Read |
3 (0x03 ) |
Read AO | 16 bit | Read |
4 (0x04 ) |
Read AI | 16 bit | Read |
5 (0x05 ) |
Write one DO | Discrete | Write |
6 (0x06 ) |
Write one AO | 16 bit | Write |
15 (0x0F ) |
Multiple DO recording | Discrete | Write |
16 (0x10 ) |
Multiple AO recording | 16 bit | Write |
The Modbus message uses the register address.
For example, the first register of AO Holding Register has the number 40001
, but its address is 0х0000
.
The difference between these two quantities is offset
.
Each table has its own offset, respectively: 1
, 10001
, 30001
и 40001
.
The following is an example of a Modbus RTU request for obtaining the AO
value of the holding registers from registers 40108
to 40110
with the address of the device 17
.
11 03 006B 0003 7687
11 |
Address of the slaved device (17 = 11 hex) |
03 |
Functional code Function Code (reading Analog Output Holding Registers) |
006B |
Address of the first register (40108-40001 = 107 =6B hex) |
0003 |
Number of required registers (reading 3 registers from 40108 to 40110) |
7687 |
CRC checksum |
In response to the Modbus RTU Slave device we get:
11 03 06 AE41 5652 4340 49AD
11 |
Device address (SlaveID) |
03 |
Function Code |
06 |
Number of bytes further |
AE |
Register value Hi (AO0) |
41 |
Register value Lo (AO0) |
56 |
Register value Hi (AO1) |
52 |
Register value Lo (AO1) |
43 |
Register value Hi (AO2) |
40 |
Register value Lo (AO2) |
49 |
CRC value Hi |
AD |
CRC value Lo |
The analog output register AO0 has the value 0xAE41
or 44609
in the decimal system.
The analog output register AO1 has a value of 0x5652
or 22098
in the decimal system.
The analog output register AO2 has a value of 0x4340
or 17216
in the decimal system.
The 0xAE41
value is 16 bits 1010 1110 0100 0001
, can take a different value, depending on the type of representation.
The value of register 40108
when combined with register 40109
gives a 32 bit value.
An example of a representation.
View Type | Value Range | Example in HEX | In Decimal Form |
---|---|---|---|
16-bit unsigned integer | 0 to 65535 | AE41 |
44609 |
16-bit signed integer | -32768 to 32767 | AE41 |
-20927 |
two character ASCII string | 2 char | AE41 |
®A |
discrete on/off value | 0 and 1 | 0001 |
0001 |
32-bit unsigned integer | 0 to 4294967295 | AE415652 |
2923517522 |
32-bit signed integer | -2147483648 to 2147483647 | AE415652 |
-1371449774 |
32-bit IEEE floating point number | 1.2*10−38 to 3.4*10+38 | AE415652 |
-4.395978E-11 |
four character ASCII string | 4 char | AE415652 |
®AVR |
This command is used to read the values of the DO digital outputs.
The PDU request specifies the start address of the first DO register and the subsequent number of required DO values. In the PDU, the DO values are addressed starting from zero.
The DO values in the response are in one byte and correspond to the value of the bits.
The bit values are defined as:
1
= ON
0
= OFF
The low bit of the first data byte contains the DO value whose address was specified in the request. The remaining values of DO follow the increasing value to the highest value of the byte. Those. from right to left.
If less than eight DO values were requested, the remaining bits in the response will be filled with zeros (in the direction from the low to high byte). Byte Count Number of bytes further indicates the number of full bytes of data in the response.
Example of a DO query from 20
to 56
for the device's SlaveID address 17
. The address of the first register will be 0x0013
= 19
, because the account is maintained from 0 address (register = 20, -1 zero offset, we get 19).
Byte | Request | Byte | Response |
---|---|---|---|
(Hex) | Field name | (Hex) | Field name |
11 |
Device address | 11 |
Device address |
01 |
Functional code | 01 |
Functional code |
00 |
Address of the first register Hi bytes | 05 |
Number of bytes further |
13 |
Address of the first register Lo bytes | CD |
Register value DO 27-20 (11001101 ) |
00 |
Number of registers Hi bytes | 6B |
Register value DO 35-28 (01101011 ) |
25 |
Number of registers Lo bytes | B2 |
Register value DO 43-36 (10110010 ) |
0E |
Checksum CRC Hi bytes | 0E |
Register value DO 51-44 (00001110 ) |
84 |
Checksum CRC Lo bytes | 1B |
Register value DO 56-52 (00011011 ) |
45 |
Checksum CRC Hi bytes | ||
E6 |
Checksum CRC Lo bytes |
States of the outputs DO 27-20 are shown as the values of the 0xCD
hex, or in the binary system 11001101
.
In register DO 56-52, 5 bits on the right were requested, and the remaining bits are filled with zeros to the full byte (00011011).
Channels | DO 56 | DO 55 | DO 54 | DO 53 | DO 52 | |||
---|---|---|---|---|---|---|---|---|
Bits | 0 |
0 |
0 |
1 |
1 |
0 |
1 |
1 |
Hex | 1B |
This command is used to read the values of digital inputs DI.
Example of a DI request from the registers from 10197
to 10218
for the device's SlaveID address 17
. The address of the first register will be 0x00C4
hex = 196, (because account is maintained from 0 address).
Byte | Request | Byte | Response |
---|---|---|---|
(Hex) | Field name | (Hex) | Field name |
11 |
Device address | 11 |
Device address |
02 |
Functional code | 02 |
Functional code |
00 |
Address of the first register Hi bytes | 03 |
Number of bytes further |
C4 |
Address of the first register Lo bytes | AC |
Register value DI 10204-10197 (10101100 ) |
00 |
Number of registers Hi bytes | DB |
Register value DI 10212-10205 (11011011 ) |
16 |
Number of registers Lo bytes | 35 |
Register value DI 10218-10213 (00110101 ) |
BA |
Checksum CRC Hi bytes | 20 |
Checksum CRC Hi bytes |
A9 |
Checksum CRC Lo bytes | 18 |
Checksum CRC Lo bytes |
This command is used to read the values of the analog outputs AO.
Example of an AO request from registers from 40108
to 40110
for the SlaveID of the device address 17
. The address of the first register will be 0x006B
hex = 107, (because account is maintained from 0 address).
Byte | Request | Byte | Response |
---|---|---|---|
(Hex) | Field name | (Hex) | Field name |
11 |
Device address | 11 |
Device address |
03 |
Functional code | 03 |
Functional code |
00 |
Address of the first register Hi bytes | 06 |
Number of bytes further |
6B |
Address of the first register Lo bytes | AE |
Register value 40108 Hi bytes |
00 |
Number of registers Hi bytes | 41 |
Register value 40108 Lo bytes |
03 |
Number of registers Lo bytes | 56 |
Register value 40109 Hi bytes |
76 |
Checksum CRC Hi bytes | 52 |
Register value 40109 Lo bytes |
87 |
Checksum CRC Lo bytes | 43 |
Register value 40110 Hi bytes |
40 |
Register value 40110 Lo bytes | ||
49 |
Checksum CRC Hi bytes | ||
AD |
Checksum CRC Lo bytes |
This command is used to read the values of analog inputs AI.
Example of an AI request from the register 30009
for the SlaveID of the device address 17
. The address of the first register is 0x0008
hex = 8, (because account is maintained from 0 address).
Byte | Request | Byte | Response |
---|---|---|---|
(Hex) | Field name | (Hex) | Field name |
11 |
Device address | 11 |
Device address |
04 |
Functional code | 04 |
Functional code |
00 |
Address of the first register Hi bytes | 02 |
Number of bytes further |
08 |
Address of the first register Lo bytes | 00 |
Register value Hi 30009 |
00 |
Number of registers Hi bytes | 0A |
Register value Lo 30009 |
01 |
Number of registers Lo bytes | F8 |
Checksum CRC Hi bytes |
B2 |
Checksum CRC Hi bytes | F4 |
Checksum CRC Lo bytes |
98 |
Checksum CRC Lo bytes |
This command is used to record one value of the DO digital output.
The value 0xFF00
hex sets the output to ON
.
The value 0x0000
hex sets the output to OFF
.
All other values are invalid and will not be affected by the output value.
The normal response to such a request is an эхо (a repeat request in the response), is returned after the DO state has been changed.
An example of a DO record with register 173
for the SlaveID address of the device 17
. The register address will be 0x00AC
hex = 172, (because account is maintained from 0 address).
Byte | Request | Byte | Response |
---|---|---|---|
(Hex) | Field name | (Hex) | Field name |
11 |
Device address | 11 |
Device address |
05 |
Functional code | 05 |
Functional code |
00 |
Address of the first register Hi bytes | 00 |
Address of the first register Hi bytes |
AC |
Address of the first register Lo bytes | AC |
Address of the first register Lo bytes |
FF |
Value of Hi bytes | FF |
Value of Hi bytes |
00 |
Value of Lo bytes | 00 |
Value of Lo bytes |
4E |
Checksum CRC Hi bytes | 4E |
Checksum CRC Hi bytes |
8B |
Checksum CRC Lo bytes | 8B |
Checksum CRC Lo bytes |
The DO173 output state has changed from
OFF
toON
.
This command is used to record one value of the analog output AO.
The normal response to such a request is an echo (a repeat request in the response), is returned after the AO state has been changed.
Example of recording in AO with register 40002
for SlaveID address of the device 17
. The address of the first register will be 0x0001
hex = 1, (because account is maintained from 0 address).
Byte | Request | Byte | Response |
---|---|---|---|
(Hex) | Field name | (Hex) | Field name |
11 |
Device address | 11 |
Device address |
06 |
Functional code | 06 |
Functional code |
00 |
Address of the first register Hi bytes | 00 |
Address of the first register Hi bytes |
01 |
Address of the first register Lo bytes | 01 |
Address of the first register Lo bytes |
00 |
Value of Hi bytes | 00 |
Value of Hi bytes |
03 |
Value of Lo bytes | 03 |
Value of Lo bytes |
9A |
Checksum CRC Hi bytes | 9A |
Checksum CRC Hi bytes |
9B |
Checksum CRC Lo bytes | 9B |
Checksum CRC Lo bytes |
The AO2 register is set to
3
.
This command is used to record multiple values of DO's digital output.
Example of writing in several DOs with registers from 20
to 29
for the SlaveID address of the device 17
. The register address will be 0x0013
hex = 19, (because account is maintained from 0 address).
Byte | Request | Byte | Response |
---|---|---|---|
(Hex) | Field name | (Hex) | Field name |
11 |
Device address | 11 |
Device address |
07 |
Functional code | 07 |
Functional code |
00 |
Address of the first register Hi bytes | 00 |
Address of the first register Hi bytes |
13 |
Address of the first register Lo bytes | 13 |
Address of the first register Lo bytes |
00 |
Value of Hi bytes | 00 |
Value of Hi bytes |
0A |
Value of Lo bytes | 0A |
Value of Lo bytes |
02 |
Number of bytes further | 26 |
Checksum CRC Hi bytes |
CD |
Byte Value DO 27-20 (11001101 ) |
99 |
Checksum CRC Lo bytes |
01 |
Byte Value DO 29-28 (00000001 ) |
||
BF |
Checksum CRC Hi bytes | ||
0B |
Checksum CRC Lo bytes |
The response returns the number of registers recorded.
This command is used to record multiple values of the analog output AO.
Example of recording in several AO with registers 40002
and 40003
for the SlaveID address of the device 17
. The address of the first register will be 0x0001
hex = 1, (because account is maintained from 0 address).
Byte | Request | Byte | Response |
---|---|---|---|
(Hex) | Field name | (Hex) | Field name |
11 |
Device address | 11 |
Device address |
10 |
Functional code | 10 |
Functional code |
00 |
Address of the first register Hi bytes | 00 |
Address of the first register Hi bytes |
01 |
Address of the first register Lo bytes | 01 |
Address of the first register Lo bytes |
00 |
Value of Hi bytes | 00 |
Value of Hi bytes |
02 |
Value of Lo bytes | 02 |
Value of Lo bytes |
04 |
Number of bytes further | 12 |
Checksum CRC Hi bytes |
00 |
Value 40002 Hi bytes | 98 |
Checksum CRC Lo bytes |
0A |
Value 40002 Lo bytes | ||
01 |
Value 40003 Hi bytes | ||
02 |
Value 40003 Lo bytes | ||
C6 |
Checksum CRC Hi bytes | ||
F0 |
Checksum CRC Lo bytes |
The response returns the number of registers recorded.
If the device receives a request, but the request can not be processed, the device will respond with an error code.
The response will contain the modified Function code, the high-order bit will be 1
.
Functional Code in Request | Functional Code in Response | ||||
---|---|---|---|---|---|
(DEC) | (HEX) | (BIN) | (DEC) | (HEX) | (BIN) |
1 |
0x01 |
00000001 |
129 |
0x81 |
10000001 |
2 |
0x02 |
00000010 |
130 |
0x82 |
10000010 |
3 |
0x03 |
00000011 |
131 |
0x83 |
10000011 |
4 |
0x04 |
00000100 |
132 |
0x84 |
10000100 |
5 |
0x05 |
00000101 |
133 |
0x85 |
10000101 |
6 |
0x06 |
00000110 |
134 |
0x86 |
10000110 |
15 |
0x0F |
00001111 |
143 |
0x8F |
10001111 |
16 |
0x10 |
00010000 |
144 |
0x90 |
10010000 |
Example of the request and response with error:
Byte | Request | Byte | Response |
---|---|---|---|
(Hex) | Field name | (Hex) | Field name |
0A |
Device address | 0A |
Device address |
01 |
Functional code | 81 |
Functional code with changed bit |
04 |
Address of the first register Hi bytes | 02 |
Error code |
A1 |
Address of the first register Lo bytes | B0 |
Checksum CRC Hi bytes |
00 |
Number of registers Hi bytes | 53 |
Checksum CRC Lo bytes |
01 |
Number of registers Lo bytes | ||
AC |
Checksum CRC Hi bytes | ||
63 |
Checksum CRC Lo bytes |
Code | Descriptiion |
---|---|
1 (0x01 ) |
Received function code cannot be processed. |
2 (0x02 ) |
The data address specified in the request is not available. |
3 (0x03 ) |
The value contained in the query data field is an invalid value. |
4 (0x04 ) |
An unrecoverable error occurred while the slave attempted to perform the requested action. |
5 (0x05 ) |
The slave has accepted the request and processes it, but it takes a long time. This response prevents the host from generating a timeout error. |
6 (0x06 ) |
The slave is busy processing the command. The master must repeat the message later when the slave is freed. |
7 (0x07 ) |
The slave can not execute the program function specified in the request. This code is returned for an unsuccessful program request using functions with numbers 13 or 14 . The master must request diagnostic information or error information from the slave. |
8 (0x08 ) |
The slave detected a parity error when reading the extended memory. The master can repeat the request, but usually in such cases, repairs are required. |
10 (0x0A ) |
The gateway is not configured correctly or is overloaded with requests. |
11 (0x0B ) |
The slave is not online or there is no response from it. |