Modbus Register Address Decrements by 1


Thread Starter

Joe O

I’ve been involved in working with various industrial communication networks for the past twenty years or so. One of the protocols I deal with is Modbus RTU. When interfacing with 3rd party devices, I know that the register addresses have to be incremented by one to be properly transmitted. For example, if I want to a read a register at 40100, I must set the register address to 40101 and it works just fine. If I data capture the actual transmitted register address, it is 40100. I’ve been to the Modbus web sites, and they mention this also, but they do not give an explanation. I’m just curious why the address decrements by one. Does anybody know?

This "issue" occurs simply because Modicon (Schneider) PLC models do not support an address of "0" (Zero) for any of the datatypes. Third party users of Modbus protocol typically do not impose this address restricition in their design.

We (Schneider) have no problem with this when doing Modbus with Modicon to Modicon apps.

A similar issue occurs when using the JBUS protocol.

Peter Nachtwey

Yes, registers 400001 to 465536 are mapped to 0 to 65535 when sent over Modbus RTU. Your statement about register 40100 and 40101 is not correct or a manufacturer screwed thing up. If you want to read a register at 400100 then you ask the number encoded in the Modbus packet will be 99. The 4xxxxx is implied by the Modbus function. It just selects an address space. Modicon PLC registers start with 1. Modbus registers start with 0.

Jonathan P Blanchard

The issue that you are experiencing is due to how different devices handle addressing. For example:

The TSX Quantum from Schneider Electric has a Modbus port therefore supports the protocol Modbus. Addressing in the TSX Quantum begins with 1. ie 400001. Most other third party field devices that support Modbus don't use this 4x register scheme but instead just refer to their addressing as words. These words typically begin at zero and work there way up. So if the TSX Quantum is trying to read register 400001 from a field device thats addressing starts at zero, the TSX Quantum is actually reading word 0.

400001 => 0
400002 => 1

So in your case, in order to read word 100 from the field device, you have to tell the TSX Quantum to request register 400101.
I think part of this problem stems simply from numbering and addressing
systems. Many PLCs and devices allow for addresses of 0, while the Modicon does not. So I think that's the way you accomodate the fact that the first address in the Modicon memory is 1, not 0. Ex. 40001 is first data register. Maybe other device is expecting 40000 to be first address. Now I'm not sure, I've only got about one year with Modicon devices, but that's my best guess.


Greg Goodman

It's not that the address decrements by one; it's that you must convert from user-friendly register numbering to the programmer-friendly address specification defined by the protocol.

Most of us use the human-friendly format, in which the first digit signifies the data type and the rest of the reference is a 1-based item number of that type. Thus, the first holding register is at address 40001.

The protocol defines an address specification as a 0-based reference to an item whose type is implied by the function code. Thus, a Modbus RTU message to read from the first holding register specifies function code 3 (read holding register) and item 0 (the first item in the range).

If you're asking why the protocol is defined that way, I can't answer for the guys who made the decision, but I can say that it's a common (and reasonable and defensible) programming decision to start numbering from zero. Programming languages typically define the first element of an array as zero; specifying addresses from zero makes determining array indexes and calculating memory offsets trivial. It also obviates the need to check for an illegal zero value. If a numbering scheme uses unsigned integers and starts from one, then zero is either an illegal address or has a special meaning. In either case, it needs to be trapped every time the address is referenced.

Of course, it is the responsibility of programmers to protect end users from this sort of arcana. People who write programs in which end users must specify Modbus addresses typically provide the necessary translation invisibly. The user gets to use the familiar convention, and the program builds corresponding correct protocol messages.

Hope this helps,
Greg Goodman
Chiron Consulting

Jerry Miille

Because that is what the specification says to do.
From the spec:
"coils are numbered from zero; (coil number 1 = zero, coil number 2 = one,
coil number 3 = two, etc.)"
You will find that not all Modbus implementations adhere to this specification. It is not at all unusual to find that a read for the first register or coil requires the number in the message to be one, not zero. It is best to allow either format with a user defined switch to select one method or the other.

Jerry Miille
I was curious about this when I first ran against it as well. The only reasoning I was able to find is that some people like to think of the first device as "device1" at "addr1". Others (often those with C/C++ backgrounds)
like to think in terms of 0-indexed arrays and so think of the first device as "device0" at "addr0". 1-based is more convenient for hardware, 0-based for software.

Some packages will allow you to set the "address offset" while others won't even mention that they use one.

It is often easiest when dealing with a new package to set discrete outputs in the 1st 3 positions and try to activate output "#1". That will readily show you any address offset.

Brian Lawry
Mfg Software Engineer
Compressor Controls Corporation
[email protected] <mailto:[email protected]>
"It may be warriors who get the glory,
but it's the engineers that build societies."
---Chief Engineer B'Elanna Torres,
ST:Voy episode Flesh and Blood, Part 2

Toni Kaesbeck

It all comes from 4xxxx "holding and output register" as they were on
early MODICON PLC's.
The MODBUS protocol is used to read/write those and the protocol defines
to read/write the offset address from the first register 40001 with
40001 being an offset of 0 (read zero)
40101 being an offset of 100

This applies to 0xxxx, 1xxxx, 3xxxx as well.
There are many links to MODBUS docu in the archive of this list.
See the original GOULD MODICON spec on this!