Modbus – A Quick Introduction

General InformationModbus

This article is for those of you getting started with Modbus and would like a quick introduction. After reading, you’ll be proficient in the Modbus protocol, and you’ll have enough knowledge to implement Modbus on any platform. We’ll keep things simple, and we’ll be sure to use layman’s terms.

What is it?

Modbus is a communication protocol developed to allow computers to share data with each other in real time. It was originally created in 1979 by a company called Modicon, which is now owned by Schneider Electric. It became extremely popular throughout the years because Modicon openly published the protocol specifications with no royalty fees, thereby allowing device manufacturers to incorporate Modbus into their products free of charge. Dozens of years later, it’s still one of the most used industrial communication protocols.

Overview

Clients and Servers

Like most communication protocols, there is a client (sometimes called a master) and a server (sometimes called a slave). The client sends a request to the server, the server processes the request, and then the server issues a response to the client. In most applications, the client is a SCADA system that’s gathering data from a programmable logic controller (PLC). The PLC is the server. The SCADA system will periodically (i.e. every 5 seconds) send a request to the PLC asking for data stored in the PLC’s memory. The PLC will respond with the requested data, and then the SCADA system can display it for the user. Here’s a quick diagram illustrating the concept:

The 3 Types of Modbus

There are 3 different types of Modbus, and Modbus users must be aware of them. However, the architects of Modbus worked hard to keep the foundation of all 3 protocols the same, so the programmers don’t really need to concern themselves too much with the differences. You really just need to know which one to use based on the application you’re implementing. The 3 types of Modbus are Modbus RTU, Modbus ASCII, and Modbus TCP/IP.

Modbus RTU

Modbus RTU was designed for serial communications. It’s used when the client and server are connected via RS232, RS422, or RS485. Its standard specifies things like serial communication settings (parity, stop bits, …). It also defines a device addressing scheme so multiple devices can be connected in the same serial network and distinguish who is being spoken too.

Modbus ASCII

Just like Modbus RTU, Modbus ASCII was designed for serial communications as well. The standard is almost identical to Modbus RTU, with the only difference being data encoding. When Modbus RTU sends data, everything is transmitted as raw binary bits. This is very efficient, however difficult to troubleshoot when viewing data being transmitted. Modbus ASCII sends data as text based characters, which makes things easier to read. However, the drawback is that ASCII requires roughly 2 times the amount of data to be transmitted. It’s recommended to only use Modbus ASCII while troubleshooting and stick to Modbus RTU for production applications.

Modbus TCP/IP

Modbus TCP/IP is used when the client and server are communicating via a TCP/IP network like Ethernet. This is extremely common in today’s world of controls. The protocol specifies additional pieces of information that must be included in Modbus messages to work in a TCP/IP network.

Functions

The client can send several different “types” of requests to the server. The “type” of request sent is chosen based on what the client wants the server to do. For example, if the client wants to read data in the server, the client would send a “read” request. Alternatively, maybe the client wants to update some data in the server. In this case, the client would send a “write” request along with the data to be written. These request “types” are known in the Modbus protocol as functions. Modbus has 21 different functions, each with a special purpose. Most of the time, only 8 of those functions are used and the other 14 are for special use cases. Later on in this article, we’ll provide a breakdown of the 8 most common functions and how to use them.

Data Model

To allow a client to specify what data it wants to read/write in the server, the server maps all its data into “addressable locations” called registers. That way, the client can say “send me the data you’re holding in registers 1-7” or “write 1234 to registers 3-6”. The Modbus data model specifies exactly how the server will organize data into registers.

The data model specifies four types of registers which are described below. Due to the age of the protocol, the names likely won’t have much meaning to modern controls engineers, so it’s recommended to disregard the names and focus mostly on the descriptions:

Register TypeDescriptionAllowed ValuesRegister Bit SizeModbus Client Permissions
Input DiscreteHolds values received by PLC digital input channels“On” or “Off”1Read only
CoilHolds values sent to PLC digital output channels“On” or “Off”1Read and write
Input RegisterHolds values received by PLC analog input channels0-6553516Read only
Holding RegisterHolds values stored in PLC memory0-6553516Read and write


To explain how these register types are used, let’s go through a quick hypothetical example.

Example

Say you’re a PLC programmer and the PLC you’re working on has 4 digital inputs, 4 digital outputs, 2 analog inputs, and 2 setpoints. You’d like the inputs/outputs of the PLC to be visible to a connected SCADA system, and the SCADA system must be able to adjust the setpoints in the PLC.

