Technical Article

Introduction to Modbus and Modbus Function Codes

January 30, 2023 by Shawn Dietrich

Modbus is one of the oldest industrial communication protocols still in use today. Continue reading to find out how the protocol works and how to use it for monitoring and control.

When industrial electronic devices communicate with each other, they need to use a common communication protocol such as Ethernet/IP, ProfiNet, or EtherCat. Of these communication protocols, Modbus is one of the oldest still in use today.


What is Modbus?

Created in 1979 by Modicon (now Schneider Electric), Modbus was originally used to communicate with the Modicon family of PLCs. Today, Modbus is an open protocol used by PLC and automation device manufacturers.

With Modbus being an ‘open’ standard, any manufacturer can use the protocol without having to pay a fee to the organization that maintains the standard. With the protocol being able to reside on different types of infrastructure, it is common to see multiple manufacturers on the same Modbus network all talking to each other. For these reasons, Modbus can be found on PLCs, HMIs, sensors, and motion control devices. In some cases, Modbus is found alongside other protocols, such as Ethernet/IP or ProfiNet


standard Modbus data frame

Figure 1. A standard Modbus frame. Image used courtesy of Modbus


Modbus Protocol

The Modbus protocol works on a master/slave communication template (also often called the client/server model in modern networks). This means only the master (client) can request data, and typically, the PLC or automation controller is the master (client) in the network. 

The master device can choose to broadcast messages or directly address devices on the network, and the slave devices can respond to directly addressed messages only. The slave devices can also perform actions based on the messages received from the master device. 

Each message will have an address, a function code, a data register, and a cyclic redundancy check (CRC) register. The slave device will compare the message address, and if it’s a match to its assigned address, the device will execute the function code.

Modbus network architecture

Figure 2. An example of a Modbus network architecture. Image used courtesy of Figueroa-Lorenzo et al.


Modbus addressing model

Figure 3. A Modbus addressing model. Image used courtesy of Modbus


Modbus Function Codes

Because the slave devices do not broadcast their information, the master needs to request, or ‘poll’, information about the slave. Alternatively, the master may send output commands to tell the slave what coils or registers need to be updated. These commands are executed using function codes. The codes are two bytes long or one word (16 bit) of hexadecimal numbering with the most significant byte first or “big-endian”. 

Typically, each device on the Modbus network will have four memory registers: discrete inputs, coil outputs, input registers (input data), and holding registers (output data). These memory registers can be read or manipulated using function codes. 

The device uses these memory registers to control or monitor itself. For example, a VFD might use the discrete inputs or registers to start, stop, or reset faults. The input registers can be used for setting speed or frequency, and the holding registers can be used to display the speed or frequency output. A sensor may only have the ability to read input registers which is where the sensor's values would reside.


Modbus RTU and Modbus TCP are the most common

Figure 4. Modbus temperature sensors. Image used courtesy of Modbus


Standard Modbus Function Codes

Most devices will have a standard set of functions and numeric codes that can be used to monitor or control the device


Discrete Input Codes:

02 - Read Discrete Inputs

This function can read the status of multiple input terminals which is helpful with HMI or SCADA screens.


Discrete Output/Internal Codes:

01 - Read Output Coils

This function can be used to read the status of a specific output coil with up to 2000 different outputs.

05 - Write Single Output

This function will write a 1 (on) or 0 (off) to a specific output coil.

15 - Write Multiple Outputs

When you need to set a group of outputs on or off, this might be used to set a group of outputs off when a door opens.


Register Input Codes:

04 - Read Input Registers

This function can be used to read numeric values from devices, like analog input values.


Register Output/Internal Codes:

03 - Read Holding Register

This function will read the value of a numeric setting that may have been previously set.

06 - Write Holding Register

Used to set a numeric value to a specific register.

16 - Write Multiple Holding Register

Used to set multiple numeric registers.


The data register in the message will contain any additional information the device might need to execute the function. Typically, the data register will contain the slave register address, the number of registers to modify, and any write data from the master. 



The slave will respond to directly addressed messages—the response will echo the function code if the message was received correctly. If, however, there was an error in the message, the slave device will respond with the function code and the most significant bit set to 1. 

For example, if the function code to read the holding registers is sent (0000 0011), the error response will be 1000 0011 with a unique error code in the data field. 

VFD serial ports with RS-232 and RS-485 use Modbus

Figure 5. Most drives in the Rockwell (Allen-Bradley) PowerFlex series can use Modbus. Image used courtesy of PLC City


Modbus Implementation Example 

Rockwell and Allen Bradley have a product line of VFDs called PowerFlex. Some of these drives use Modbus to monitor and control the VFD. 

The PowerFlex 4 uses an RS485 network and Modbus protocol to monitor and control the drive using only holding register functions. Always refer to the device’s manual for mapping and memory register layout. 

The address 8192 (decimal) can be used to control the drive. This address is a holding register with 16 bits (2 bytes, or 1 word). We need to use the binary numbers to address individual bits within the two bytes. If we want to set the start bit on, then our binary number would be 0000 0010 which is hex 00 02. This same register can be used to control acceleration and declaration rates along with jogging and clearing faults. To start the motor, our protocol data unit will be as follows:





Function Code

Starting Address

Value to Write


To read the status bits of the drive, we can use the function code for reading holding register function code 03 to memory register 8448 (decimal) and set the number of bytes to read as one. According to the manual, there are 16 bits (2 bytes) in the status memory register. Our protocol data unit will be as follows:





Function Code

Starting Address

Number of Bytes


Provided there are no errors, our return message will have the same function code, and in the data section of the message, there will be the number of bytes returned and then the resulting bytes we requested to read. If we convert our returned hex value into binary, we can map each bit of the binary number to a status bit of the drive.

For devices that do not need to update their values or status very often, or manufacturers that would like to take advantage of the open protocol flexibility, the Modbus protocol is a flexible and simple protocol to use. 

Featured image used courtesy of Nuttapon