Layout of registers, coils and inputs. Design-question


Thread Starter

Nick Mueller


Short project description:
Call me nuts, but I decided to build my own ModBus over RS232 module. Hardware is up and running. Software basically working. The module is a CPU-board with 4 ports. On each port, up to 10 (tested with 4) extenders can be connected. Each extender has (currently) 16 INs or 16 OUTs. On every port, only one breed of extenders can be connected. That would make 1600 IOs. Hahahaha!

The CPU is a 8-core 32bit RISC µC running at 80 MHz. It is fast enough to handle commands at 115kBaud without being saturated.

Now to my question:
INs and OUTs have to be mapped to registers somehow. 16INs can't have the same register address as 16OUTs. Right?

Now if I say have 100 registers, does it make sense to assign all INs starting at regsiter #1 and all OUTs starting at register #50. Or is it necessary to be able to asign INs and OUTs to registers in a "randomn pattern".

What do I do with unassigned registers? Treat them as non-existent or have them sitting around for read/write without further effects?

There are four types of Modbus memory - Coils, Discrete Inputs, Holding Registers, and Input Registers. You can have up to 65,536 of each, numbered from 0 to 65,535.

1) Digital inputs go into Modbus Discrete Inputs.
2) Digital outputs go into Modbus Coils.
3) Analogue inputs go into Modbus Input Registers.
4) Analogue outputs go into Modbus Holding Registers.

Discrete Inputs and Input Registers are read only. Coils and Holding Registers are read/write. Discrete Inputs and Coils are boolean (bit) addresses, while Input Registers and Holding Registers are 16 big integers.

I think you should read up a bit on Modbus, as more background information can help you understand it better. The spec can be found at the Modbus web site ( Look at the link at the top of the page.

As for unassigned registers in the middle of an address range, its up to you whether they exist but are unused, or whether they constitute a "hole" in the addresses. For registers that are "above" the highest used address, it is normal for them to not exist.

Mueller Nick


Yes, I have read the ModBus docs. But the layout of registers, coils, inputs has so much freedom, that it's hard to see (for me, right now) what is an good option.

My current design is like this:
There is I/O Memory that directly interfaces the hardware (the inputs and outputs). Coils can be defined to map into this I/O Memory (as long as it is for output). Inputs also map into this I/O Memory (IN-memory), and registers can also map into it. Consequently, that mapping can be made that way, that a register reads the 16 bits of coils or inputs.

As I have it now, coils, Inputs, registers are just a different perspective/way of looking at physical I/O.

Does that make sense?
Yes, coils, discrete inputs, holding registers, and input registers are just different ways of looking at memory. The best way of doing things depends on your particular applications and how you think your customers will be using your equipment.

Basically though, there are 4 types of memory, which can be classified in 2 different orthogonal ways.

1) bit versus word, and
2) read only versus read-write.

Bit memory addresses are coils and discrete inputs. These are used to represent true/false or on/off states. Sensor inputs such as switches are normally discrete inputs. Outputs such as valves or pilot lights are usually coils.

Word memory addresses are input registers and holding registers. Analogue sensor readings such as LVDTs or encoders are usually input registers. Command set points for things such as drive speeds or servo valves are usually holding registers.

These memory addresses can of course also represent things that do not correspond directly to physical devices. They can be times, calculation parameters, or anything else that is necessary.

Read only and read-write is an important distinction to make in order to simplify error handling. For example, if you use coils to represent physical switches, then how do you respond when the user writes to the switch? If the physical switch is a discrete input, then that problem doesn't arise, because there is no Modbus function for writing to a discrete input. In other words, by definition the problem simply can't arise.

As for whether the same physical characteristic can be both a register and a bit, that is permitted. I've done that myself in software that I've written. It's all a question of whether it makes sense in that application. If you think it's a good idea, then go ahead.

You have to look at it from your user's perspective. What are they going to be hooking up to your device and how are they going to be using it? Also, what Modbus functions will they have available to them?

Where duplicating bit values into registers makes sense is where it makes things easier for the end user. If for example you have a couple of discrete input values and several input register values, you could duplicate the discrete inputs into a input register to allow the user to read everything in one operation (assuming you lay everything out in adjacent registers). That might be an advantage if network bandwidth has to be conserved.

On the other hand, if they mainly just want to read the discrete inputs, then they won't be happy if they have to read them as registers and then do a bunch of mask and shift operations to get at the individual bits.

When the actual Modbus message goes over the wires, coils and discrete inputs are already packed as compactly as possible into bytes. They get unpacked into individual boolean values by the protocol driver on the receiving end. The distinction between bits and registers is so that the end user doesn't have to write the logic for packing and unpacking them into bytes for transmission.

So, what you have to do is put yourself in the shoes of the end user, rather than looking at it from a designer's perspective. A good idea would be to create a few sample applications and see what the logic would look like.

If the I/O is all digital (bit) I/O, then most people would expect to be able to access it as coils and discrete inputs. That lets the protocol driver do all the work of packing and unpacking the bits for transmission.

If you also want to have these accessible as registers, then the question has to be what advantage does this bring to the end user in this application?

Nick Mueller


Your answer absolutely addressed the philosophical side of my problem.

There are different ways to look at things. And I see, that it is best to allow all opinions and not to force people to my way of seeing things or wanting things to be done.

Currently, I don't intend to sell that interface. It's just for myself. But I wanted to be open in all directions. And I have no experience with ModBus.

Thanks again, perfect answer!
Nick from Germany.