EN  中
A Short Introduction to Modbus: Protocol, Frame Formats and LRC/CRC Checking
source:    date:2026-10-01

1. About the Modbus protocol

Modbus is a common language for electronic controllers. Through it, controllers talk to each other, to devices across a network (e.g. Ethernet) — a de facto industrial standard letting equipment from different vendors form industrial networks for centralised monitoring.

The protocol defines a message structure controllers recognise regardless of the network, describing how a controller requests access to another device, how it responds to requests, and how errors are detected and reported — a common format for message fields and content.

On a Modbus network the protocol dictates each controller's device address, recognition of addressed messages and actions taken. If a response is needed, the controller generates it in Modbus. On other networks, Modbus messages are embedded in that network's frame/packet structure — a conversion that also extends node addressing, routing and error detection to the specific network.

1.1 Transmission on a Modbus network

The standard Modbus port is an RS-232C-compatible serial interface defining pins, cabling, signal bits, baud rates and parity. Controllers network directly or via modems.

Communication is master-slave: only one device (the master) initiates transactions (queries); the others (slaves) respond with the requested data. Typical masters: hosts and programmable instruments; typical slaves: PLCs. The master addresses one slave individually or broadcasts to all. Individual queries draw a response; broadcast draws none. The protocol defines the query format: device (or broadcast) address, function code, data to send, an error-check field.

The slave's response also follows Modbus: confirming the action, returning any data, and an error-check field. On a receiving error, or inability to execute, the slave builds an error message as its response.

1.2 Transmission on other networks

On other networks controllers use peer-to-peer communication — any controller may initiate; in a single transaction a controller acts as master or slave as needed, with multiple internal channels permitting concurrent transactions.

At message level Modbus keeps the master-slave principle despite the peer network: a controller sending a message acts as master and expects a slave reply; one receiving a message builds a slave response and returns it.

1.3 The query-response cycle

(1) Query: the function code tells the selected slave what to do; the data field carries any additional information — e.g. code 03 asks the slave to read holding registers and return their contents, the data field naming the starting register and count; the error-check field lets the slave validate the message.

(2) Response: in a normal response the function code echoes the query's; the data field carries the collected data — register values or status. On error the function code is modified to flag the exception, with a code describing the error in the data field; the error-check field lets the master validate the message.

2. Two transmission modes

Controllers may transmit in either ASCII or RTU mode on a standard Modbus network. The user chooses the mode and serial parameters (baud, parity); all devices on one Modbus network must share the same mode and serial settings.

The chosen ASCII or RTU mode applies only to standard Modbus networks, defining every bit of the transmitted message and how information packs into fields and decodes. On other networks (MAP, Modbus Plus) Modbus messages convert to frames independent of serial transmission.

2.1 ASCII mode

In ASCII (American Standard Code for Information Interchange) mode each 8-bit byte in the message is sent as two ASCII characters. The chief advantage: character intervals up to 1 second without error.

  • Code system: hexadecimal 0...9, A...F — each ASCII character is one hexadecimal character;
  • Bits per byte: 1 start bit; 7 data bits, least significant first; 1 parity bit (none if no parity); 1 stop bit (with parity) or 2 (without);
  • Error-check field: LRC (longitudinal redundancy check).

2.2 RTU mode

In RTU (Remote Terminal Unit) mode each 8-bit byte carries two 4-bit hexadecimal characters. The chief advantage: at the same baud rate far more data than ASCII.

  • Code system: 8-bit binary, hexadecimal 0...9, A...F — each 8-bit field is two hexadecimal characters;
  • Bits per byte: 1 start bit; 8 data bits, least significant first; 1 parity bit (none if no parity); 1 stop bit (with parity) or 2 (without);
  • Error-check field: CRC (cyclical redundancy check).

3. Modbus message frames

In both modes the transmitting device frames the message with a start and an end, letting receivers begin at the start, read the addressing, tell which device is selected (all, on broadcast) and know when the message ends. Partial messages are detectable and errors can trigger a result.

3.1 ASCII frame

In ASCII mode a message starts with a colon (:) character (ASCII 3AH) and ends with carriage-return/line-feed (0DH, 0AH); other fields use hexadecimal 0...9, A...F. Devices watch for the colon; on receipt each decodes the next field (address) to tell whether the message is for it.

Intervals between characters must not exceed 1 second, or the receiver treats it as an error. A typical frame:

START : | Address 2 chars | Function 2 chars | Byte count 2 chars | Data n chars | LRC high 2 chars | LRC low 2 chars | End CR/LF

3.2 Address field

The address field holds two characters (ASCII) or 8 bits (RTU). Possible slave addresses are 0–247 decimal; individual devices 1–247. The master addresses a slave by putting its address in the field; a responding slave puts its own address there so the master knows who replied.

Address 0 is the broadcast address, recognised by all slaves. On higher-level networks broadcast may be disallowed or replaced.

3.3 Function field

The function-code field holds two characters (ASCII) or 8 bits (RTU); codes range 1–255 decimal. Some codes apply to all controllers, some to specific ones, and some are reserved.

