Part I · Chapter 2
The Modbus Data Model
When a client reaches into a server for a value, what is it reaching into? Four small tables. Once you can picture them, most function codes read like plain English: they just move data into or out of these tables.
By the end of this chapter you can
- Name the four tables and say which hold bits, which hold registers, and which are read-only.
- Convert a reference number like
40013to the zero-based address on the wire. - Read a register map, and explain why Modbus itself assigns no meaning to the data.
Four tables, two questions
Every Modbus server organizes its data into exactly four tables. That isn't a teaching simplification; it's the model the protocol defines. Each table is a numbered list of storage slots, and the four differ along just two questions:
- Is each slot a single bit (on or off) or a sixteen-bit register (a number)?
- May the client only read the slot, or also write it?
Two questions with two answers each give four combinations, and those are the four tables.
Commit these four names to memory; they appear constantly in device manuals:
| Table | Slot size | Access | Typical use |
|---|---|---|---|
| Discrete Inputs | 1 bit | Read-only | A switch or status the device senses |
| Coils | 1 bit | Read/write | An output you can turn on or off |
| Input Registers | 16 bits | Read-only | A measured value the device reports |
| Holding Registers | 16 bits | Read/write | A setting or value you can change |
A pattern jumps out. The two input tables are read-only: they reflect what the device measures or senses, so you can't change them. Coils and holding registers are read/write: they hold things you're allowed to set. The names are historical. A "coil" comes from the relay coils early controllers switched on and off, so it's a one-bit output you command. A "discrete input" is a one-bit reading from the world, like whether a limit switch is pressed. An input register is a number the device produces, like a temperature; a holding register is a number you can read and write, like a setpoint.
Bits and registers
Almost every Modbus operation is about one or the other. A bit is the smallest piece of data: 1 or 0, on or off. A relay is closed or open; a pump is running or stopped. Reading a coil returns a single yes-or-no; writing one commands a single yes-or-no.
A register is a sixteen-bit word that holds a whole number from 0 to 65535. A temperature sensor might report 235 to mean 23.5 degrees; a drive might accept 1750 to mean 1750 RPM. Sixteen bits is the native unit of Modbus, a legacy of the sixteen-bit controllers it was born on. When a value needs more (a large counter, or a fractional number) a device uses two registers together, which Chapter 14 covers in detail.
Addresses within a table
Each table is a numbered list, and a slot's position in its table is its address. On the wire, Modbus addresses are zero-based: the first slot is address 0, the next is 1, and so on up to 65535, so a table can hold up to 65,536 slots.
The four tables are addressed independently. Holding register 0, input register 0, and coil 0 are three different slots. There's never confusion about which "address 0" you mean, because every request names an operation, and the operation implies the table. So the on-the-wire model is simple: the function picks the table, a zero-based address picks the slot. If that were the whole story, addressing would trouble nobody. Unfortunately, an older way of writing addresses grew up alongside it.
The addressing trap: reference numbers
Long before the modern specification settled on zero-based addresses, device makers wrote register locations as reference numbers (also called conventional addressing). Each is a five-digit (or six-digit) number: the leading digit names the table, and the rest give the position counting from one.
| Leading digit | Table | Reference range | Protocol address |
|---|---|---|---|
| 0 | Coils | 00001–09999 | 0–9998 |
| 1 | Discrete Inputs | 10001–19999 | 0–9998 |
| 3 | Input Registers | 30001–39999 | 0–9998 |
| 4 | Holding Registers | 40001–49999 | 0–9998 |
That's why holding registers so often appear in the forty-thousands. When a meter's manual says voltage is at register 40013, the leading 4 means "holding register" and 0013 means "the thirteenth one, counting from one." On the wire, that same slot is address 12.
The conversion has two steps, and forgetting either one is the classic beginner bug:
- Strip the leading digit that names the table.
- Subtract one to go from counting-from-one to the zero-based protocol address.
So 40001 is holding-register address 0, 40100 is address 99, and 30005 is input-register address 4. Get it wrong and you read a value that is "one off" from where you expected, or land in the wrong table entirely.
To make things worse, manuals aren't consistent. Some modern devices document registers directly as zero-based protocol addresses and never mention reference numbers. Others use the 4xxxx style. A few list "register 40001" but quietly mean address 40001 on the wire. The only safe habit: read each device's documentation carefully and confirm on a known value that you land where you expect. Software tools usually let you choose which convention you're typing, so know which one is selected.
Try it: reference number converter
Type a 5- or 6-digit reference such as 40001, 40100, 30005, 10001, or 400250.
The register map
A device tells you what lives at each address in a document called its register map (or memory map). Each row names an address, says which table it's in, gives the quantity stored there, and notes how to interpret the raw number. The register map is the single most important page of any Modbus device's manual: everything you do with the device starts by finding the right row.
Here's a small but realistic map for an imaginary temperature-and-humidity sensor. (The last column, the protocol address, isn't in the manual; it's the conversion you just learned.)
| Address | Table | Quantity | Notes | On the wire |
|---|---|---|---|---|
| 30001 | Input Register | Temperature | Value / 10, in °C | IR 0 |
| 30002 | Input Register | Humidity | Value / 10, in % RH | IR 1 |
| 30003 | Input Register | Status flags | Bitfield; bit 0 = fault | IR 2 |
| 40001 | Holding Register | Sample period | Seconds, 1–3600 | HR 0 |
| 40002 | Holding Register | Modbus address | Unit ID, 1–247 | HR 1 |
Each row carries everything you need. The temperature is in an input register (read-only, because you can't dictate a measurement), while the sample period is in a holding register (a setting you're allowed to change). The raw value must be divided by ten: the sensor stores 235 to mean 23.5 °C, because registers hold whole numbers and that's how this device packs a fraction into one. That scaling rule is not part of Modbus. It's a convention this device chose and documented, so the same raw number can mean different things on different devices.
What Modbus does not define
It matters just as much what the data model leaves out. Modbus defines bits and sixteen-bit registers, and nothing more. It has no notion of a signed number, a decimal point, a temperature, or a name. It doesn't know that 30001 is a temperature or that it should be divided by ten. All that meaning lives in the register map and in the agreement between the people who built the device and the people reading it. The protocol moves raw bits and raw words faithfully; interpreting them is your job.
This minimalism is deliberate, and freeing. Because Modbus imposes no data types, any device can use plain registers to carry signed values, fractions, text, packed flags, or numbers wider than sixteen bits, each by its own documented convention. The cost is that you must always consult the map; the benefit is that the protocol never gets in the way. Chapter 14 shows how to read signed integers, 32-bit values, and floating-point numbers out of these same registers.
Putting the model to work
With the data model in hand, every Modbus operation becomes predictable:
| To… | you… |
|---|---|
| Read a measurement | read an input register |
| Check a status bit | read a discrete input |
| Flip an output | write a coil |
| Change a setting | write a holding register |
Each of these maps to a specific function code, the subject of Part II. But the data they move always lives in one of the four tables you now know.
You now know what Modbus data is and where it lives. The remaining question for Part I is how a client actually asks for it: the precise back-and-forth of request and response, including what happens when something goes wrong.
Check your understanding
1. Which two tables are read-only?
The two tables named "input" are read-only: they reflect the physical world. Coils and holding registers are read/write.
2. A meter's manual lists voltage at register 40013. What address goes on the wire?
Strip the leading 4 (holding registers) to get 0013, then subtract one: address 12.
3. Using the sensor's register map, input register 30002 reads 612. What is the humidity?
The map says "Value / 10, in % RH," so 612 / 10 = 61.2 % RH. The scaling comes from the map, not from Modbus.
4. Where does Modbus record that a register holds a temperature in tenths of a degree?
Modbus moves raw bits and sixteen-bit words with no meaning attached. Units, scaling, and data types come from the register map.