Modbus is an open communication protocol originally developed by Modicon in 1979 for communication between programmable logic controllers (PLCs) and other industrial devices. It defines a master/slave (or client/server in newer terminology) message structure for reading and writing registers and coils across a shared bus or network. The protocol family covers both serial and Ethernet-based physical layers.
In practice
Modbus appears in three main variants. Modbus RTU transmits binary-encoded frames over a serial link, typically RS-485 at baud rates such as 9600 to 115200 bps (though other rates are supported depending on device capabilities). Each frame includes a device address, function code, data, and a 16-bit CRC. Modbus ASCII is a less common text-encoded variant over RS-232 or RS-485. Modbus TCP wraps the same register model in a TCP/IP packet (port 502), replacing the RTU CRC with an MBAP header that includes a transaction identifier and other framing fields; it is common in industrial Ethernet installations. The underlying data model -- discrete coils, discrete inputs, holding registers, and input registers -- is identical across all standard variants, though some vendor implementations or gateways may impose additional constraints or extensions.
In embedded work, a device acting as a Modbus RTU slave typically monitors a half-duplex RS-485 bus, decodes incoming frames addressed to it, and responds with register values or acknowledgments. Driver/receiver ICs like the MAX485 or SP3485 handle the electrical layer, and a GPIO line controls transmit/receive direction switching. Timing is critical: Modbus RTU uses inter-character and inter-frame silence periods (1.5 and 3.5 character times, respectively) to delimit frames, so the UART and any DMA setup must handle these gaps correctly. The blog post "Help, My Serial Data Has Been Framed: How To Handle Packets When All You Have Are Streams" discusses exactly this kind of framing challenge on serial streams.
On resource-constrained MCUs, Modbus slave stacks are small enough to run bare-metal. Full master/slave implementations are also available for RTOSes; the blog post "Using a board with NuttX RTOS as an RS-485 / Modbus Slave Device" covers a practical slave implementation on NuttX. Modbus TCP requires a TCP/IP stack, making it more suitable for MCUs with Ethernet MACs or Wi-Fi and enough RAM to support lwIP or a similar stack.
A common pitfall is byte order. Individual 16-bit holding registers are transmitted big-endian (high byte first), but 32-bit values spanning two concatenated registers have no single standard byte and word order -- different vendors use different arrangements. This is a frequent source of interoperability bugs, especially when mixing devices from different manufacturers. The blog post "Endianness and Serial Communication" covers endianness issues that arise in exactly these situations.
Discussed on EmbeddedRelated
Frequently asked
What is the difference between Modbus RTU and Modbus TCP?
Modbus RTU runs over a serial physical layer, usually
RS-485, and uses binary framing with a 16-bit
CRC and inter-frame silence gaps to delimit messages. Modbus TCP runs over standard
TCP/IP (port 502) and wraps the same function codes and register model in a Modbus Application Protocol (MBAP) header, replacing the CRC with a transaction identifier. The register and coil data model is identical in both variants.
How does frame detection work in Modbus RTU?
Modbus RTU has no explicit start-of-frame byte. Instead, a silence period of at least 3.5 character times on the bus signals the end of one frame and the beginning of the next. Characters within a frame must arrive with gaps no larger than 1.5 character times. At 9600 bps, 3.5 character times is about 4 ms. This means the receiver must use a timer -- hardware or software -- to detect these silence windows rather than relying on a delimiter byte.
How many devices can share a Modbus RTU RS-485 bus?
The
RS-485 electrical standard supports up to 32 unit loads on a single segment without repeaters (more with low-unit-load transceivers). Modbus RTU addressing supports device addresses 1 through 247 (address 0 is reserved for broadcast). In practice, bus length, termination, and transceiver selection typically constrain physical node count before the address space is exhausted.
What does 'holding register' mean in Modbus?
Modbus organizes data into four tables: coils (single-bit read/write), discrete inputs (single-bit read-only), holding
registers (16-bit read/write), and input registers (16-bit read-only). Holding registers (function codes 03 to read, 06/16 to write) are the most commonly used, typically holding sensor values, setpoints, or configuration parameters. The absolute address space is device-specific -- each vendor maps their own data onto register numbers.
Is Modbus suitable for real-time control?
Modbus is a polled, master-initiated protocol with no built-in priority scheme or guaranteed
latency. It is suitable for supervisory monitoring and control at timescales of tens of milliseconds or slower. It is generally not used for tight real-time control loops where deterministic sub-millisecond response is required. For those applications, protocols like EtherCAT or CANopen are more appropriate.
Differentiators vs similar concepts
Modbus RTU and Modbus
ASCII both run over serial links (commonly
RS-485) and share the same register model, but RTU uses compact binary encoding with a
CRC-16, while ASCII encodes each byte as two ASCII hex characters with an LRC
checksum, making ASCII easier to debug with a terminal but doubling frame size. Modbus TCP is not a serial protocol at all -- it carries Modbus data over
TCP/IP and is oriented toward
Ethernet-connected industrial devices and SCADA systems. All three variants share the same underlying coil/register data model and function code set, which is why they are often grouped under the single "Modbus" label.