0% found this document useful (0 votes)
8 views

Modbus

Uploaded by

AngoNews On-line
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
8 views

Modbus

Uploaded by

AngoNews On-line
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 32

MODBUS PROTOCOL

Ashkan Sedighi,
November 2023
What Is the Modbus Protocol?, Protocol Data Unit, Application Data Unit,
New Function Codes, Network Layers, ADU Modifications, Modbus Message
Patterns, Reliability of Modbus Interactions, Unsolicited Communication,
Network Control and Determinism, Tag-Oriented Communication and Data
Organization, Network Utilization, Security Considerations, Application or
Library, Request Scheduling, Type Availability, Modbus Using NI OPC Servers,
Modbus Using I/O Servers, Modbus Using Low-Level APIs, Benefits and
Drawbacks of Modbus,
What is the Modbus Protocol & How Does It Work?
Overview
Modbus is an industrial protocol that was developed in 1979 to make communication
possible between automation devices. Originally implemented as an application-level
protocol intended to transfer data over a serial layer, Modbus has expanded to include
implementations over serial, TCP/IP, and the user datagram protocol (UDP). This document
provides an in-depth view of the protocol implementation.

What Is the Modbus Protocol?


Modbus is a request-response protocol implemented using a master-slave relationship. In a
master-slave relationship, communication always occurs in pairs—one device must initiate a
request and then wait for a response—and the initiating device (the master) is responsible
for initiating every interaction. Typically, the master is a human machine interface (HMI) or
Supervisory Control and Data Acquisition (SCADA) system and the slave is a sensor,
programmable logic controller (PLC), or programmable automation controller (PAC). The
content of these requests and responses, and the network layers across which these
messages are sent, are defined by the different layers of the protocol.

Figure 1. A Master-Slave Networking Relationship

Layers of the Modbus Protocol


