Ploxc

Modbux

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 termNew termRole
MasterClientSends requests, asks for data
SlaveServerResponds 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.

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). RTU is common in older installations and industrial environments where devices are directly connected by cable.

Unit ID

The Unit ID identifies which server should respond to a request. How it works depends on the variant:

With RTU the Unit ID is always required. Multiple devices share the same serial bus, and the Unit ID is the only way to address a specific one. Each device on the bus has its own unique Unit ID.

With TCP the Unit ID is often optional. Each device typically has its own IP address, so the Unit ID is redundant. You can usually leave it at 0.

RTU-to-TCP converters are where it gets interesting. These converters bridge a TCP network to a serial RTU bus. You connect via TCP (IP address and port), but behind the converter there may be multiple RTU devices. In that case the Unit ID is required to route your request to the correct device on the bus.

Register types

Modbus organizes data into four types of registers. Each type has its own purpose, described here from the client's perspective:

Holding Registers: read and write

The workhorses of Modbus. The client can both read and write these. Used for setpoints, configuration parameters, alarm thresholds.

Input Registers: read only

Sensor data and measurements. The server populates these with values (e.g. a temperature reading) and the client reads them out. The client can't write to them.

Coils: read and write (on/off)

Digital outputs. The client can turn them on or off, for example a pump or a valve. Each coil is one bit: 0 (off) or 1 (on).

Discrete Inputs: read only (on/off)

Digital inputs. The server sets these based on physical state (a switch, a sensor). The client can only read them. Like coils they're binary, but read only.

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:

PrefixTypeConventionalProtocol address
0xxxxCoils000010
1xxxxDiscrete Inputs100010
3xxxxInput Registers300010
4xxxxHolding Registers400010

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:

FCWhat it does
FC 01Read coils
FC 02Read discrete inputs
FC 03Read holding registers
FC 04Read input registers
FC 05Write a single coil
FC 06Write a single holding register
FC 15Write multiple coils
FC 16Write 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 layout
Register 0:  0x1234  (W1 - high word)
Register 1:  0x5678  (W0 - low word)
SCL assignment
registers[0] := W1;   // most significant word first
registers[1] := W0;

Most significant word first. This is the Modbus standard and what most PLCs use.

Register layout
Register 0:  0x5678  (W0 - low word)
Register 1:  0x1234  (W1 - high word)
SCL assignment
registers[0] := W0;   // least significant word first
registers[1] := W1;

Least significant word first. 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. In Server mode, endianness is a global setting per server, so all registers on a server share the same byte order, matching how real devices typically work.