In this lesson

What this lesson covers

  • The four fields of an RTU frame, byte by byte
  • Why the CRC is the only field that goes low byte first
  • What a wrong CRC gives you: a timeout, not an error message

Read first: Reading exception codes and choosing a function code, Baud rate and parity: why 8E1 is the default

A Modbus RTU frame is four fields in a fixed order: server address, function code, data, and a CRC-16 checksum that closes it off. There is no start byte, no length field and no end marker, so once you can point at the field boundaries yourself you can read any capture on any bus. After this lesson you can take a frame apart on paper and tell a broken one from a valid one before you touch the wiring.

A real frame, byte by byte

Here is a complete request, eight bytes, nothing hidden: 01 03 00 6B 00 03 74 17.

ByteHexFieldWhat it says
101Server addressServer 1 answers, every other device stays silent
203Function codeFC03, read holding registers
3 and 400 6BStart addressPDU address 107, high byte first
5 and 600 03QuantityThree registers
7 and 874 17CRC-16Checksum 0x1774, low byte first

That PDU address 107 is the same register a datasheet would call 40108, which is the conversion covered in Modbus addressing explained.

Now the general shape. Every RTU frame is 1 address byte, 1 function code byte, 0 to 252 data bytes and 2 CRC bytes, which is why the maximum is 256 bytes on the wire.

1 byteServer address1 byteFunction code0 to 252 bytesData2 bytes, low byte firstCRC-163.5 character timesSilencet = 0frame endnext frame
Five fixed parts. The silence belongs to the frame, because it is what marks the boundary.

Change one thing and the shape holds. 01 04 00 08 00 01 B0 08 is the same server, the same field order and the same length, but function code 04 reads one input register at PDU address 8. Only the data block changed meaning. Which code reads which block is the subject of the Modbus function codes reference.

The response to that same frame

The answer to the request above is eleven bytes: 01 03 06 02 2B 00 00 00 64 05 7A.

ByteHexFieldWhat it says
101Server addressServer 1 is talking
203Function codeStill FC03, so no error
306Byte count6 data bytes follow
4 and 502 2BRegister 1555
6 and 700 00Register 20
8 and 900 64Register 3100
10 and 1105 7ACRC-16Checksum 0x7A05

Two things are worth fixing in your head. The byte count is 6, not 3: it counts bytes, not registers, and three 16-bit registers are always six bytes. And the function code came back unchanged. Had the server refused, byte 2 would have been 83, which is 03 with the high bit set, followed by a single exception code byte.

The length of a read response therefore follows from the request: 5 bytes of frame plus 2 bytes per register.

Where does a frame begin and end?

Silence, and nothing else. An RTU frame carries no start character, no end character and no length field, so a receiver decides where a frame stops purely by listening for a gap.

Two intervals do that work, both measured in character times, and one RTU character is always 11 bits on the line. Those are the numbers from baud rate, parity and timing, now with a frame wrapped around them. A gap of at least 3.5 character times (t3,5) means the frame is finished. A gap of more than 1.5 character times (t1,5) in the middle of a frame means the frame is broken and gets discarded. At 19200 baud, the default the standard prescribes, that is 2.005 ms and 0.859 ms.

Frame 1: FC03 request to server 1Frame 2: response from server 11 character = 11 bits: start, 8 data, parity, stop12Time on the bus1t1,5: largest gap allowed inside one frame0.859 ms at 19200 baud2t3,5: silence that closes the frame2.005 ms at 19200 baudAbove 19200 baud the standard recommends fixedvalues instead: 750 microseconds and 1.750 ms.
The gaps are part of the protocol on RTU, because nothing else tells a receiver where a frame ends.

This is why a USB adapter that hands its buffer over in pieces can break traffic that is electrically perfect. The bytes all arrive, but not close enough together.

What the CRC is, and what it misses

The CRC-16 is a two-byte number calculated over every byte of the frame in front of it, and it exists to tell a receiver that the frame arrived exactly as it was sent.

The calculation is fixed by the standard: a 16-bit register preloaded with 0xFFFF, shifted bit by bit, with the polynomial 0xA001 (the reflected form) mixed in whenever a shifted-out bit was 1. It runs over the address byte, the function code and all data bytes. Start bits, stop bits and the parity bit are not part of it. You do not need to implement this to work on a bus, but you do need to know its reach.

That reach is what separates it from parity. Parity protects one character at a time and only catches an error when an odd number of bits in that character flip. The CRC checks the contents of the entire message, and it does that whether or not parity is switched on.

Why the CRC sits reversed in the frame

Because the standard says the low-order byte goes first, and only for this field. The CRC value in our example is 0x1774, and on the wire it appears as 74 17.

Everywhere else in the frame a 16-bit value goes high byte first: the start address 00 6B is 107, the quantity 00 03 is three, the register value 02 2B is 555. The CRC is the single little-endian field in a Modbus RTU frame.

The trick receivers use

A receiver does not have to calculate the CRC and then compare it. It can run the same calculation over the complete frame, the two CRC bytes included, and check that the result is 0x0000.

