Almost every week I support someone using Modbus communications in one form or another. And when I say one form or another, I truly mean that. Modbus is not a single protocol but a family of protocols. There’s Modbus ASCII, Modbus RTU, and Modbus TCP and maybe even more, but those are the ones I am most familiar with.
I cannot say that I am a guru on Modbus, but I can certainly attest to dozens, if not hundreds of hours setting up and using this protocol. Mostly I have used it in two forms, Modbus RTU and Modbus TCP. For the rest of this article, I am going to be pulling information from https://modbus.org/ for the technical details. This is a great resource and I highly recommend visiting that page, especially https://modbus.org/specs.php.
The original Modbus standard as I understand it was developed by Modicon in 1979. It is a typical client/server communication protocol much like most other industrial protocols, however this protocol has become an Open protocol, meaning that it is free to use and therefore has been widely adopted by many companies.
Obviously, back in 1979, the Internet as we know it today did not exist and so the original Modbus specification worked over an RS-485 multi-drop serial network with one client and many server stations on a network. In this version, each client needed a station number. All clients needed to talk synchronously, so they had to share a common baud rate (bus speed) and agree on all the various details to avoid collisions on the network.
As Ethernet hardware developed and it became a predominant communication network for PCs, it worked its way into Industrial hardware and Factory Automation as well. With this change of hardware, Modbus TCP was developed to take advantage of a network that was becoming increasingly popular and readily available so that custom wiring and hardware solutions would no longer be required. Since Modbus TCP rides on top of the TCP/IP stack, it can co-exist with other Ethernet traffic quite nicely and rarely bogs down a network.
These days we are getting more and more accustomed to seemingly instantaneous data, available exactly when we want it, and when we need it. But not all data needs to be provided that quickly, and Modbus, plain and simply put, is not a fast protocol. It is a polled protocol whereby the Client will request data cyclically, often this is in the range of 100ms to 500ms. This is not unlike many other protocols, but it certainly is more apparent with Modbus. So, when using Modbus communications in your application, be aware that the polling rate is not terrifically fast. Furthermore, if you need deterministic feedback from sensors or devices, Modbus is probably not the preferred network; whether it is RS-485 or Ethernet, it does not really change.
So, what can you do with Modbus and why would I continue to use a 40+ year old communication protocol? Simply put – because it works!
The protocol really has not changed significantly since I started using it in April of 2000. It is a stable, while sometimes frustrating to set up, protocol that once configured seems to be rock solid and stable. I believe that comes down to the fact that most people only implement the basics. For Modbus, this consists of reading and writing two types of data: bits and registers.
The most common commands that I see used are the following:
Read Coils – Modbus Command 01 (Hexadecimal 0x01)
Read Discrete Inputs – Modbus Command 02 (Hexadecimal 0x02)
Read Holding Registers – Modbus Command 03 (Hexadecimal 0x03)
Read Input Registers – Modbus Command 04 (Hexadecimal 0x04)
Write Single Coil – Modbus Command 05 (Hexadecimal 0x05)
Write Single Register – Modbus Command 06 (Hexadecimal 0x06)
Write Multiple Coils – Modbus Command 15 (Hexadecimal 0x0F)
Write Multiple Registers – Modbus Command 16 (Hexadecimal 0x10)
Basically, when a Client sends a request to a Server, it is sending one of these commands, the command is followed by the details such as the coil/register number and how many devices. If we are sending any data, that is obviously included in the packet as well.
There are more commands than this and not every manufacturer implements every command code, so you need to read through their documentation to see which command codes they have implemented and any restrictions that may exist. For instance, when reading and writing multiple coils or registers, there is often a maximum number of registers that can be read or written at a time.
This all is easy so far - Client, Server, Address (station number or IP), command codes… no problem, but this is when it can get tricky. Not everyone seems to agree on how coil and register numbers work.
From https://en.wikipedia.org/wiki/Modbus we find the following table:
The issue becomes that not everyone starts their address space at 1, some people start at 0. So, sometimes you will ask for register or bit number 1 and get bit number 2. There was even an older standard that only used 4 digits for address, so 4,001 not 40,001 was the first holding register.
So, whenever I first set up Modbus communications, I will do a test. I will first get Holding Registers reading and writing and I often just ask for a single register and I choose 40,001. Why? Because if you are zero based (so you start at 40,000 instead of 40,001) you should still have this register and if you are 1 based then it would be the first register and not the second. I will then fill in values on both sides and see if I get back the data I expect. Then, I make a note of any offsets and I know that it will work from here on out for this setup.
The last couple of things to understand about Modbus is that there is no concept of strings, or floating-point values. These are data types that consume multiple consecutive 16-bit registers. So simply map your data into multiple consecutive registers and decode it on each side of the transfer. Which leads us to the final tip – decoding the data. Unfortunately, just like register addressing and 0 vs 1 start, not everyone agrees on the order of bytes within a register. Some manufacturers prefer high-byte order and some prefer low-byte order. If you get a value but the bytes seem reversed from what you expect, check the communications setup. Often there is a checkbox or a switch for inverting byte order. If not, you may have to do this manually.
Hopefully, this article can help you get started with Modbus. It has been around for a long time and will continue to be used because it simply works, but unfortunately it doesn’t always work simply!