Modbus for City Slickers

I like the movie City Slickers. I think it appeals to me because we are always searching for meaning in our lives. I think that very few of us are really content. We have regrets, opportunities we missed, people we lost for one reason or another – and we always wonder “If…”

If you haven’t seen the movie, it’s about three friends who are always going on adventures; parachuting, running with the bulls in Spain, and other exotic exploits. On a cattle drive, the old cowboy Curly (Jack Palance) tells Mitch (Billy Crystal) the secret of life. He says “It’s one thing. Just one thing.” When Billy Crystal asks what that one thing is, Curly tells him “that you need to figure it out for yourself.” And when Mitch discovers it, life is meaningful for him again. It’s a great movie.

I don’t know about the secret of life, but I do know what the key is to understanding Modbus, DeviceNet, Profibus, EtherNet/IP, ProfiNet IO, and every other protocol. And that’s the data representation. If you understand the data representation for a protocol, you’re 80% of the way to understanding what that communications protocol does and how it does it.

In the case of Modbus (and like everything else about Modbus), the data representation is pretty simple. In fact, data is represented more simply in Modbus than in any other industrial protocol you’ll ever find.
There are only two data types in Modbus: coils and registers.

Coils:
Coils are simply single bits. The bits can be ON (1) or they can be OFF (0). Some coils represents inputs, meaning they contain the status of some physical discrete input. Or they represent outputs, meaning that they hold the state of some physical discrete output signal.

Registers:
Registers are simply 16-bit unsigned register data. Registers can have a value from 0 to 65535 (0 to FFFF hexadecimal). There is no representation for negative values, no representation for values greater than 65535, and no representation for real data like 200.125.

Applications can impose these representations on registers. For example, a register can treat two registers, the first containing 200 and the second containing 125, as 200.125. Or an application can group four registers and place a 64-bit IEEE floating point bit pattern in those registers. Any application can organize and treat register data in any way it may want, but there is no way for any other Modbus device to automatically know what that representation is. A Modbus application that reads registers from a Modbus Slave device must have some prior knowledge of how particular registers are treated to process them correctly.

Registers are grouped into Input Registers and Holding Registers. Like Input Coils, Input Registers report the state of some external input as a value between 0 and 65535. The original intent of an Input Register was to reflect the value of some analog input. It is a digital representation of an analog signal like a voltage or a current. Most Modbus devices today are not I/O devices, and Input Registers simply function identically to Holding Registers.

Holding Registers were originally designed as temporary program storage for devices like Modbus controllers. Today, Holding Registers function as data storage for devices.

Both Modbus registers and coils are addressed with the first register or coil as Address 1 and the last as Address 65536. That means that there can be up to 65536 (10000 Hex) Input Registers, 65536 Output Registers, 65536 Input Coils and 65536 Status Coils, but most devices use far fewer. Often you will find no coils in a device, and sometimes as few as 10 Holding Registers.
A lot of novice Modbus users find the address space notation used in Modbus confusing. Modbus includes the address space type with the index in the address space. The typical address space notation used in Modbus follows:

0x is Status Coil Address Space from 00000 to 065535

1x is Input Coil Address Space from 10000 to 165535

3x is Input Register Address Space from 30000 to 365535

4x is Holding Register Address Space from 40000 to 465535

So, when you see a notation that some value is at Modbus Register 40010, you know that the value is stored in a Holding Register at offset 10, the 11th value, in the Holding Register area of the device. The reason that this is important is that there are specific Modbus functions that operate on specific areas of the address space. There is a read Holding Register command that always reads registers in the 4x address space. There is a Write Single Coil Register that only writes coils in the 0x address space.

What’s important to note about this data addressing is that the coil addressing is specifying bit addresses, while register addresses specify 16-bit unsigned integer values. Input Coil address 2 is a bit address. It’s the third bit of the coil address space. Input Holding Register address 2 is the address of a 16-bit value. It’s the third value of the Holding Register address space.

Other than some awkward notation that is a left over from the era when Modicon Inc. designed the protocol, the Modbus data representation is very simple and straightforward. When a Modbus device is designed, the designer makes a decision of not only how many registers or coils are needed, but also which address space to use (Input Coil, Status Coil, Input Register, Holding Register) and where in that address space to locate those values. A designer may have only 10 bits of coil data and 2 registers. Those bits and registers can be located anywhere in the Modbus address space.

That example points to one of the deficiencies of this data representation. There are no standards. There is no way to communicate any meta-data to the user of the device. If the value of register 40100 is a temperature, there is no standard way to communicate the meaning of register 40100 and how to interpret the data. The user has no information to know if a value of 1001 means 100.1 degrees or 10.01 degrees or 1001 degrees.

And there is no standard regarding device profiles. Another temperature controller may store its temperature at 40200 and use a completely different data interpretation.

The Modbus data representation is simple and almost standards-free and that makes it easy to compare every other networking technology to Modbus. Modbus is most assuredly not the meaning of life, but it sure provides a basis for understanding the one important key to understanding network communications.