That works because of how the checksum is constructed: appending the correct CRC makes the whole message divide out cleanly. Both frames from this lesson behave that way, 01 03 00 00 00 0A C5 CD and 01 03 00 6B 00 03 74 17, and so does every valid frame you will ever see. It means a device can decide "valid or not" in one pass over the bytes it just received, without holding anything in memory to compare against.

What happens when the CRC does not match

Nothing comes back. The server drops the frame, builds no response and says nothing, so the client sits and waits until its own timeout expires.

That behaviour is deliberate. A frame with a broken CRC cannot be trusted to say who it was for, so answering it could mean two devices talking at once on the same pair. The practical consequence is the one that costs people afternoons: a timeout is not proof that a device is absent. Wrong address, wrong serial parameters, a bad connection and a line that flips the occasional bit all produce exactly the same silence, which is where Modbus RTU troubleshooting picks up.

Common mistakes

Swapping the two CRC bytes. The value 0x1774 belongs in the frame as 74 17. Written the other way round, every device discards the frame and you see timeouts on a bus where nothing is wrong. Addresses and quantities do go high byte first; the CRC is the exception.

Reading the byte count as a register count. Three registers give a byte count of 6. Take that 6 as "six registers" and every value after it lands one field too far along, which produces plausible but wrong numbers rather than an error.

Treating a CRC error as a protocol fault. A CRC error produces silence, so it looks identical to a device that is switched off. Never conclude from a timeout alone that the address is wrong.

Assuming a short pause inside a frame is harmless. A gap longer than 1.5 character times makes the frame invalid, even when every byte is correct. USB adapters that deliver their buffers in chunks do exactly this.

Get hands-on

Take the frame apart on paper first, then check yourself against the decoder.

  1. 1

    Write down what each byte means

    Use 01 03 00 00 00 0A C5 CD and fill in the blanks below before you look anything up.

  2. 2

    Name the four fields

    Server address, function code, data and CRC. Say which bytes belong to which.

  3. 3

    Work out how long the response will be

    Ten registers is 20 data bytes, plus 1 address, 1 function code, 1 byte count and 2 CRC bytes. That is 25 bytes.

  4. 4

    Paste the frame into the decoder and compare

    Load the presets one at a time, including the exception and the broken CRC.

  5. 5

    Change a single byte and look at the CRC line

    Turn the 0A into a 0B and read the value the decoder now expects. That is the same judgement a device makes in microseconds.

  6. 6

    Watch the bytes on your own bus

    With hardware to hand, run mbpoll with the -v switch so it prints every frame it sends and receives, then compare those bytes with your own breakdown. mbpoll is free to use, including commercially. Or open the Protocol Analyzer in ModbusCloud Diagnostics, which colours the same bytes per frame field and prints a short description beside each frame.

01 03 00 00 00 0A C5 CD

01     ->  server address 1
03     ->  ______________________
00 00  ->  ______________________
00 0A  ->  ______________________
C5 CD  ->  ______________________

CRC matches

01
0
03
1
00
2
6B
3
00
4
03
5
74
6
17
7
  • Server address
  • Function code
  • Data
  • CRC-16
FieldHexDecimalMeaning
Server address011
Function code033Read Holding Registers
Start address00 6B107
Quantity00 033
CRC-1674 176004
Load a preset or paste a frame from your own capture and check the CRC before you suspect the cabling.

No hardware needed. Steps 1 to 5 need nothing but this page. Only step 6 needs a device and an RS485 adapter, and this is the command it takes:

mbpoll -m rtu -b 19200 -P even -a 1 -t 4 -r 108 -c 3 -v /dev/ttyUSB0

Expected result: a breakdown that matches the decoder field for field, and a frame with one altered byte where the decoder names the CRC it expected instead. Scanning a bus you know nothing about is covered in how to scan a Modbus network.

Summary

  • A Modbus RTU frame is always server address, function code, data and CRC-16, with a maximum of 256 bytes on the wire.
  • The byte count in a read response counts bytes and not registers, so three registers give a byte count of 6.
  • Frame boundaries on RTU are silence: at least 3.5 character times between frames, and never more than 1.5 character times inside one.
  • The CRC-16 is the only little-endian field in the frame, so the value 0x1774 travels as the bytes 74 17.
  • A frame with a bad CRC is dropped without any reply, so the client sees a timeout and not an exception, exactly as Modbus RTU explained describes for the transport as a whole.

Check yourself

Four questions about this lesson. Every answer comes with an explanation.

Question 1 of 4
In the frame 01 03 00 6B 00 03 74 17, which start address is being requested, in decimal?
How many bytes long is the response to the request 01 03 00 00 00 0A C5 CD?
A frame arrives with one corrupted byte, so the CRC does not match. What does the server send back?
You see 01 03 06 02 2B 00 00 00 64 05 7A in a capture. What is in the third register?

Stuck on a project?

Describe what you see and where it goes wrong. We will look at it and tell you what we would do.

Further reading in the knowledge base