To accomplish this, you’ll need to map the data points (inputs, outputs, and setpoints) to Modbus registers in the PLC. You can then configure the SCADA system to send read/write requests to the appropriate registers. Let’s start by mapping each PLC data point to a Modbus register as shown below:

Register TypeRegister AddressPLC Data Point
Input Discrete1Digital Input 1
Input Discrete2Digital Input 2
Input Discrete3Digital Input 3
Input Discrete4Digital Input 4
Coil1Digital Output 1
Coil2Digital Output 2
Coil3Digital Output 3
Coil4Digital Output 4
Input Register1Analog Input 1
Input Register2Analog Input 2
Holding Register1Setpoint 1
Holding Register1Setpoint 2


As side note, please be aware that many PLC’s utilize something known as a “Modbus prefix”. Instead of listing the register type, a number corresponding to the register type is prefixed in front of the register address. Common convention is that input discrete has a prefix of 1, coil has a prefix of 0, input register has a prefix of 3, and holding register has a prefix of 4. This convention is not actually part of the Modbus standard, but it is heavily utilized by the Modicon line of PLCs. Using the Modbus prefix convention, the Modbus register map can be rewritten as follows.

Register AddressPLC Data Point
1×1Digital Input 1
1×2Digital Input 2
1×3Digital Input 3
1×4Digital Input 4
0x1Digital Output 1
0x2Digital Output 2
0x3Digital Output 3
0x4Digital Output 4
3×1Analog Input 1
3×2Analog Input 2
4×1Setpoint 1
4×1Setpoint 2


Please keep in mind, there’s more than one approach to use when setting up a Modbus register map. Instead of using Modbus register addresses 1-4 for the digital inputs, I could have chosen 2, 4, 6, and 8. Generally speaking, selecting addresses is arbitrary and does not matter. However, for performance reasons that’s out of the scope of this article, it’s best to avoid spacing registers apart. This degrades communication performance.

Modbus Function Codes

Now that you understand what Modbus functions are, and how they’re used to interact with registers in the server, let’s get into the details of the 8 most popular Modbus functions.

Read Coils (Code 01)

A Modbus client uses this function to read the values of coil registers within the Modbus server. The parameters included by the Modbus client when sending this request are below:

  1. Starting address
  2. Quantity of registers

The Modbus server responds with a list of the requested coil values. The list will contain the quantity of registers requested, and the first item in the list will be the value at the start address.

Read Discrete Inputs (Code 02)

A Modbus client uses this function to read the values of discrete input registers within the Modbus server. The parameters included by the Modbus client when sending this request are below:

  1. Starting address
  2. Quantity of registers

The Modbus server responds with a list of the requested discrete input values. The list will contain the quantity of registers requested, and the first item in the list will be the value at the start address.

Read Holding Registers (Code 03)

A Modbus client uses this function to read the values of holding registers within the Modbus server. The parameters included by the Modbus client when sending this request are below:

  1. Starting address
  2. Quantity of registers

The Modbus server responds with a list of the requested holding register values. The list will contain the quantity of registers requested, and the first item in the list will be the value at the start address.

Read Input Registers (Code 04)

A Modbus client uses this function to read the values of input registers within the Modbus server. The parameters included by the Modbus client when sending this request are below:

  1. Starting address
  2. Quantity of registers

The Modbus server responds with a list of the requested input register values. The list will contain the quantity of registers requested, and the first item in the list will be the value at the start address.

Write Single Coil (Code 05)

A Modbus client uses this function to write a coil value within the Modbus server. The parameters included by the Modbus client when sending this request are below:

  1. Coil address
  2. Coil value

The Modbus server responds by echoing the request back to the client.

Write Single Register (Code 06)

A Modbus client uses this function to write a holding register value within the Modbus server. The parameters included by the Modbus client when sending this request are below:

  1. Holding register address
  2. Holding register value

The Modbus server responds by echoing the request back to the client.

Write Multiple Coils (Code 15)

A Modbus client uses this function to write multiple coil values within the Modbus server. The parameters included by the Modbus client when sending this request are below:

  1. Starting address
  2. Quantity of registers
  3. List of coil values

The Modbus server responds by sending the starting address and quantity of coils that were written too.

Write Multiple Holding Registers (Code 16)

A Modbus client uses this function to write multiple holding register values within the Modbus server. The parameters included by the Modbus client when sending this request are below:

  1. Starting address
  2. Quantity of registers
  3. List of holding register values

The Modbus server responds by sending the starting address and quantity of holding registers that were written too.

Introducing SimServe by SCADAmatic