In a master-to-slave message the function code tells the slave what to do — read input states, read a register block, read diagnostics, allow fetch/record/verify of the slave's program, etc.

In its response the slave uses the field to signal a normal reply (error-free) or an exception: normally it echoes the function code; on exception it returns the code with its most significant bit set to logic 1.

E.g. a read of holding registers produces 00000011 (hex 03H); a normal response echoes 03H; an exception returns 10000011 (hex 83H). Besides the modified code the slave puts a unique code in the data field telling the master what went wrong. Typical master handling: retransmit, or diagnose the outgoing message and report to the operator.

3.4 Data field

The data field is built of two-hex-digit sets, 00...FF — a pair of ASCII characters or one RTU byte depending on mode.

Master-to-slave data carries the additional information the slave needs to execute the function: discrete register addresses, item counts, byte counts. E.g. to read holding registers (code 03) the data names the start register and count; to write registers (code 10 hex) it names start register, count, byte count and the data to write.

Without error, the slave's data field carries the requested data; with error, an exception code for the master's next step. Some messages have no data field (zero length) — e.g. requesting the communication event log (code 0B hex) needs no extra information.

3.5 Error-check field

Standard Modbus networks use two error-check methods; the field depends on the one chosen. ASCII: the field holds two ASCII characters computed by LRC (longitudinal redundancy check) over the message excluding the leading colon and trailing CR/LF; the LRC precedes the CR/LF. RTU: the field holds a 16-bit value (two 8-bit characters) computed by cyclical redundancy check — the CRC attaches to the end of the message, low byte first then high, so the CRC high byte is the message's last byte.

3.6 Character transmission

On standard Modbus networks each character or byte transmits left to right, least significant bit first. ASCII frame bit sequence: with parity — start, 1–7, parity, stop; without — start, 1–7, stop, stop. RTU frame: with parity — start, 1–8, parity, stop; without — start, 1–8, stop, stop.

4. Error-check methods

Standard Modbus serial networks use two methods: parity per character, and frame checking (LRC or CRC) over the whole message. The master generates both before sending; the slave checks each character and the whole frame on receipt.

The user configures a predefined timeout on the master, long enough for any slave to respond normally. If a slave detects a transmission error it ignores the message and does not respond — the timeout then triggers master error handling; addresses of nonexistent slaves also time out.

4.1 Parity checking

The user configures odd, even or no parity, determining each character's parity bit. With odd or even parity, the "1" bits count within the character's data bits (7 in ASCII, 8 in RTU). E.g. an RTU frame with data bits 11000101 has four 1s. Even parity sets the parity bit to 0, keeping four; odd parity sets it to 1, making five. Without parity no check occurs, and an extra stop bit fills the frame instead.

4.2 LRC checking

In ASCII mode the message carries an LRC error-check field covering the message except the leading colon and trailing CR/LF. The LRC field is one 8-bit byte, computed by the transmitter and inserted; the receiver computes LRC on reception and compares — unequal means error. LRC simply adds the 8-bit bytes of the message, discarding carries. A simple LRC function:

static unsigned char LRC(auchMsg, usDataLen)
unsigned char *auchMsg;   /* message to check */
unsigned short usDataLen; /* number of bytes */
{
  unsigned char uchLRC = 0; /* LRC byte init */
  while (usDataLen--)       /* through the buffer */
    uchLRC += *auchMsg++;   /* accumulate */
  return ((unsigned char)(-(char)uchLRC));
}

4.3 CRC checking

In RTU mode the message carries a CRC error-check field covering the whole message. The CRC field is two bytes — a 16-bit binary value computed by the transmitter; the receiver recomputes the CRC of the received message and compares with the field — unequal means error.

CRC starts with a 16-bit register of all "1"s, then processes each successive 8-bit byte against the register. Only the 8 data bits of each character count — start, stop and parity bits do not.

In generation each 8-bit character is OR-ed with the register contents; the result shifts toward the least significant bit, filling the MSB with 0. The LSB is extracted and examined: if 1, the register is OR-ed with a preset value; if 0, not. The process repeats 8 times; after the eighth bit the next byte is OR-ed with the current register value. The final register value is the CRC of the message. The CRC attaches low byte first, then high. A simple CRC function:

unsigned short CRC16(puchMsg, usDataLen)
unsigned char *puchMsg;   /* message to CRC-check */
unsigned short usDataLen; /* bytes in message */
{
  unsigned char uchCRCHi = 0xFF; /* high byte init */
  unsigned char uchCRCLo = 0xFF; /* low byte init */
  unsigned uIndex;               /* loop index */
  while (usDataLen--)            /* through the buffer */
  {
    uIndex = uchCRCHi ^ *puchMsg++; /* compute CRC */
    uchCRCHi = uchCRCLo ^ auchCRCHi[uIndex];
    uchCRCLo = auchCRCLo[uIndex];
  }
  return (uchCRCHi << 8 | uchCRCLo);
}

Related Reading

 
    
Support:Shandong Juxi Electromechanical Equipment Co.,Ltd.    Tel:+86-13853147838     Email:actuators@163.com    WhatsApp:13853147838/18678894019
© 2006-2025 Shandong Juxi Electromechanical Equipment