Understanding Modbus
Client and Server (or Master and Slave?)
One of the biggest sources of confusion on-site is the terminology. Older Modbus documentation and many devices still use master and slave. Newer standards use client and server. They mean the same thing:
| Old term | New term | Role |
|---|---|---|
| Master | Client | Sends requests, asks for data |
| Slave | Server | Responds to requests, provides data |
You'll see both naming conventions used interchangeably in datasheets, PLC manuals, and configuration software. A "Modbus master" is the same as a "Modbus client". If a colleague says "the slave isn't responding", they mean the server.
This naming confusion causes real problems in the field. When you're working with mixed documentation (one manual says "master", another says "client"), just remember: the one asking questions is the client/master, the one answering is the server/slave.
In Modbux you choose which side you're on: are you requesting data (Client mode) or providing data (Server mode)?
TCP or RTU
Modbus comes in two variants that determine how messages are transmitted:
Modbus TCP works over a regular network (Ethernet/Wi-Fi). You need an IP address and port. No special hardware required. This is the most common variant in modern installations.
Modbus RTU works over a serial connection (RS-485). You need a USB-to-RS485 adapter. RTU is common in older installations and industrial environments where devices are directly connected by cable.
With TCP the Unit ID is often optional, so you can usually just leave it at 0. With RTU the Unit ID is always required because it determines which device on the bus should respond.
Register types
Modbus organizes data into four types of registers. Each type has its own purpose:
Holding Registers: read and write
The workhorses of Modbus. You use them for anything you need to both read and set: setpoints, configuration parameters, alarm thresholds. When a device says "write the desired temperature to register 100", that's almost always a Holding Register.
Input Registers: read only
Sensor data and measurements end up here. A temperature sensor writes its reading to an Input Register, and you read it out. You can't write to them. The device determines the value.
Coils: read and write (on/off)
Digital outputs: turning a pump on or off, opening or closing a valve. Each coil is one bit: 0 (off) or 1 (on).
Discrete Inputs: read only (on/off)
Digital inputs: a switch that's on or off, a sensor detecting whether something is open or closed. Like coils they're binary, but you can only read them.
In practice, most systems mainly use Holding and Input Registers. Coils and Discrete Inputs are less common because a single 16-bit register can hold 16 statuses at once.
Addressing
The address problem
Each register type has addresses from 0 to 65535. But here's where it gets confusing: manufacturers often use conventional addresses with a prefix that indicates the register type:
| Prefix | Type | Conventional | Protocol address |
|---|---|---|---|
| 0xxxx | Coils | 00001 | 0 |
| 1xxxx | Discrete Inputs | 10001 | 0 |
| 3xxxx | Input Registers | 30001 | 0 |
| 4xxxx | Holding Registers | 40001 | 0 |
Say a datasheet says "read register 40101". They could mean Holding Register at protocol address 100, or 101, depending on whether they count from 0 or 1. You can't know for sure without checking the device documentation.
A real-world example: Siemens TIA Portal's MB_CLIENT block uses this exact convention. When you set MODE=0 (read) and DATA_ADDR=40001, the block reads Holding Register at protocol address 0 using function code 03. The leading 4 tells the block which register type to use. Set DATA_ADDR=30001 and it reads Input Registers instead (FC 04). This is convenient (one parameter handles both the register type and the address), but it also means you need to understand the convention to configure it correctly.
This is the most common Modbus mistake: the difference between conventional address and protocol address. A device that says "register 40001" means the first holding register (protocol address 0). Always check your device documentation whether addresses are 0-based or 1-based. Modbux has an address base toggle so you can adjust this.
Function codes
Under the hood, Modbus uses numbered commands (function codes) for each operation. You don't need to memorize them, but they help when debugging:
| FC | What it does |
|---|---|
| FC 01 | Read coils |
| FC 02 | Read discrete inputs |
| FC 03 | Read holding registers |
| FC 04 | Read input registers |
| FC 05 | Write a single coil |
| FC 06 | Write a single holding register |
| FC 15 | Write multiple coils |
| FC 16 | Write multiple holding registers |
Big-Endian vs Little-Endian
When a value needs more than 16 bits (like a 32-bit integer or float), it gets split across multiple 16-bit registers. The question is: which register gets the "high" part and which gets the "low" part? That's what endianness determines.
Take the 32-bit integer 305419896 (hex 0x12345678) split across two registers. Switch between the tabs to see what changes:
Register 0: 0x1234 (W1 - high word)
Register 1: 0x5678 (W0 - low word)registers[0] := W1; // most significant word first
registers[1] := W0;Big-Endian puts the most significant word in the first register. This is the Modbus standard and what most PLCs use (including Siemens S7).
Register 0: 0x5678 (W0 - low word)
Register 1: 0x1234 (W1 - high word)registers[0] := W0; // least significant word first
registers[1] := W1;Little-Endian puts the least significant word in the first register. Less common in Modbus, but some devices use it.
If your values look nonsensical (a temperature reading of millions, or a counter that makes no sense), the endianness is probably wrong. This is one of the most common issues when connecting to a new device.
Use the BE/LE toggle in the Modbux toolbar to quickly switch between word orders and see which one gives you sensible values.