Detailed Explanation of Modbus-RTU Message Structure and Common Function Codes

Detailed Explanation of Modbus-RTU Message Structure and Common Function Codes

Modbus is a serial communication protocol that was published by Modicon (now Schneider Electric) in 1979 for communication with programmable logic controllers (PLCs). The Modbus protocol has now become the industry standard for communication protocols in the field of industrial control and is commonly used for communication between industrial electronic devices.

The reason why the Modbus protocol has become the most widely used protocol in the field of industrial control is due to the following characteristics:

  • Open Architecture: The Modbus protocol is completely open and has no copyright restrictions, allowing companies to freely modify it to adapt to their devices, thus reducing development costs. After Schneider Electric made the protocol public, over 200 companies worldwide launched compatible hardware;
  • Cross-Platform Compatibility: Supports various physical layer interfaces such as RS-485, RS-232, and Ethernet, covering scenarios from serial communication to TCP/IP networks;
  • Simple and Stable Protocol: Fixed data frame format (Address + Function Code + Data + CRC) and master-slave communication mode ensure real-time performance and reliability;

Modbus RTU Protocol

1. Basic Concepts of Modbus RTU Protocol

The Modbus RTU mode is a binary mode where data is transmitted byte by byte, with the high bit of each byte sent first. During data transmission, an error detection mechanism is used to ensure data integrity. Typically, the RTU mode communicates via RS-485 bus, as it supports multiple devices (up to 247 devices) and long-distance transmission.

2. Frame Structure of Modbus RTU Communication

Purpose Length Description
Device Address 1 byte The slave has a unique address, ranging from 1 to 247. Address 0 is a broadcast address, and the slave will not respond.
Function Code 1 byte The type of operation requested by the master for the slave to perform.
Data Variable (0-252 bytes) Contains specific parameters of the command, with format and length depending on the function code.
CRC Check 2 bytes Checks for errors in the data during transmission.

3. Function Codes in Modbus RTU Protocol

Common Function Code Table

Function Code Name Data Type Function
0x01 Read Coils Bit Obtains the current status (ON/OFF) of a group of logical coils.
0x02 Read Discrete Inputs Bit Obtains the current status (ON/OFF) of a group of switch inputs.
0x03 Read Holding Registers Integer, Float, Character Obtains the current binary value from one or more holding registers.
0x04 Read Input Registers Integer, Float Obtains the current binary value from one or more input registers.
0x05 Write Single Coil Bit Forcibly sets the ON/OFF state of a logical coil.
0x06 Write Single Register Integer, Float, Character Loads a specific binary value into a holding register.
0x0F Write Multiple Coils Bit Forcibly sets the ON/OFF state of a series of continuous logical coils.
0x10 Write Multiple Registers Integer, Float, Character Loads specific binary values into a series of continuous holding registers.

1. Function Code 0x01 – Read Coils

  • Function: Reads the coil registers of the slave, bit operation, can read single or multiple;
  • Send Command: Slave Address: 0x01, Register Start Address: 0x0017, read a total of 8 coils. The command sent is as follows:
    Slave Address Function Code Register Start Address (High 8 bits) Register Start Address (Low 8 bits) Register Count (High 8 bits) Register Count (Low 8 bits) CRC H CRC L
    0x01 0x01 0x00 0x17 0x00 0x08 0x8D 0xC8
Tx:01 01 00 17 00 08 8D C8
  • Response: Returns the corresponding coil status for each bit of data, where 1 indicates ON and 0 indicates OFF;
Slave Address Function Code Returned Byte Count Data CRC H CRC L
0x01 0x01 0x01 0x17 0x11 0x86
Rx:01 01 01 17 11 86

2. Function Code 0x02 – Read Discrete Inputs

  • Function: Reads the discrete input registers of the slave, bit operation, can read single or multiple;
  • Send Command: Slave Address: 0x01, Register Start Address: 0x0017, read a total of 8 coils. The command sent is as follows:
    Slave Address Function Code Register Start Address (High 8 bits) Register Start Address (Low 8 bits) Register Count (High 8 bits) Register Count (Low 8 bits) CRC H CRC L
    0x01 0x02 0x00 0x17 0x00 0x08 0xC9 0xC8
Tx:01 02 00 17 00 08 C9 C8
  • Response: Returns the corresponding coil status for each bit of data, where 1 indicates ON and 0 indicates OFF;
Slave Address Function Code Returned Byte Count Data CRC H CRC L
0x01 0x02 0x01 0x17 0xE1 0x86
Rx:01 02 01 17 E1 86

3. Function Code 0x03 – Read Holding Registers

  • Function: Reads the holding registers of the slave, byte operation, can read single or multiple;
  • Send Command: Slave Address: 0x01, Register Start Address: 0x0017, read a total of 1 register. The command sent is as follows:
    Slave Address Function Code Register Start Address (High 8 bits) Register Start Address (Low 8 bits) Register Count (High 8 bits) Register Count (Low 8 bits) CRC H CRC L
    0x01 0x03 0x00 0x17 0x00 0x01 0x34 0x0E
