With the wide range of devices that use Modbus for their communication protocol, you'll find many different interpretations, terminology and labels with respect to how to access different types of data in those devices. Sometimes a device manual might only refer to the supported Modbus function codes and the range of offsets available for those function codes.
In this blog post, I will step through the specifics of Modbus function codes and how they pertain to addressing, and how they affect what addresses to use in TOP Server for Wonderware applications.
In my previous blog post Demystifying Modbus Register Addressing, I discussed how confusing Modbus addressing can be due to how different device manufacturers describe their implementations in their device manuals. I know some of you who read that post were looking for a little more depth on how specific Modbus function codes come into play.
So, in this post, I'm going to discuss the Modbus functions codes that TOP Server uses to read and write the different types of Modbus memory addresses and how they correspond to the actual addresses your client is requesting, using TOP Server for Wonderware applications as an example.
A function code (FC) in Modbus is a specific code used in a Modbus request to tell the Modbus slave device what type of memory (i.e. holding registers, input coils, etc) to access and what action to perform on that memory (i.e. reading or writing). The following table lists the specific Modbus function codes used for communicating by all of the Modbus drivers included in the TOP Server Modbus Suite:
There are also some special settings in the TOP Server Modbus drivers that allow for more flexibility for different Modbus implementations in a device that we will cover shortly.
And, though we won't go into the specifics in this post, Modbus flexibility in TOP Server goes even further with support for Modbus-variants in specific non-standard drivers such as Enron Modbus, OMNI Flow, Lufkin ELAM, Honeywell UDC, and even Yaskawa Memobus-based drivers.
As we covered last time, when we're talking about the Modbus protocol and addressing particular locations of data (or types of memory), there are generally four different types of Modbus addresses:
We also discussed last time how a lot of device documentation doesn't always provide detailed listings of Modbus addresses in terms of the type of address such as 4xxxxx or Holding Register.
So, since we're talking in more depth about Modbus function codes, it is essential that we talk about Modbus addresses in terms of the type of memory a particular address is and whether or not it can be read from and written to or only read from.
Both of those factors determine which Modbus function code will be used in sending a request to a device. Let's discuss each function code and the corresponding address and function it performs:
So, the function determines which type of memory is being accessed and whether it is a read or write operation. But function codes work together with other information in a Modbus request, including what is referred to as an offset.
TOP Server Modbus Suite drivers support the following address ranges for the different memory types:
So we support Offsets 1 to 65,536 for all memory types. But what is an offset?
The way I typically explain offsets is that you have to look at the first digit of an address (i.e. 4, 3, 1 or 0) as telling the driver which type of memory to access. Everything after the first digit is the offset - the specific memory address that you're interested in within that memory type.
This is why, as we covered in more detail in the previous blog post, an address of 4001, 40001 and 400001 are all the same - they are all requesting holding register offset 1 (and, as we covered earlier, a read request would be using Modbus function code 3 and write requests might be using Modbus function code 6 or 16, depending on your settings and what your Modbus slave device supports).
Modbus Holding Register Offsets | |||
Modbus Document Says: | TOP Server Says it Supports: | ||
4 | 001 | 4 | 00001 |
4 | 0001 | 4 | 00001 |
The Modbus function code and the offset work together in a Modbus request to tell the device a specific piece of information that should be returned or modified.
One final subtlety that is important when discussing offset-based Modbus addressing is whether a device supports zero or one-based addressing. Originally, zero-based addressing was the intended implementation with Modbus. But, as time progressed and Modbus, as an open protocol, was so widely adopted, a concept known as one-based addressed was adopted by certain device manufacturers.
Zero-based addressing involves the first offset of a memory type starting at zero. So, for instance, if you were requesting holding register 400001, the actual Modbus protocol request would be FC 3 for offset 0. And 400002 would request FC 3 for offset 1, and so on.
As you can imagine, that could be quite confusing. So some manufacturers adopted an implementation called one-based addressing. With one-based addressing, the offset is aligned with the actual address request. For instance, if you request holding register 1, the request still uses FC 3 but for offset 1. And 400002 would request FC 3 for offset 2, and so on. It is much more "user-friendly".
However, because there are some devices that support zero-based and some devices that support one-based addressing, it is important to be aware of this. TOP Server Modbus drivers have a configurable setting for specifying which implementation your Modbus slave device supports.
The default setting for "Zero-Based Addressing" is enabled, since that is the Modbus specification default. Switching this setting to disabled will result in the driver using one-based addressing. Always make sure you're using the correct setting as to not do so means the value being displayed could be for the wrong address in your device.
For example, if you read a value for 400001 and it's the "wrong" value compared to what you're expecting, look to see if it is the value of the register next to 400001. If so, you need to swap from one to zero-based addressing (or vice versa).
Additionally, there is one-based or zero-based bit addressing. By default, TOP Server Modbus drivers support zero-based bit addressing, as well, since it is the Modbus specification default. This means that bits are addressed from 0 to 15.
One-based bit addressing means that bits are addressed from 1-16 - again, what feels more natural to a human counting 16 bits. And, again, TOP Server Modbus drivers have a configurable setting for that, based on what your device supports.
As with offset addressing, the bit addressing method selected in TOP Server must match what your device supports - otherwise, if incorrect, the bit values you will be accessing will be for the wrong bits. The setting should be left enabled for 0-15 bit access or should be disabled for 1-16 bit access.
Always consult the manufacturer's documentation or speak with the manufacturer to determine which method they support. If you notice a bit is "on" but should be "off" (or vice versa), you may need to switch this setting.
As you can see, Modbus has a lot of quirks being such a well-established and widely used open protocol. A flexible Modbus master such as TOP Server provides a range of configurable settings (including swapping Byte, Word and Dword ordering, which will be covered in a future post) to work with the widest range of Modbus slave implementations regardless of manufacturer for the greatest compatible.
Don't forget to subscribe to our blog to find out about the latest updates to TOP Server and for other useful tutorials and resources as well as take a look at our other Modbus related Technical Blog posts.
Ready to put TOP Server's flexible Modbus drivers to work with your own Modbus devices?