Part II · Chapter 5
Modbus RTU
For many people, RTU simply is Modbus: the Chapter 4 frame (address, PDU, error check) sent as compact binary bytes down a serial wire, usually the rugged two-wire bus called RS-485.
By the end of this chapter you can
- Describe an RS-485 bus: daisy chain, A and B lines, termination, and bias.
- Set and read serial settings such as "9600 8-E-1", and draw one character on the wire.
- Explain how silence marks the edges of an RTU frame.
- Say what the CRC does, trace it through a byte, and put it on the wire low byte first.
The wire: RS-485
Most RTU networks run over RS-485, an electrical standard built for exactly this job: reliable data over long distances, through electrically noisy plants, to many devices on one shared pair of wires. One bus can run over a thousand meters (about 1,200 m at typical Modbus speeds) and connect dozens of devices: 32 standard unit loads per segment, more with low-load transceivers or a repeater. You'll occasionally meet RS-232 too. The Modbus framing is identical, but RS-232 is point-to-point and short-range, so it can't form a multidrop bus.
An RS-485 bus is a daisy chain, not a star. The pair runs from device to device in a single line, and each device taps on as the line passes. The two conductors are usually labeled A and B. You'll also see D−/D+, −/+, or other names, and frustratingly, manufacturers don't agree on them. Most installations add a third conductor as a common signal ground.
Two practical details separate a bus that works from one that doesn't:
- Termination. Each of the two far ends carries a resistor across A and B, typically 120 Ω to match the cable's impedance. It absorbs the signal at the end of the line so it doesn't reflect back and garble data on long or fast runs. Only the two ends, nowhere in the middle.
- Bias. Gentle bias resistors, usually in one place on the bus, hold the line in a known state when nobody is transmitting, so the quiet between messages reads as a clean idle instead of random noise.
Many devices have switchable termination and bias. Knowing they exist saves hours when a long bus behaves erratically.
Why two wires? Differential signaling
RS-485 is tough because it's differential. A receiver doesn't measure one wire against ground, which industrial noise easily corrupts. It looks only at the difference between A and B: which line is higher decides whether the bit is a one or a zero. Noise tends to strike both wires almost equally, pushing both voltages up or down together and leaving the difference nearly untouched. The signal rides in that difference, so the noise largely cancels.
Half-duplex: taking turns on one pair
A two-wire RS-485 bus is half-duplex: the same pair carries traffic both ways, but only one device may transmit at a time. That suits Modbus perfectly. Chapter 3's one-question-at-a-time discipline (the client speaks then listens; a server speaks only to answer) stops being mere manners and becomes a physical necessity. If two devices drove the pair at once, their signals would collide and both would be lost.
So each device switches its transmitter on only while it's sending, then releases the line. That turnaround happens in the quiet gaps between messages.
Serial settings that must match
Before two devices can exchange a single byte, they must agree on how each byte's bits are timed and shaped. Four settings are configured identically at both ends, and a mismatch is one of the most common reasons a freshly wired bus produces nothing but silence.
- Baud rate: the speed in bits per second. 9600 and 19200 are common; 38400 and 115200 are widely supported.
- Data bits: always 8 for RTU, because RTU sends whole bytes.
- Parity: an optional check bit on each character (even, odd, or none) that catches some single-bit errors.
- Stop bits: one or two, marking the end of each character.
They're written compactly: 9600 8-E-1 means 9600 baud, 8 data bits, even parity, 1 stop bit.
| Setting | Typical values | Notes |
|---|---|---|
| Baud rate | 9600, 19200, 38400 | Must match exactly at both ends |
| Data bits | 8 | Always 8 for Modbus RTU |
| Parity | Even, Odd, None | Even is the specified default |
| Stop bits | 1 or 2 | Use 2 when parity is None, so every character stays 11 bits long |
Here's what those settings produce on the wire. The line idles high. A start bit (low) announces a character, the eight data bits follow least significant bit first, then the parity bit, then the stop bit returns the line high. At 8-E-1 that's 11 bits per byte.
Framing by silence
Here's the cleverest idea in RTU. A serial line is just a stream of characters with no built-in marker for "a new message starts here." RTU's answer is time. A frame is a burst of characters sent back to back, bracketed by silence: a gap of at least 3.5 character times (the time to send three and a half bytes at the current speed) marks the boundary. Once the line has been quiet that long, the next byte to arrive starts a fresh frame.
Inside a frame it works in reverse: the bytes must arrive in a tight stream with no gap longer than about 1.5 character times. A longer pause in the middle tells the receiver the frame was interrupted, and it throws the frame away.
This framing is elegant and needs no special start or stop bytes, but it makes RTU sensitive to timing. Software reaching a serial port through layers of operating-system buffering, or a USB adapter or radio that delivers data in bursts, can smear these gaps. That's one reason dependable serial hardware matters more than it first appears.
Character-time calculator
| Quantity | Time |
|---|
The CRC: catching corruption
The last two bytes of every RTU frame are the CRC, or cyclic redundancy check. Before sending, the transmitter runs every byte of the frame (address, function code, data) through a fixed procedure that boils them down to one 16-bit number, and appends it. The receiver runs the identical procedure over what it received and compares. If they match, the frame is almost certainly intact. If not, a byte was corrupted in transit, and the receiver silently discards the frame as if it never came.
The procedure is specific, sometimes written CRC-16/MODBUS. You don't need to derive it, but seeing it removes the mystery. The value starts at all ones, 0xFFFF. Each byte is mixed in with exclusive-or, then the value is shifted right one bit at a time, eight times. Whenever the bit shifted out was a 1, the value is combined with a fixed constant, the polynomial 0xA001. After the last byte, the 16-bit result is the CRC.
def crc16(data):
crc = 0xFFFF
for byte in data:
crc ^= byte
for _ in range(8):
if crc & 1:
crc = (crc >> 1) ^ 0xA001
else:
crc >>= 1
return crc
frame = bytes([0x01, 0x03, 0x00, 0x00, 0x00, 0x04])
crc = crc16(frame)
print(hex(crc))
print((frame + crc.to_bytes(2, "little")).hex(" "))
0x944
01 03 00 00 00 04 44 09
Two facts about the CRC trip people up:
- It goes on the wire low byte first, the opposite of the big-endian order used everywhere else in the frame. The CRC value
0x0944from our running example travels as44then09. - A bad CRC draws no exception. The receiver can't trust anything in a corrupted frame, not even the address, so it says nothing. To the client, a bad CRC looks exactly like silence, which is why CRC problems and wiring problems feel alike when you're troubleshooting.
In practice you'll almost never compute a CRC by hand; every Modbus library does it. But knowing what it is keeps its failures from being baffling.
CRC step-through
| Step | What happens | CRC | Binary (lowest bit underlined) |
|---|
Modbus RTU is the workhorse, and you now know its distinctive parts: the RS-485 bus it usually rides, the serial settings that must match, and the CRC and silence-based framing that make a serial frame self-contained. Before Ethernet, one more serial form: the older, human-readable Modbus ASCII, which trades RTU's efficiency for legibility.
Check your understanding
1. How does an RTU receiver know a frame has ended?
RTU has no delimiters and no length field. Silence of 3.5 character times separates frames.
2. A frame's CRC value is 0x0944. In what order do its bytes go on the wire?
The CRC is the one field sent low byte first, so 0x0944 travels as 44 09.
3. A server receives a frame whose CRC doesn't check out. What does the client see?
A corrupted frame can't be trusted, not even its address, so the server stays silent. That's why bad CRCs look like wiring faults.
4. Where do the 120 Ω termination resistors go on an RS-485 bus?
Termination absorbs the signal at the ends of the cable to stop reflections. Extra terminators in the middle load the bus and weaken the signal.