Tx:01 03 00 17 00 01 34 0E
  • Response: Returns data;
Slave Address Function Code Returned Byte Count Data1H Data1L CRC H CRC L
0x01 0x03 0x02 0x17 0x01 0x76 0x74
Rx:01 03 02 17 01 76 74

4. Function Code 0x04 – Read Input Registers

  • Function: Reads the input registers of the slave, byte operation, can read single or multiple;
  • Send Command: Slave Address: 0x01, Register Start Address: 0x0017, read a total of 1 register. The command sent is as follows:
    Slave Address Function Code Register Start Address (High 8 bits) Register Start Address (Low 8 bits) Register Count (High 8 bits) Register Count (Low 8 bits) CRC H CRC L
    0x01 0x04 0x00 0x17 0x00 0x01 0x81 0xCE
Tx:01 04 00 17 00 01 81 CE
  • Response: Returns data;
Slave Address Function Code Returned Byte Count Data1H Data1L CRC H CRC L
0x01 0x04 0x02 0x17 0x01 0x77 0x00
Rx:01 04 02 17 01 77 00

5. Function Code 0x05 – Write Single Coil

  • Function: Writes a single coil, bit operation, can only write one, writing 0xFF00 indicates the coil is ON, writing 0x0000 indicates the coil is OFF.
  • Send Command: Slave Address: 0x01, set coil 0x0017 to ON. The command sent is as follows:
    Slave Address Function Code Register Start Address (High 8 bits) Register Start Address (Low 8 bits) DATAH DATAL CRC H CRC L
    0x01 0x05 0x00 0x17 0xFF 0x00 0x3C 0x3E
Tx:01 05 00 17 FF 00 3C 3E
  • Response: Same as sent data;

6. Function Code 0x06 – Write Single Register

  • Function: Writes a single holding register, byte operation, can only write one;
  • Send Command: Slave Address: 0x01, set register 0x0017 to 0x2193. The command sent is as follows:
    Slave Address Function Code Register Start Address (High 8 bits) Register Start Address (Low 8 bits) DATAH DATAL CRC H CRC L
    0x01 0x06 0x00 0x17 0x21 0x93 0x61 0xF3
Tx:01 06 00 17 21 93 61 F3
  • Response: Same as sent data;

7. Function Code 0x0F – Write Multiple Coils

  • Function: Writes multiple coil registers, where bit 0 in the data area indicates OFF, and bit 1 indicates ON;
  • Send Command: Slave Address: 0x01, coil address 0x0012, write 5 coils. The command sent is as follows:
    Slave Address Function Code Register Start Address (High 8 bits) Register Start Address (Low 8 bits) Register Count (High 8 bits) Register Count (Low 8 bits) Byte Count DATAH DATAL CRC H CRC L
    0x01 0x0F 0x00 0x12 0x00 0x05 0x01 0x00 0x13 0x54 0x93
Tx:01 0F 00 12 00 05 01 00 13 54 93
  • Response:
Slave Address Function Code Register Start Address (High 8 bits) Register Start Address (Low 8 bits) Register Count (High 8 bits) Register Count (Low 8 bits) Byte Count CRC H CRC L
0x01 0x0F 0x00 0x12 0x00 0x05 0x01 0xCC 0xD7
Tx:01 0F 00 12 00 05 01 00 13 CC D7

8. Function Code 0x10 – Write Multiple Registers

  • Function: Writes multiple holding registers, byte operation, can write multiple;
  • Send Command: Slave Address: 0x01, register address 0x0012, write 2 registers with 4 bytes of data. The command sent is as follows:
    Slave Address Function Code Register Start Address (High 8 bits) Register Start Address (Low 8 bits) Register Count (High 8 bits) Register Count (Low 8 bits) Byte Count DATA1H DATA1L DATA2H DATA2L CRC H CRC L
    0x01 0x10 0x00 0x12 0x00 0x02 0x04 0x00 0x13 0x00 0x11 0x42 0xB3
Tx:01 0F 00 12 00 05 01 00 13 00 11 42 B3
  • Response:
Slave Address Function Code Register Start Address (High 8 bits) Register Start Address (Low 8 bits) Register Count (High 8 bits) Register Count (Low 8 bits) Byte Count CRC H CRC L
0x01 0x10 0x00 0x12 0x00 0x02 0x04 0x0C 0x8B
Tx:01 0F 00 12 00 02 04 0C 8B 

Conclusion

The Modbus RTU protocol is a very common communication protocol in industrial control systems, widely used for serial communication between various devices due to its simplicity, reliability, and efficiency. It is suitable for small to medium-sized systems, especially playing an important role in communication between field devices, PLCs, and sensors. However, due to the lack of built-in security mechanisms, it is necessary to ensure the security of the network and communication when using it.

Recommended Tools

  • Free online tool Modbus RTU Message Parser
  • Free online tool Modbus TCP Message Parser
  • Free online tool Modbus ASCII Message Parser
  • Useful! Hexadecimal to Float Online Tool

Leave a Comment