In short: Modbus RTU sends binary frames of address, function code, data and a CRC-16 over RS-485, and the receiver finds frame boundaries purely by silence: at least 3.5 character times of idle line ends one frame and starts the next, so baud, parity and wiring must match on every node.
Why Modbus RTU still matters
Introduced by Modicon in 1979, Modbus is still the default language of energy meters, VFDs, PLC I/O blocks and HVAC controllers. The RTU variant is the compact binary flavour that rides on a UART. It has no start-of-frame byte and no length field, which makes it deceptively simple and the source of most field failures. If you want the Ethernet cousin, read our Modbus TCP guide; for the physical layer, see RS-485 basics.
Anatomy of an RTU frame
A frame is: 1 byte slave address (1-247; 0 is broadcast), 1 byte function code, N data bytes, and 2 bytes CRC. Maximum length is 256 bytes, so the data field holds at most 252 bytes. Each byte travels as 11 bits by default: 1 start, 8 data (LSB first), 1 parity (even by default), 1 stop. With no parity the spec asks for 2 stop bits to keep 11 bits.
Silent-interval framing: the 3.5 character rule
With no markers, the receiver uses time. Bytes inside a frame must arrive with gaps under 1.5 character times; a gap over 1.5 means the frame is corrupt and must be discarded. A gap of 3.5 character times or more closes the frame, and the next byte starts a new one. A character time is 11 bits divided by the baud rate.
| Baud | Char time | t1.5 | t3.5 |
|---|---|---|---|
| 9600 | 1.146 ms | 1.72 ms | 4.01 ms |
| 19200 | 0.573 ms | 0.86 ms | 2.00 ms |
| 38400 and up | 0.286 ms | fixed 0.75 ms | fixed 1.75 ms |
Above 19200 baud the spec fixes the timers at 750 µs and 1.75 ms, because a typical OS or interrupt latency makes sub-millisecond character timing unrealistic.
This is why a Linux USB-serial adapter running pymodbus occasionally "loses" frames: the kernel's buffering can insert a gap of several milliseconds in the middle of a frame, and a strict slave sees two truncated frames. Most real stacks relax the intra-frame rule and only enforce the 3.5 gap, or use a hardware idle-line interrupt on the UART (STM32 IDLE flag, for example) to mark the end of a frame without per-byte timers.
CRC-16 step by step
Modbus uses CRC-16/MODBUS: polynomial 0x8005, reflected to 0xA001, initial value 0xFFFF, no final XOR. For each byte: XOR it into the low byte of the CRC, then do eight times: if the least significant bit is 1, shift right and XOR 0xA001, otherwise just shift right. Everything is computed over address, function and data, never the CRC itself.
uint16_t crc16(const uint8_t *p, size_t n) {
uint16_t crc = 0xFFFF;
while (n--) {
crc ^= *p++;
for (int i = 0; i < 8; i++)
crc = (crc & 1) ? (crc >> 1) ^ 0xA001 : crc >> 1;
}
return crc; /* send low byte first */
}
For 01 03 00 00 00 0A the result is 0xCDC5, transmitted as C5 then CD. Mixing up that byte order is the classic bug. A 16-bit CRC detects all burst errors up to 16 bits and all odd-bit-count errors, which is why it suits noisy plant floors. A 256-entry lookup table cuts the cost to one XOR and shift per byte on small MCUs.
Baud rate and serial settings
- Common rates: 9600 (default), 19200, 38400, 115200. Long multidrop cables favour 9600 or 19200.
- Even parity with 1 stop bit is the standard; many cheap meters ship as 8N1 or 8N2. A mismatch looks like silence or constant CRC errors.
- Throughput is lower than the baud suggests. Reading 10 registers at 9600 is 8 bytes out, 25 back, 33 bytes at 1.146 ms is about 38 ms, plus two 4 ms silences and the slave's turnaround, so a poll cycle for 32 slaves can easily take over a second.
- The master must set a response timeout (typically 100-1000 ms) and a retry count; slaves never speak unsolicited.
Two devices with the same slave address on one bus corrupt each other's replies, and the master sees only CRC errors, so address uniqueness is the first thing to check.
RS-485 wiring that actually works
RS-485 is differential: a driver puts a voltage across the A/B pair and the receiver detects a difference of at least 200 mV. It tolerates common-mode shifts of -7 V to +12 V and runs up to 1200 m, with up to 32 unit loads (more with 1/4 or 1/8 load transceivers). Modbus RTU uses the two-wire half-duplex form.
- Use twisted-pair, ideally 120 Ω characteristic impedance, and a daisy chain. Stubs longer than a few tens of centimetres cause reflections at higher baud.
- Terminate with 120 Ω at both far ends only. Extra terminators overload the driver.
- Bias the idle line (about 560 Ω pull-up on B, pull-down on A) at a single point so that a floating bus reads as a clean idle level, not random noise that looks like start bits.
- Connect a common reference (the third wire or shield, often via 100 Ω) so receivers stay inside the common-mode range.
- Direction control: the transceiver's DE/RE pin must be switched to receive right after the last stop bit. Releasing it too early truncates the CRC; too late swallows the reply's first byte.
Swapped A/B labels are an endless trap, because vendors disagree on which is "+". If nothing answers, swap the pair before debugging firmware.
Debugging in practice
Use a USB-RS485 adapter with a protocol sniffer (Wireshark with a serial capture, or Modbus Poll) and verify the CRC of captured frames against the code above. Design teams building the SoC or MCU side of such nodes usually verify UART and idle-line behaviour in simulation with Synopsys VCS or Cadence Xcelium before tape-out; Avecas design services does this kind of verification work, and ChipXpert training covers the digital design behind it.
FAQ
Why does Modbus RTU use a 3.5 character silence?
Because frames carry no start marker or length, silence is the only unambiguous delimiter; 3.5 character times is long enough that it cannot occur inside a healthy frame.
Is the CRC sent low byte first?
Yes. For CRC 0xCDC5 the wire carries C5 then CD, while register data fields are big-endian.
How many devices fit on one RS-485 segment?
32 unit loads per segment, with a Modbus address range of 1-247; repeaters or low-load transceivers extend this.
What is the difference from Modbus TCP?
TCP drops the CRC and address-based framing in favour of an MBAP header over TCP port 502; see Modbus TCP.
Want to build and verify serial protocol controllers hands-on? Explore the embedded and VLSI tracks in CourseTron courses.