You're likely to come across the term Modbus when you're searching for industrial control modules. Various sensors use Modbus, VFD, actuator control, and PLC, particularly in the oil & gas and agricultural industry.
If you're not familiar with Modbus, choosing industrial modules and setting them up can be challenging. You could be overwhelmed by the various registers and struggle to communicate with a Modbus device.
Modbus is, thankfully, relatively simple technology, and we've put together everything you should know about Modbus in this comprehensive guide.
Let’s start with a simple Modbus definition.
Modbus is what you’ll call a communication protocol built for industrial controllers. It enables industrial controllers or PLCs to communicate with sensors, actuators, HMIs, and other modules used in instrumentation and control. Almost every integrable industrial device supports Modbus.
Modbus is a half-duplex, serial digital communication protocol. It works perfectly with the popular communication medium for industrial controllers, which is RS485. RS485 enables Modbus communication over long distances. Modbus is also compatible with other serial communication interfaces, such as RS232 and RS422.
Here's how the Modbus story started.
It all began in 1979 when Modicon, now Schneider Electric, built a protocol to make communication easier for its range of PLCs. Modbus is an application layer protocol, which means that it’s independent of the electrical medium of transfer. The Modbus standard covers the format, fields, and transmission sequence of the Modbus frame.
Today, the Modbus Organization manages the protocol. The de-facto industrial protocol has evolved throughout the decades. Initially, there were two types of Modbus protocol — Modbus RTU and Modbus ASCII. With the emergence of ethernet networking, Modbus TCP was introduced to leverage the connection-based nature of TCP protocol.
You would have thought a protocol that spans over 40 years would have been rendered obsolete. Not with Modbus. It remains the most common protocol used by modern industrial systems. Modbus is such a hit with industrial engineers, equipment manufacturers, and PC programmers for a few reasons.
Modbus is an open-source protocol. Thus, manufacturers can incorporate the protocol into their industrial products without paying royalty fees. Incorporating Modbus into a controller is also reasonably straightforward. It’s a matter of adding the Modbus driver into the controller’s firmware.
Modbus has an advantage over the direct connection of switches (input) and solenoids (output) in terms of wiring. Modbus only takes a pair of twisted cables for an RS485 connection, while a direct link will require as many wiring connections for the individual I/O.
Given that cabling cost is always on the rise, it makes sense to opt for Modbus.
You’ll never get a more straightforward protocol than Modbus. It provides read/write operation on an industrial device’s coil, status, input registers, and holding registers, mapped to a range of addresses.
Programming skills are not needed to operate a Modbus-featured controller. The concept of writing and reading from coils and registers is easy to comprehend. With the aid of a visual interface, system engineers can set up and control Modbus-operated devices without any programming skills.
Over the decades, Modbus has matured into a large ecosystem of industrial control products. As a result, PLC programmers and system engineers are accustomed to working with Modbus.
There isn’t a growing need for a different form of protocol. Unlike consumer applications, industrial controls do not need streaming megabytes of data in real-time. Existing Modbus infrastructures are unlikely to undergo drastic changes even with technology upgrades.
Modbus simplifies data acquisition and output control for an industrial controller. A Modbus connection requires a master controller and at least one slave device. The master controller sends Modbus commands, and slave devices respond with data or acknowledgment.
Modbus can’t have more than one master controller. Doing so will result in corrupted data packets when multiple controllers try to send commands simultaneously on the Modbus network.
Modbus replaces individual connections to I/O modules. As such, it retains familiar terms like coils and inputs in its data representation. All Modbus protocols share the same data types, which are allocated to specific addresses.
Here’s how Modbus data types are represented:
Modbus Data Type | Read/Write | Format | Address Range (Dec) |
Coil | R/W | 1 bit | 00001-09999 |
Discrete Input | Read-only | 1 bit | 10001-19999 |
Input Register | Read-only | 16 bit | 30001-39999 |
Holding Register | R/W | 16 bit | 40001-49999 |
Fig 1 - Modbus Data Type
The coil data type will be typically associated with a solenoid output or solid-state relays. Discrete inputs are often flow switches, limit switches, or other single-bit digital inputs. Input registers are similar to discrete inputs, except that it returns a 16-bit data.
The holding register is a read/write storage that can be used for various purposes—for example, writing and reading parameter configuration on a Modbus actuator. In addition, the holding register can be used to set parameters like maximum torque, alarms, relay contact, fail-safe measures by writing the appropriate 16-bit data variable.
The next question lies in how a Modbus data packet is transferred between master and slave devices. The following diagram of a typical Modbus message frame gives a clearer picture.
Modbus message frame |
Start |
Device ID |
Function Code |
Register Address |
Register Count |
Data |
Checksum |
End |
Fig 2 - Modbus Message Frame
The above message frame is valid for Modbus RTU and Modbus ASCII. In Modbus TCP, the Checksum and End fields are removed, and the Start field is replaced with a 6- byte overhead. We’ll explain the differences between these protocols in the next section.
Each Modbus message frame is wrapped by a start and end field. It allows the receiving unit to segregate different data packets.
The Device ID indicates the recipient of the Modbus message. The device ID ranges from 1 to 247, but the limit differs based on the transmission medium. Most industrial systems run on RS485, which allows up to 32 connected devices. If you’re using RS232, you’ll have a maximum of 2 devices. Running Modbus on TCP will expand the device count, subjected to the network switches and gateways.
The core of Modbus lies in the Function Code, Register Address, and Data. They are also known as the Protocol Data Unit (PDU). These fields provide specific instruction to Modbus slaves on what information needs to be retrieved, written, and where they are located.
These are standard function codes supported by industrial Modbus devices.
Function Code (Dec) | Function |
1 |
Read Coil |
2 |
Read Discrete Input |
3 |
Read Holding Registers |
4 |
Read Input Registers |
5 |
Write Single Coil |
6 |
Write Single Holding Register |
15 |
Write Multiple Coils |
16 |
Write Multiple Holding Registers |
Fig 3 - Modbus Function Codes
So, how does data get moved around in a Modbus connection?
Modbus communication always starts with a master controller sending a request to a slave device. It can be a write or read request, depending on the function code selected in the message frame.
The controller specifies the register address, register count, and data written on the Modbus PDU for a written request. A read request has a similar format, minus the data field.
When a slave device successfully processes a request, it’ll return an acknowledgment Modbus frame to the master controller. The acknowledgment frame contains the functioned code that was executed and data if it’s a read request. If a Modbus slave fails to process the request, it’ll respond with an exception code.
There are instances where a master controller sends a request that is not supported by a slave device, or the latter experiences technical issues. In such cases, the slave device will respond with a Modbus exception code.
Exception Code | Name |
1 |
Illegal Function |
2 |
Illegal Data Address |
3 |
Illegal Data Value |
4 |
Slave Device Failure |
Industrial automation and instrumentation rely on data integrity. Measured value from the sensor must be received without alteration by the controller. The same goes from configurations sent by a controller to a Modbus device.
It will be disastrous for the data to be corrupted during transmission and processed by the devices. For example, a temperature sensor measured 24 degrees C but returned 18 degrees C because some bits got flipped during transmission.
Therefore, the Checksum in the Modbus frame is vital to ensure the data integrity of Modbus transmission.
The 2-bytes Checksum is calculated from each byte of the Device ID and PDU. It is then appended on the Modbus message. Upon receiving a Modbus frame, the recipient will compare the checksum value against the calculated Checksum based on the received packet. If there’s a mismatch between the checksum values, the device discards the Modbus data packet.
You can run it over RS232, RS485, or an ethernet cable. Each transmission medium allows different distances and speed limits. For example, you can’t go further than 50 ft. on a 9600 baud rate with RS232.
Most installations are on RS485, which works up to 4,000 feet and a speed limit of 115,200 baud. Ethernet cable provides a distance of 100 meters and the speed of the network switches.
Theoretically, Modbus RS-485 has an upper limit of 115,200 baud rate, but real-life applications rarely go beyond 19,200. Often, there isn’t a need for such a high data transfer rate, and most slave devices aren’t built to handle such a high baud rate.
Not all Modbus devices are built equal. When you’re setting up a Modbus system, you’ll need to ensure that all devices can communicate on the same protocol. Modbus RTU is the most popular protocol, but if you’re choosing a Modbus ASCII or Modbus TCP sensor, you’ll need to ensure that the master controller supports both protocols.
The protocols differ in formatting and size. So let’s take a deeper look at each protocol.
Modbus RTU Frame | Length (bits) |
Start (silence) |
28 |
Device ID |
8 |
Function Code |
8 |
Data |
n x 8 |
Checksum |
16 |
End (silence) |
28 |
Fig 5- Modbus RTU Frame
The Modbus RTU protocol transmits data in 8-bits (byte) binary format. For example, the function code of 16 is represented by a single byte 0x10 hexadecimal value. Using the Modbus RTU format allows you to send or receive data with the smallest bandwidth.
It’s interesting to point out how Modbus RTU uses a period of science to indicate the start and end of a message. Timing is crucial for a Modbus RTU device as it needs to time the silence interval to mark the end of a message frame.
Modbus ASCII Frame | Length (byte) |
Start |
1 |
Device ID |
2 |
Function Code |
2 |
Data |
n x 2 |
Checksum (LRC) |
2 |
End |
2 |
Fig 6- Modbus RTU Frame
The Modbus ASCII shares the same field types with Modbus RTU, but that's where the similarity ends. Instead of binary formatting, Modbus ASCII uses ASCII characters to encode the data into the message frame. For example, function code 16 is represented by two characters of 0x31, 0x36.
ASCII formatting also limits the device limit to 247 (0xF7). Thus, the most significant device ID on a Modbus ASCII frame is 0x46, 0x37, the ASCII values for 'F' and '7'. The same applies to the register address and data that are passed in the message body.
A 2-byte LRC checksum is calculated for error-checking and appended to the message.
Unlike Modbus RTU, Modbus ASCII uses characters to indicate the starting and ending of a message. It uses 0x3A (:) as a start character and CRLF (0x0D, 0x0A) to terminate the transmission.
The payload uses only alphanumeric characters, which means that it produces intelligible text string when monitored on a Modbus sniffer software. It's also less sensitive to timing requirements as the message starts and ends with characters.
The downside of Modbus ASCII is that it takes at least twice the size of Modbus RTU. For example, it takes 2 bytes to transfer 0x5469 in Modbus RTU, but it'll take 4 bytes to convert the value to ASCII representations of 0x35, 0x34, 0x36, 0x39.
Modbus TCP Frame | Length (byte) |
Transaction Identifier |
2 |
Protocol Identifier |
2 |
Length Field |
2 |
Unit Identifier |
1 |
Function Code |
1 |
Data Bytes |
n |
Fig 7- Modbus TCP Frame
The 1990s saw the introduction of the 10-Base-T ethernet standard and the internet going mainstream. In 1999, Modbus TCP was introduced to leverage ethernet connectivity.
TCP is a connection-based transport layer protocol on the OSI stack. It automates connection synchronization, handshaking, error checking, and packet handling. With TCP taking care of the data transfer mechanism, some of the fields in the original Modbus frame become redundant.
The Start and End bits are no longer needed, and the same goes for the checksum. Therefore, the Modbus TCP saw a revision in its data frame. The Start, Stop, and checksum were removed. They are replaced by a 6-bytes header.
What’s new in the Modbus TCP is the Transaction Identifier, which is used to determine that a request is followed by a matching response. In addition, the Protocol Identifier is set to 0, indicating TCP protocol, while the Length Field indicates the remaining byte in the data packet.
Despite sounding similar, Modbus Plus is not Modbus. Instead, it is a high-speed peer-to-peer communication protocol developed by Schneider that allows data transfer at 1 Mbps.
Modbus Plus specification includes protocol and hardware layers such as cabling and terminating connector. It involves token-passing in a flat network hierarchy, which differs from Modbus’s master-slave configuration.
We’re about to dive deeper into the workings of Modbus. Understanding how Modbus addressing and messaging works helps when you’re configuring and troubleshooting a Modbus network.
A single byte can hold up to 255 possible Device IDs. However, Modbus specifications limit the valid IDs from 1 to 247. So, if you’re sending address 0x00 or 0xF8-0xFF on a Modbus RTU frame, the data frame will be ignored.
The standard Modbus specification allocates 9,999 memory points for different data types ( coil, discrete input, input register, holding register). On a Modbus device, these data are stored in volatile and non-volatile memories.
For example, configuration values for a Modbus transducer are stored on a non-volatile memory like an EEPROM. Meanwhile, sensor values are stored and updated on an SRAM. Of course, the physical storage is abstracted for a PLC programmer. A programmer needs to know how to access the data with the address allocation of each data type.
Here’s where it gets tricky.
Modbus data frame takes in relative addresses and not absolute addresses. The absolute and relative address for the data types are as follow:
Modbus Data Type | Absolute Address (Dec) | Relative Address | Data Frame (Hex) |
Coil | 00001-09999 | 0001-9999 | 0x0000-0x270E |
Discrete Input | 10001-19999 | 0001-9999 | 0x0000-0x270E |
Input Register | 30001-39999 | 0001-9999 | 0x0000-0x270E |
Holding Register | 40001-49999 | 0001-9999 | 0x0000-0x270E |
Fig 8- Modbus Addressing
The relative address is the result of discarding the tenth-thousandth decimal from the address. For example, an input register at an absolute address at 35,468 has a relative address of 5,468.
A device receiving the Modbus frame will determine the data type from the relative address by inspecting the function code. For example, a Read Holding Register request has a function code of 04, and the device automatically translates the relative address to 35,468.
It gets trickier.
The register address sent in a Modbus frame is deducted by one from the corresponding relative address. To read a coil at an absolute address at 00100, you’ll need to send a command request with an address of 0x63 (00099) in the data frame.
Each of the data types is allocated 9,999 memory spaces. Often, they will be sufficient for most applications. However, some devices require registries exceeding the standard allocation, and that's where extended addressing comes in.
Extended addressing stretches the address limits to 65,535 (0xFFFF), which is the maximum address possible with 2-byte addressing. The Modbus protocol remains the same in fields and syntax with extended addressing. However, devices that don't support extended addressing will respond with an exception when responding to a request with a vast address range.
We wouldn’t call this a Bible of Modbus without showing what Modbus data packets look like when observed on a protocol sniffer software. Here, you’ll start piecing together what you’ve learned about Modbus and gain clarity.
Let’s consider an example where a PLC reads 1 input register 30100 from a device (ID 2)
The PLC will transmit the following sequence in Modbus RTU (Hex).
02 04 00 63 00 01 C1 E7
Request frame breakdown.
The slave device responds with the next data frame.
02 04 01 5F 27 74 DA
Response frame breakdown
The above protocol sequence is similar when you’re performing a Read Holding Register request.
Write holding register is usually used for setting configuration parameters on a Modbus device.
For example, a PLC writing 0x782A and 0xB7C3 into register 40078 and 40079 on a device (ID 3)
The request sequence will be as follow:
03 10 00 4C 00 02 78 2A B7 C3 B7 05
Request frame breakdown
When successfully executed, the device will respond with:
03 10 00 4C 00 02 81 FD
Response frame breakdown
Understanding the data frame for reading coils (and discrete inputs) is more challenging, as each of the addresses holds only 1 bit. When retrieving multiple coil values, interpreting the value requires bit-wise identification.
A PLC reading 10 coils from an address 00500 from a Device ID 4 has the following request sequence.
04 01 01 F3 00 0A 4F 97
Request frame breakdown
Assuming that coils 501 and 508 are set, the response will be as follow:
04 01 02 01 02 F5 AD
Response frame breakdown
The value of the coils returns as 0x01, 0x02. How does this correspond to the 10 coil addresses?
Modbus is a Big-Endian protocol. It means that the most significant bytes are transmitted first. Within a byte, the value starts with the most significant bit from left to right.