In the initial implementation, Modbus was a single protocol built on top of serial, so it could
not be divided into multiple layers. Over time, different application data units were
introduced to either change the packet format used over serial or to allow the use of TCP/IP
(Transmission Control Protocol/Internet Protocol( and user datagram protocol (UDP)
networks. This led to a separation of the core protocol, which defines the protocol data unit
(PDU), and the network layer, which defines the application data unit (ADU).

Protocol Data Unit


The PDU and the code that handles it comprise the core of the Modbus Application
Protocol Specification. This specification defines the format of the PDU, the various data

1
concepts used by the protocol, the use of function codes to access that data, and the
specific implementation and restrictions of each function code.

The Modbus PDU format is defined as a function code followed by an associated set of
data. The size and contents of this data are defined by the function code, and the entire
PDU (function code and data) cannot exceed 253 bytes in size. Every function code has a
specific behavior that slaves can flexibly implement based on their desired application
behavior. The PDU specification defines core concepts for data access and manipulation;
however, a slave may handle data in a way that is not explicitly defined in the specification.

Accessing Data in Modbus and the Modbus Data Model


Modbus-accessible data is stored, in general, in one of four data banks or address ranges:
coils, discrete inputs, holding registers, and input registers. As with much of the
specification, the names may vary depending on the industry or application. For example,
holding registers may be referred to as output registers, and coils may be referred to as
digital or discrete outputs. These data banks define the type and access rights of the
contained data. Slave devices have direct access to this data, which is hosted locally on the
devices. The Modbus-accessible data is generally a subset of the device’s main memory. In
contrast, Modbus masters must request access to this data through various function codes.
The behavior of each block is described in Table 1.

Master
Memory Block Data Type Slave Access
Access
Coils Boolean Read/Write Read/Write
Discrete Inputs Boolean Read-only Read/Write
Holding Registers Unsigned Word Read/Write Read/Write
Input Registers Unsigned Word Read-only Read/Write
Table 1. Modbus Data Model Blocks

These blocks give you the ability to restrict or permit access to different data elements and
also to provide simplified mechanisms at the application layer to access different data types.

The blocks are completely conceptual. They may exist as separate memory addresses in a
given system, but they may also overlap. For example, coil one may exist in the same
location in memory as the first bit of the word represented by holding register one. The
addressing scheme is entirely defined by the slave device, and its interpretation of each
memory block is an important part of the device’s data model.

2
Data Model Addressing
The specification defines each block as containing an address space of as many as 65,536
(216) elements. Within the definition of the PDU, Modbus defines the address of each data
element as ranging from 0 to 65,535. However, each data element is numbered from 1 to n,
where n has a maximum value of 65,536. That is, coil 1 is in the coil block at address 0, while
holding register 54 is at address 53 in the section of memory that the slave has defined as
holding registers.

The full ranges allowed by the specification are not required to be implemented by a given
device. For example, a device may choose not to implement coils, discrete inputs, or input
registers and instead only use holding registers 150 through 175 and 200 through 225. This
is perfectly acceptable, and invalid access attempts would be handled through exceptions.

Data Addressing Ranges


Although the specification defines different data types as existing in different blocks and
assigns a local address range to each type, this does not necessarily translate into an
intuitive addressing scheme for the purposes of documentation or understanding a given
device’s Modbus-accessible memory. To simplify the discussion of memory block locations,
a numbering scheme was introduced, which added prefixes to the address of the data in
question.

For example, rather than referring to an item as holding register 14 at address 13, a device
manual would refer to a data item at address 4,014, 40,014, or 400,014. In each case, the
first number specified is 4 to represent holding registers, and the address is specified using
the remaining numbers. The difference between 4XXX, 4XXXX, and 4XXXXX depends on the
address space used by the device. If all 65,536 registers are in use, 4XXXXX notation should
be used, as it allows for a range from 400,001 to 465,536. If only a few registers are used, a
common practice is to use the range 4,001 through 4,999.

In this addressing scheme, each data type is assigned a prefix as shown in Table 2.

Data Block Prefix


Coils 0
Discrete Inputs 1
Input Registers 3
Holding Registers 4
Table 2. Data Range Prefixes

3
Coils exist with a prefix of 0. This means that a reference of 4001 could refer to either
holding register one or coil 4001. For this reason, all new implementations are
recommended to use 6-digit addressing with leading zeros, and to note this in the
documentation. Thus, holding register one is referenced as 400,001 and coil 4001 is
referenced as 004,001.

Data Address Start Values


The difference between memory addresses and reference numbers is further complicated by
the indexing selected by a given application. As mentioned previously, holding register one
is at address zero. Typically, reference numbers are one-indexed, meaning that the start
value of a given range is one. Thus, 400,001 translates literally to holding register 00001,
which is at address 0. Some implementations choose to start their ranges at zero, meaning
that 400,000 translates to the holding register at address zero. Table 3 demonstrates this
concept.

Address Register Number (1-indexing, Number (0-indexing,


Number standard) alternative)
0 1 400001 400000
1 2 400002 400001
2 3 400003 400002
Table 3. Register Indexing Schemes

One-indexed ranges are common and strongly recommended. In either case, the start value
for each range should be noted in documentation.

Large Data Types


The Modbus standard supplies a relatively simplistic data model that does not include
additional data types outside of an unsigned word and bit value. Although this is sufficient
for some systems, where the bit values correspond to solenoids and relays and the word
values correspond to unscaled ADC values, it is insufficient for more advanced systems. As a
result, many Modbus implementations include data types that cross register boundaries.
The NI LabVIEW Datalogging and Supervisory Control (DSC) Module and KEPServerEX both
define a number of reference types. For example, strings stored in a holding register follow
the standard form (400,001) but are followed by a decimal, the length, and the byte
ordering of the string (400,001.2H, a two-character string in holding register 1 where the
high byte corresponds to the first character of the string). This is required because each
request has finite size, and so a Modbus master must know the exact bounds of the string
rather than searching for a length or delimiter like NULL.

4
Bit Access
In addition to allowing access to data that crosses a register boundary, some Modbus
masters support references to individual bits within a register. This is beneficial as is allows
devices to combine data of every type in the same memory range without having to split
binary data into the coil and discrete input ranges. This is usually referenced using a decimal
point and the bit index or number, depending on the implementation. That is, the first bit in
the first register may be 400,001.00 or 400,001.01. It is recommended that any
documentation specify the indexing scheme used.

Data Endianness
Multi register data, like single-precision floating point value, can be easily transferred in
Modbus by splitting the data across two registers. Because this is not defined by the
standard, the endianness (or byte order) of this split is not defined. Although each unsigned
word must be sent in network (big-endian) byte order to satisfy the standard, many devices
reverse the byte order for multibyte data. Figure 2 shows an unusual but valid example of
this.

Figure 2. Byte Order Swap for Multiword Data

It is up to the master to understand how the slave is storing information in memory and to
decode it properly. It is recommended that documentation reflect the word order used by
the system. Endianness can also be added as a system configuration option, with underlying
encode and decode functions, if flexibility in implementation is required.

Strings
Strings can be easily stored in Modbus registers. For simplicity, some implementations
require that string lengths be multiples of two, with any additional space filled with null
values. Byte order is also a variable in string interactions. String format may or may not
include a NULL as the final value. As an example of this variability, some devices may store
data as shown in Figure 3.

5
Figure 3. Byte Order Reversal in Modbus Strings

Understanding Function Codes


In contrast to the data model that can vary significantly from device to device, function
codes and their data are defined explicitly by the standard. Each function follows a pattern.
First, the slave validates inputs like function code, data address, and data range. Then, it
executes the requested action and sends a response appropriate to the code. If any step in
this process fails, an exception is returned to the requestor. The data transport for these
requests is the PDU.

The Modbus PDU


The PDU consists of a one-byte function code followed by up to 252 bytes of function-
specific data.

Table 4. The Modbus PDU

The function code is the first item to be validated. If the function code is not recognized by
the device receiving the request, it responds with an exception. Should the function code be
accepted, the slave device begins decomposing the data according to the function
definition.

Because the packet size is limited to 253 bytes, devices are constrained on the amount of
data that can be transferred. The most common function codes can transfer between 240
and 250 bytes of actual data from the slave data model, depending on the code.

6
Slave Function Execution
As defined by the data model, different functions are defined to access different conceptual
blocks of data. A common implementation is to have codes access static memory locations,
but other behaviors are available. For example, function code 1 (read coils) and 3 (read
holding registers) may access the same physical location in memory. In contrast, function
code 3 (read holding registers) and 16 (write holding registers) may access completely
different locations in memory. Thus, the execution of each function code is best considered
as part of the slave data model definition.
Regardless of the actual behavior performed, all slave devices are expected to follow a
simple state diagram for each request. Figure 4 shows an example of this for code 1, read
coils.

Figure 4. Read Coils State Diagram From the Modbus Protocol Specification

Each slave must validate the function code, the number of inputs, the starting address, the
total range, and the execution of the slave-defined function that actually performs the read.
Although static address ranges are shown in the state diagram above, the needs of real-
world systems can cause these to vary somewhat from the defined numbers. In some cases,
slave devices cannot transfer the maximum number of bytes defined by the protocol. That
is, rather than allowing a master to request 0x07D0 inputs, it can only respond with 0x0400.

7
Similarly, a slave data model may define the range of acceptable coil values as address 0
through 500. If a master makes a request for 125 starting at address 0, this is OK, but if a
master makes the same request starting at address 400, the final coil will be at address 525,
which is out of range for this device and would result in exception 02 as defined by the state
diagram.

Standard Function Codes


The definition of each standard function code is in the specification. Even for the most
common function codes, there are inevitable mismatches between the functions enabled on
the master and what the slave can handle. To address this, early versions of the Modbus TCP
specification defined three conformance classes. The official Modbus Conformance Test
Specification does not reference these classes and instead defines conformance on a per-
function basis; however, they can still be convenient for understanding. It is recommended
that any documentation follow the test specification and define their conformance by which
codes they support, rather than by the legacy classifications.

Class 0 Codes
Class 0 codes are generally considered the bare minimum for a useful Modbus device, as
they give a master the ability to read from or write to the data model.

Code Description
3 Read Multiple Registers
16 Write Multiple Registers
Table 5. Conformance Class 0 Codes

Class 1 Codes
Class 1 function codes consist of the other codes necessary to access all of the types of the
data model. In the original definition, this list included function code 7 (read exception).
However, this code is defined by the current specification as a serial-only code.

Code Description
1 Read Coils
2 Read Discrete Inputs
4 Read Input Registers
5 Write Single Coil
6 Write Single Register
7 Read Exception Status (serial-only)
Table 6. Conformance Class 1 Codes

8
Class 2 Codes
Class 2 function codes are more specialized functions that are less commonly implemented.
For example, Read/Write Multiple Registers may help reduce the total number of request-
response cycles, but the behavior can still be implemented with class 0 codes.

Code Description
15 Write Multiple Coils
20 Read File Record
21 Write File Record
22 Mask Write Register
23 Read/Write Multiple
Registers
24 Read FIFO
Table 7. Conformance Class 2 Codes

Modbus Encapsulated Interface


The Modbus encapsulated interface (MEI) code, function 43, is used to encapsulate other
data within a Modbus packet. At present, two MEI numbers are available, 13 (CAN open)
and 14 (Device Identification).

Function 43/14 (Device Identification) is useful in that it allows for the transfer of up to 256
unique objects. Some of these objects are predefined and reserved, such as vendor name
and product code, but applications can define other objects to transfer as generic data sets.

This code is not commonly implemented.

Exceptions
Slaves use exceptions to indicate a number of bad conditions, from a malformed request to
incorrect inputs. However, exceptions can also be generated as an application-level
response to an invalid request. Slaves do not respond to requests issued with an exception.
Instead, the slave ignores incomplete or corrupted requests and begins waiting for a new
incoming message.
Exceptions are reported in a defined packet format. First, a function code is returned to the
requesting master equal to the original function code, except with its most significant bit
set. This is equivalent to adding 0x80 to the value of the original function code. In lieu of the
normal data associated with a given function response, exception responses include a single
exception code.

9
Within the standard, the four most common exception codes are 01, 02, 03, and 04. These
are shown in Table 8 with standard meanings by each function.

Table 8. Common Modbus Exception Codes


Exception
Meaning
Code
The received function code is not supported. To confirm the original function
01
code, subtract 0x80 from the returned value.
The request attempted to access an invalid address. In the standard, this can
02 happen only if the starting address and the requested number of values exceeds
216. However, some devices may restrict this address space in their data model.
The request had incorrect data. In some cases, this means that there was a
parameter mismatch, for example between the number of registers sent and the
“byte count” field. More commonly, the master requested more data than either
03
the slave or protocol allows. For example, a master may read only 125 holding
registers at a time, and resource-limited devices may restrict this value to even
fewer registers.
An unrecoverable error occurred while attempting to process the request. This is a
04 catchall exception code that indicates the request was valid, but the slave could
not execute it.

The state diagram for every function code should cover at least exception code 01 and
usually includes exception code 04, 02, 03, and any other defined exception codes are
optional.

Application Data Unit


In addition to the functionality defined at the PDU core of the Modbus protocol, you can
use multiple network protocols. The most common protocols are serial and TCP/IP, but you
can use others like UDP as well. To transmit data necessary for Modbus across these layers,
Modbus includes a set of ADU variants that are tailored to each network protocol.

Common Features
Modbus requires certain features to provide reliable communication. The Unit ID or Address
is used in each ADU format to provide routing information to the application layer. Each
ADU comes with a full PDU, which includes the function code and associated data for a
given request. For reliability, each message includes error-checking information. Finally, all
ADUs provide a mechanism for determining the beginning and end of a request frame, but
implements these differently.

10
Standard Formats
The three standard ADU formats are TCP, remote terminal unit (RTU), and ASCII. RTU and
ASCII ADUs are traditionally used over a serial line, while TCP is used over modern TCP/IP or
UDP/IP networks.

TCP/IP
The TCP ADUs consists of the Modbus Application Protocol (MBAP) Header concatenated
with the Modbus PDU. The MBAP is a general-purpose header that depends on a reliable
networking layer. The format of this ADU, including the header, is shown in Table 9.

Table 9. The TCP/IP ADU

The data fields of the header indicate its use. First, it includes a transaction identifier. This is
valuable on a network where multiple requests can be outstanding simultaneously. That is, a
master can send requests 1, 2, and 3. At some later point, a slave can respond in the order 2,
1, 3, and the master can match the requests to the responses and parse data accurately. This
is useful for Ethernet networks.

The protocol identifier is normally zero, but you can use it to expand the behavior of the
protocol. The length field is used by the protocol to delineate the length of the rest of the
packet. The location of this element also indicates the dependency of this header format on
a reliable networking layer. Because TCP packets have built-in error checking and ensure
data coherency and delivery, packet length can be located anywhere in the header. On a
less inherently reliable network such as a serial network, a packet could be lost, having the
effect that even if the stream of data read by the application included valid transaction and
protocol information, corrupted length information would make the header invalid. TCP
provides a reasonable amount of protection against this situation.

The Unit ID is typically unused for TCP/IP devices. However, Modbus is such a common
protocol that many gateways are developed, which convert the Modbus protocol into
another protocol. In the original intended use case, a Modbus TCP/IP to serial gateway
could be used to allow connection between new TCP/IP networks and older serial networks.
In such an environment, the Unit ID is used to determine the address of the slave device
that the PDU is actually intended for.

11
Finally, the ADU includes a PDU. The length of this PDU is still limited to 253 bytes for the
standard protocol.

RTU
The RTU ADU appears to be much simpler, as shown in Table 10.

Table 10. The RTU ADU

Unlike the more complex TCP/IP ADU, this ADU includes only two pieces of information in
addition to the core PDU. First, an address is used to define which slave a PDU is intended
for. On most networks, an address of 0 defines the “broadcast” address. That is, a master
may send an output command to address 0 and all slaves should process the request but no
slave should respond. Besides this address, a CRC is used to ensure the integrity of the data.

However, the reality of the situation in more modern implementations is far from simple.
Bracketing the packet is a pair of silent times—that is, periods where there is no
communication on the bus. For a baud rate of 9,600, this rate is around 4 msec. The
standard defines a minimum silence length, regardless of baud rate, of just under 2 msec.

First, this has a performance drawback as the device must wait for the idle time to complete
before the packet can be processed. More dangerous, however, is the introduction of
different technologies used for serial transfer and much faster baud rates than when the
standard was introduced. With a USB-to-serial converter cable, for example, you have no
control over the packetization and transfer of data. Testing shows that using a USB-to-serial
cable with the NI-VISA driver introduces large, variably sized gaps in the data stream, and
these gaps—periods of silence—trick specification-compliant code into believing that a
message is complete. Because the message is not complete, this usually leads to an invalid
CRC and to the device interpreting the ADU as being corrupted.

In addition to issues with transmission, modern driver technologies abstract serial


communication significantly and typically require a polling mechanism from the application
code. For example, neither the .NET Framework 4.5 Serial Port Class nor the NI-VISA driver
provide a mechanism for detecting silence on a serial line except by polling the bytes on the
port. This results in a sliding scale of poor performance (if polling is performed too slowly)
or high CPU usage (if polling is performed too quickly).

12
A common method for addressing these issues is to break the layer of abstraction between
the Modbus PDU and the networking layer. That is, the serial code interrogates the Modbus
PDU packet to determine the function code. Combined with other data in the packet, the
length of the remaining packet can be discovered and used to determine the end of the
packet. With this information, a much longer time-out can be used, allowing for
transmission gaps, and application-level polling can occur much more slowly. This
mechanism is recommended for new development. Code that does not employ this may
experience a larger than expected number of “corrupted” packets.

ASCII
The ASCII ADU is more complex than RTU as shown in Figure 8, but also avoids many of the
issues of the RTU packet. However, it has some of its own disadvantages.

Table 11. The ASCII ADU

Resolving the issue of determining packet size, the ASCII ADU has a well-defined and
unique start and end for each packet. That is, each packet begins with “:” and ends with a
carriage return (CR) and line feed (LF). In addition, serial APIs like NI-VISA and the .NET
Framework Serial Port Class can easily read data in a buffer until a specific character—like
CR/LF—is received. These features make it easy to process the stream of data on the serial
line efficiently in modern application code.

The downside of the ASCII ADU is that all data is transferred as hexadecimal characters
encoded in ASCII. That is, rather than sending a single byte for the function code 3, 0x03, it
sends the ASCII characters “0” and “3,” or 0x30/0x33. This makes the protocol more human-
readable, but also means that twice as much data must be transferred across the serial
network and that the sending and receiving applications must be capable of parsing the
ASCII values.

Extending Modbus
Modbus, a relatively simple and open standard, can be modified to suit the needs of a given
application. This is most common for communication between an HMI and PLC or PAC, as
this is a situation in which a single organization has control over both endpoints of the
protocol. Developers of sensors, for example, are more likely to adhere to the written
standard because they typically only control the implementation of their slave, and
interoperability is desirable.

13
In general, modifying the protocol is not recommended. This section is merely provided as
an acknowledgment of the mechanisms that others have used to adjust the behavior of the
protocol.

New Function Codes


Some function codes are defined, but the Modbus standard does allow you to develop
additional function codes. Specifically, function codes 1 through 64, 73 through 99, and 111
through 127 are public codes that are reserved and guaranteed to be unique. The remaining
codes, 65 through 72 and 100 through 110, are for user-defined use. With these user-
defined codes, you can use any data structure. Data can even exceed the standard 253 byte
limit for the Modbus PDU, but the entire application should be validated to ensure that
other layers work as expected when the PDU exceeds the standard limit. Function codes
above 127 are reserved for exception responses.

Network Layers
Modbus can run on many network layers besides serial and TCP. A potential implementation
is UDP because it is suited to the Modbus communication style. Modbus is a message-
based protocol at its core, so UDP’s ability to send a well-defined packet of information
without any additional application-level information, like a start character or length, makes
Modbus extremely simple to implement. Rather than require an additional ADU or reuse an
existing ADU, Modbus PDU packets can be sent using a standard UDP API and be received
fully formed on the other end. Although TCP is advantageous for some protocols because of
the built-in acknowledgement system, Modbus performs acknowledgement at the
application layer. However, using UDP in this way does eliminate the transaction identifier
field in the TCP ADU, which rids the possibility of multiple simultaneous outstanding
transactions. Therefore, the master must be a synchronous master or the UDP packet must
have an identifier to help the master organize requests and responses. A suggested
implementation would be to use the TCP/IP ADU on a UDP network layer.

ADU Modifications
Finally, an application could choose to modify an ADU, or use unutilized portions of an
existing ADU like TCP. For example, TCP defines a 16-bit length field, a 16-bit protocol, and
an 8-bit unit ID. Given that the largest Modbus PDU is 253 bytes, the high byte of the length
field is always zero. For Modbus/TCP, the protocol field and unit ID are always zero. A simple
extension of the protocol might send three packets simultaneously by changing the
protocol field to a non-zero number and using the two unused bytes (unit ID and the high
byte of the length field) to send the lengths of two additional PDUs (see Table 12).

14
Table 12. Sample Modification of the TCP ADU

Application Development with Modbus


Why Modbus?
Modbus is open, common, relatively easy to use, and has few restrictions in its application;
however, it has its shortcomings. In many cases, a user has no choice but to use it because
of hardware constraints such as existing sensors or other devices that must talk over
Modbus. Whether you must use Modbus or have many options, you should understand the
benefits and restrictions inherent to the protocol.

If Modbus is right for the job, then it’s important to know how to use it. What are the
options for implementing it? How should you design an application to take advantage of
this protocol?

Protocol Selection and Design Considerations


The Modbus application layer is implemented as a request-response, master-slave design
for transmitting single-point data across various networking layers. This fundamental design
works well, but has its drawbacks for some applications.

Modbus Message Patterns


Modbus is a request-response protocol for interaction between Supervisory Control and
Data Acquisition (SCADA) systems and automation devices. For every request sent, the
target device should respond. There is one response for every request. In addition, requests
frequently originate from a single source and target a single device. These systems can be
characterized by containing a client device that generates a request and waits on the
response and a server device that parses the requests from the client, handles them, and
then returns a response (see Figure 9). Modbus terminology frequently refers to the client as
the master, as it is usually the SCADA host, and refers to the server as the slave. The slave is
commonly a sensor or automation controller.

15
Figure 5. A Request-Response/Client-Server Model

Reliability of Modbus Interactions


The Modbus messaging pattern is similar to the one defined by HTTP. An advantage of this
pattern is that it does not require an extremely reliable network layer. If the client (or
master) sends a request and does not receive a reply, it knows that something has gone
wrong and can resend the request. Using the HTTP analogy, this would be equivalent to
clicking the refresh button on a web browser. If you repeatedly send requests and don’t get
a response back from the server, you may think that the server is down and temporarily stop
trying to access it. This is similar to the behavior exhibited by some OPC servers such as
KEPServerEX and NI OPC Servers when Modbus communication is lost. Although this does
not protect against loss of control, it does ensure that master devices know when control is
lost and gives them the ability to take appropriate action, such as engaging a failsafe or
using a redundant device to maintain control. This is not true for the slave, or server.

Because of the requirement that all requests come from the master device, an intelligent
slave does not have a reliable indication that communication has been lost. If the slave
receives no requests, it could mean that the network is down, the master is down, or that
the master has decided to stop sending requests. This lack of reliable status information can
be resolved in different ways, but a system developer should understand the necessity.

A common solution to this problem is for devices to have a watchdog timer. If a request is
not received within a designated time frame, the slave device assumes that something has
failed and enter a safe state. Depending on the device and the particular application, this
may be beneficial or detrimental to the overall control of the system.

The simple watchdog solution has limitations, namely that it only confirms that requests are
being received. You can use schemes of increasing complexity, but a commonly used simple
and effective approach is to implement a register-level heartbeat. If the device supports it or
if you are developing a new device from the ground up, this approach ensures constant
communication between a master and slave at the application level. That is, if the control

16
code on the master is responsible for changing the heartbeat value and the control code on
the slave is responsible for reading it, the heartbeat value represents a simple test that
confirms normal system function. System functionality from the master control code
through the networking layers and all the way up to the slave’s control loop are verified by
this register-level heartbeat test. Another register, modified on the slave and read on the
master might also be used to indicate communication in the other direction.

Figure 6. A Simple Heartbeat Implementation

Unsolicited Communication
The nature of this master-slave architecture also means that Modbus slaves cannot provide
data unsolicited to a master. Although the master can implement an event-based
architecture to send data to the slave, it must continuously poll the slaves at a defined rate
to retrieve new data. This requires significant overhead if changes are limited, both in terms
of network bandwidth and in master CPU utilization.

In the use case of frequently updating information (for example, from a temperature
sensor), this design works well. Because this data varies constantly, polling at an application-
defined rate makes sense. In contrast, a slowly updating data element such as an alarm bit
or a status physical switch is more effectively monitored by waiting for a value change to
occur and only updating the master when such a change occurs. Modbus, nevertheless,
requires that each value be polled periodically.

Network Control and Determinism


This inability of the slave to send unsolicited data to a master does mean that Modbus
offers a level of control over the network that some applications require. In a fragile
network, a request-response protocol can ensure that the master is the only device that can
determine when communication occurs on the network. If configured correctly, this means

17
that the master can eliminate network packet collisions and ensure a higher level of
determinism.

This can also have more general benefits for a control system in that network
communication is always at a steady state. If event-based information were transmitted
across the network by any slave, it would introduce jitter into the system. Although this may
be acceptable for some applications, using a strict polling mechanism for data transfer
reduces this risk.

Tag-Oriented Communication and Data Organization


Modbus data is oriented around the concept of tags, or variables. These data elements—
holding registers, input registers, coils, and discrete inputs—are called by different names
within the protocol, but the idea is the same. These tags are data elements that can be
written to or read from at any time, but provide only their current value. This makes sense
for many applications; however, implementing concepts like events, messages, or first-in-
first-out memory buffers (FIFOs) can be difficult.

Modbus defines four banks of data—the four types mentioned above—that store the vast
majority of the information transported by the protocol. Each request from a master can
perform a single operation on a single bank of data. That is, a single request can read from
the coils bank or write to the coils bank, but not both. There are exceptions, however. For
example, function code 23 allows a master to write holding registers and read holding
registers in a single request/response cycle. However, this is not a commonly implemented
function code. Both master and slave device documentation should be checked to verify
whether this function code is available.

It is also critical to understand that data in a given bank can only be accessed sequentially,
and up to the packet size limit of the Modbus protocol. This limit is typically about 240 to
250 bytes of payload data, but depends on the specific function used. This makes it
extremely important to carefully design the register banks.

For example, a given application may require the transfer of significant amounts of data at a
fast rate. In this case, minimizing the number of requests required is desirable. Because data
must be accessed sequentially, it would make sense for this application to concentrate as
much data as possible in a single bank of registers and to pack data together with the
minimum number of unused data elements.

Another application may have a more complex slave that allows for some local control. In
this situation, there may be some data that is read at a fast rate and some data that is

18
monitored periodically. In this case, data should be grouped by transfer rate. The quickly
updating data should be concentrated in one place, while slowly updating data should be
organized into different blocks to make it easier for a single request to read or update a
particular data set.

To demonstrate, consider a set of five quickly updating data values (F1-F5) and five slowly
updating values (S1-S5). In addition, S1, S2, and S3 correspond to one code module while
S4 and S5 correspond to another code module—that is, they may be updated at different
times. In Figure 11, the ideal organization for this case gives the master the ability to read
the quickly updating data in a single request and then, as needed, read the other slowly
updating data sets.

Table 13. Well-Organized Data

If care is not taken, a data set could easily be organized as shown in Table 13. In this case,
it’s moved from a little over 20 requests per second to over 80 requests per second. It is
actually more efficient for a small data set to read everything in a single block. However,
these approaches quickly become unscalable for a complex system.

19
Table 14. Poor Data Organization

Tag Numbering
Although internally, data in each Modbus bank is accessed using an address value from 0 to
65,535, it is more common for documentation to refer to data elements using a common
addressing scheme. In such a scheme, the address of the data element is prefixed by a
number that defines the bank to be accessed. Table 8 shows these prefixes.

Data Block Prefix


Coils 0
Discrete Inputs 1
Input Registers 3
Holding Registers 4
Table 15. Data Access Prefixes

Depending on the particular documentation being referenced, addressing starts at either


zero or one and uses a fixed width of between four and six values. That is, different
documents could all refer to the same integer holding register as 4005, 40004, and 400005.
The documentation should define the particular addressing scheme used, and any new
system development should publish this information.

20
Network Utilization
Request-response protocols do not necessarily make the best use of network bandwidth.
Although a request from the master to read a particular piece of data certainly needs a
response, a request to write data does not. However, Modbus application protocol requires
that a response be sent to every request. This means that a full Modbus packet must be
formed, including protocol data, application data, and any required network data. It also
means that the process of requesting data and receiving it in a response can take
significantly longer than simply broadcasting the data would require, due to network
latency, slave processing time, and any network collisions or interference.

This is exacerbated further by the data organization considerations outlined above. If data is
poorly organized within the Modbus memory space, the number of required request-
response cycles can increase dramatically. Because of latency considerations, there is a finite
rate at which request-response cycles can occur, even without network interference. As a
result, reducing the number of requests required for interaction between a master and slave
is one of the most significant ways to improve system performance.

Security Considerations
The Modbus protocol provides little to no security. In the past, the confined nature of
industrial networks meant that a physical security breach was necessary to infiltrate the
network. As networks become more interconnected, security is becoming a more serious
concern. In recent years, various schemes have been formulated for securing Modbus
protocol communication. However, these schemes generally break compatibility with
existing Modbus networks and devices.

Implementation Considerations
The overall utility of a given system also varies depending on the specific driver
implementation chosen. Typically, Modbus masters are integrated into an application either
through a library or through a stand-alone tool like an OPC server. In contrast, a Modbus
slave is usually integrated into a device using some sort of library or developed as part of
the device firmware. In either case, it is important to understand the variety of
implementations available to make the choice most appropriate for a given application.

Application or Library
Typically, an application like KEPServerEX or NI OPC Servers is more fully featured than a
library, but offers less control. For example, both OPC server applications can be configured
to provide specific data elements at a specific rate and both can convert the raw Modbus
data into a defined data type. They are limited however in that you cannot directly generate
and send a Modbus request—all requests go through the application and configuration

21
options are limited. A library, in contrast, typically provides raw data and requires you to
initiate all requests. This offers flexibility and gives you tight control over all traffic.

Request Scheduling
In either the case of an application or library implementation, some piece of the overall
system is responsible for scheduling requests and determining the format of those requests.
Generally, implementations take one of two forms. The first possibility would be to require
that all requests and responses occur in sequence. This synchronous design approach is a
common choice as the code is simple to write and is network agnostic, but it can
significantly underutilize a TCP/IP network. In a synchronous design, the master must
perform the following operations: generate a request, send the request across the network,
wait for the server to have time to process the request and generate a response, wait for the
response to traverse the network, and finally process that response—all before generating
another request. For a sufficiently slow slave device or network layer, this round-trip time
can be significant.

The alternative is an asynchronous design, in which one process on the master is


responsible for generating requests while another process is responsible for receiving
responses and routing those responses internally to the code that needs the data. This
design is much more efficient because multiple requests can be outstanding on the network
at once, but it requires both that the slave has a large enough buffer in memory to handle
the incoming requests and that the developer of the master implementation invest
significantly more resources to the problem. Figure 7 demonstrates the difference between
these two messages passing schemes. Each arrow to the right indicates a request, while
each arrow to the left indicates a response.

Figure 7. Synchronous Versus Asynchronous Message Passing

Some applications such as KEPServerEX and NI OPC Servers split the difference and
implement a threading scheme that offers some of the benefits of both implementations.
That is, tags and devices can be organized such that all requests occur synchronously, in a

22
single thread, or they can be organized into different threads. In this case, all tags in a given
thread are requested synchronously, but multiple devices may be accessed in parallel. This
maintains fairly tight control over the network while improving the overall performance of
the system.

Type Availability
Modbus is flexible in part because it enforces almost no restrictions on data in the system.
Instead, system data consists of up to four blocks of up to 65,635 word-sized registers or
Boolean elements. Data can be stored in elements of either type—U16 or Boolean—or it can
be stored as sub register values, or as data that crosses the boundaries of multiple registers.

Unfortunately, this flexibility does not imply usability. Just as with TCP and serial, where data
is transferred as a stream of bytes, application code using Modbus is required to format that
data in a way that makes sense to the rest of the system. For example, the conversion of
data from the 32 bits that make up the first and second register to a single-precision
floating point value is entirely up to the application code. To make things more confusing,
the ordering of this data is undefined by the protocol. It defines those registers are
transferred across the network in network (big-endian) order, but various devices handle the
cross-register boundaries differently.

This situation is important to consider in all implementations, as there may be variability


across different devices. A library typically provides raw data in the form of registers,
meaning that you have to reform data as needed for your application. If a library provides
typed data, the documentation should be consulted to understand the expected format. In
contrast, an application typically takes some of the variability into account. For example,
KEPServerEX and NI OPC Servers give you the ability to switch the endianness of
multiregister data types on a per-device basis. If this option is not exposed, you may have to
implement it yourself and treat registers as raw data.

Addressing
As discussed previously, addressing in Modbus is complicated because of the variety of
schemes used. Although the specification strictly defines an addressing scheme (that is,
holding register number five is read by requesting address 0x04 with function code 0x03),
devices typically convert this information into a single number. Documentation from
different sources may use the same number to refer to different values. It is critical that this
be considered when using either a standard library or an application.

23
Typically, a library does not provide abstractions to convert from a common addressing
scheme, like “400005,” into a request for the data stored by holding register five. Some
libraries, especially those that contain type support, may.

In contrast, OPC servers and other applications are more likely to use the more general
addressing scheme. Applications like NI OPC Servers and KEPServerEX even provide options
to cover many of the permutations in addressing schemes (indexing that starts at zero or
one, for example). However, these applications may still have unusual requirements—
especially when it comes to interpreting registers as different data types—and application
documentation should always be referenced to ensure that data is transferred and
interpreted correctly.

Selecting a Modbus Implementation and Architecture


If Modbus is selected as the protocol of choice for an application, NI offers three primary
tools for Modbus communication. At the lowest level, a variety of different API libraries are
available. These libraries usually provide both master and slave support. The NI LabVIEW
Datalogging and Supervisory Control (DSC) and LabVIEW Real-Time modules provide a tool
called the Modbus I/O server, which provides some of the flexibility and ease of use of a
low-level library. I/O servers also provide master and slave support. Finally, NI OPC Servers is
a fully functioning OPC server that can include driver support for Modbus masters.

Modbus Using NI OPC Servers


NI OPC Servers is a stand-alone, fully featured OPC server application that can be the
backbone of a SCADA system. Like all OPC servers prior to the release of OPC UA, NI OPC
Servers is a Windows-only program, and as such is best suited to use as a supervisory
system rather than a system for high-speed control of slave devices. NI OPC Servers
provides a large set of drivers to allow communication not only with Modbus devices, but
with devices using a wide range of vendor-specific protocols or standard protocols like OPC
UA. A typical system would look something like Figure 8.

24
Figure 8. This typical SCADA application uses a set of Modbus TCP/IP devices and an NI OPC Servers host.

Like many OPC servers, NI OPC Servers has facilities to handle large data types, endianness
settings on a per-device basis, request scheduling facilities, and many more features to
abstract away some of the low-level details of Modbus. After data is in the application, it can
be transferred using OPC or OPC UA to loggers, human machine interfaces (HMIs), or other
Windows applications.

Modbus Using, I/O Servers


The Modbus I/O servers included in LabVIEW provide a middle ground between the easy-
to-use range of OPC servers and the powerful low-level libraries that give full control over
the protocol. Like an OPC server, I/O servers allow a simple, configuration-based interface
for communicating with a Modbus device. Like an OPC server, I/O servers include their own
request scheduling system and handle many of the low-level caveats in Modbus, like data
endianness. However, I/O servers do offer a simple interface in LabVIEW and give programs
the ability to quickly and easily access either processed data (the single-precision floating
point value at registers 45 and 46) or the raw data (the unsigned 16-bit integer at register
45). Like an OPC server, I/O servers are typically used in applications where supervisory
control is important, while distributed microcontrollers are responsible for the high-speed
control in the system.

25
Modbus Master I/O Server
I/O servers can be thought of as a basic OPC server running inside your application. In
typical use, the Modbus master I/O server is deployed as part of an application, and then
that application is directly responsible for passing data to an HMI or to a database. In some
cases, this level of developer involvement reduces the usability of the final system—a full
OPC server is more scalable. However, for smaller systems it makes perfect sense to
eliminate the OPC middleman and create a single simple application to handle everything.

Figure 9. A Sample Control Application Using a Modbus Master I/O Server

Modbus Slave I/O Server


Just as with the I/O server master, slave servers should also be used for only supervisory
control. Because the I/O server is a background process, user code has no way of knowing
when a request has been received. This makes I/O servers best suited to applications in
which a more powerful piece of hardware, like a PAC, is used to handle most control with
occasional low-priority updates from a central hub. In such an application, Modbus data in
the I/O server would be scanned in every iteration of a control loop and used to make
decisions, but that data would not be used for critical communication (like an E-stop).

26
Figure 10. A Sample Modbus Slave I/O Server Application

Modbus Using Low-Level APIs


Many low-level Modbus drivers exist in several languages. The LabVIEW 2014 DSC and
LabVIEW 2014 Real-Time modules and later provide a low-level Modbus API to complement
the features of NI OPC Servers and Modbus I/O servers.

With these drivers, you can explicitly define what happens when a Modbus request is sent or
received. They also usually offer a higher maximum performance than higher level drivers. In
exchange, you typically must write a lot of the data processing code, which allows your
application to interact effectively with other devices in the system. The functionality and
behavior of this code varies depending on whether the device is a master or a slave.

Figure 11 demonstrates how a low-level master, the LabVIEW Modbus API, provides tight
control over the specific requests sent and the timing of those requests.

27
Figure 11. A low-level master controls the timing and content of a read request.

Low-Level Master
When used as a master, a high-performance PAC using a low-level Modbus driver can be
used to effectively control a system that requires high speed and reliability. Because
requests are generated directly by the application code, any failures are also reported and
known immediately, allowing the system to enter a safe state or take corrective action.

In addition, the application has tight control over exactly when data is transmitted, which
allows the application code to effectively use network bandwidth. Rather than scanning
everything at the same rate, different rates can be used for different slave devices. If
necessary, the application could even use entirely different network paths (two TCP
connections, different serial lines) to meet the performance requirements of the application.

Figure 18 depicts a sample application where the developer has chosen to develop a low-
speed event-based supervisory loop, similar to what you might have in a Windows-based
SCADA system. In a parallel process, a deterministic control loop is used to communicate
with a pump at a high speed.

28
Figure 12. This NI Compact RIO PAC sample application uses a low-level Modbus master driver.

In addition, because these low-level drivers are so flexible, you can use them to recreate
some of the features of a high-level interface, like an I/O server, while still maintaining
control over the priorities that are so critical to the behavior of the system. In this sample
application, a communications loop has been developed that handles the scheduling of all
requests and responses in a way that suits the specific needs of the application. A
deterministic control loop can then be written with knowledge of when new data is available
from the communications loop, giving many of the benefits of the first system without
potential drawbacks from communications faults.

Figure 13. This custom control application moves communications to a secondary loop to reduce the impact
of communication faults while maintaining the performance requirements of the system.

29
Low-Level Slave
Because of the difficulties of handling the server side of a request-response protocol directly
in application code, many Modbus slave implementations provide a background process
that handles responding to master requests. This is similar in principle to the behavior of I/O
server slaves.

However, in a low-level driver, it is typical and expected that application code can adjust the
behavior of this process to suit the needs of the system. In some cases, low-level slaves
provide an event that application code can handle. This gives you the ability to immediately
respond to incoming data from the master without having to poll for changes in device
memory.

Figure 14. This low-level slave driver uses events to indicate data changes in a shared data model.

In more advanced cases, the low-level driver may be written in such a way that application
code can be injected directly into the data model of the slave API. Thus, rather than simply
reading from a memory location, the slave may be able to respond to master requests in an
application-specific way. This allows for many of the benefits provided by the low-level
master, without having to write a server in application code.

30
Figure 15. This low-level slave application uses a custom data model to directly interact with deterministic
control code in a system-specific way.

Benefits and Drawbacks of Modbus


Benefits

▪ Commonly used, with many implementations available


▪ Flexible
▪ Freely available specification
▪ Request-response architecture provides application-level acknowledgement

Drawbacks

▪ Request-response underutilizes network or complicates application code


▪ High network overhead
▪ Limited packet size increases overhead and decreases maximum poll rate
▪ Streaming data is difficult or impossible
▪ No native type support outside of unsigned 16-bit integers and single bits
▪ No built-in security features
▪ Requires polling architecture

Modbus is and will continue to be a commonly used protocol in spite of the number of new
technologies introduced in recent years. Although it has limitations that you should be
aware of, it’s simple and flexible nature makes it an excellent choice for some designs.

31

You might also like