Modbus ASCII Protocol
Data formats
To review, we can see that an integer can be represented in different ways.
| Decimal (base10) |
Binary (base2) |
Hexadecimal (base16) |
ASCII (base256) |
|---|---|---|---|
| 174 | 1010 1110 | AE | ® |
Message Delimiting
In Modbus RTU, bytes are sent consecutively with no space in between them with a 3-1/2 character space between messages for a delimiter. This allows the software to know when a new message is starting.
Any delay between bytes will cause Modbus RTU to interpret it as the start of a new message. This keeps Modbus RTU from working properly with modems.
Modbus ASCII marks the start of each message with a colon character " : "
(hex 3A).
The end of each message is terminated with the carriage return and line feed characters
(hex 0D and
0A).
This allows the space between bytes to be variable making it suitable
for transmission through some modems.
Byte Size
In Modbus RTU each byte is sent as a string of 8 binary characters framed with a start bit, and a stop bit, making each byte 10 bits.
In Modbus ASCII, the number of data bits is reduced from 8 to 7. A parity bit is added before the stop bit which keeps the actual byte size at 10 bits.
Split Data bytes
In Modbus ASCII, each data byte is split into the two bytes representing the two ASCII characters in the Hexadecimal value. For example,
| Modbus Mode | data (ASCII) | data (hexadecimal) | data (binary) |
|---|---|---|---|
| Modbus RTU | ® | AE | 1010 1110 |
| Modbus ASCII | A & E | 41 & 45 | 100 0001 & 100 0101 |
The range of data bytes in Modbus RTU can be any characters from
00 to
FF.
The range of data bytes in Modbus ASCII represent only the 16 hexadecimal characters.
Therefore, every data byte in Modbus ASCII must be one of these 16:
| ASCII (base256) |
Hexadecimal (base16) |
Binary (base2) |
|---|---|---|
| 0 | 30 | 011 0000 |
| 1 | 31 | 011 0001 |
| 2 | 32 | 011 0010 |
| 3 | 33 | 011 0011 |
| 4 | 34 | 011 0100 |
| 5 | 35 | 011 0101 |
| 6 | 36 | 011 0110 |
| 7 | 37 | 011 0111 |
| 8 | 38 | 011 1000 |
| 9 | 39 | 011 1001 |
| A | 41 | 100 0001 |
| B | 42 | 100 0010 |
| C | 43 | 100 0011 |
| D | 44 | 100 0100 |
| E | 45 | 100 0101 |
| F | 46 | 100 0110 |
Error Checksum - LRC Calculation
As mentioned earlier, each Modbus RTU message is terminated with two error checking bytes called a CRC or Cyclic Redundancy Check. Similarly, Modbus ASCII is terminated with an error checking byte called an LRC or Longitudinal Redundancy Check.
Here is a spreadsheet
CRC calculator
for messages up to 16 bytes.
The calculation of the LRC is much easier than the CRC.
To calculate the LRC:
1. Add up all the data bytes in the message
(before converting to ASCII and without the initial colon and final CR/LF).
2. Throw away any bits that carry over 8 bits.
3. Make the result negative (by twos compliment) to get the LRC byte.
The sum of the resulting byte stream with the LRC will then be 0 since adding the negative subtotal will make the final total zero.
For example, this Modbus RTU request (without the CRC) is for registers 40108 to 40110 from slaveID 17.
11 03 00 6B 00 03
| notes | Decimal (base10) |
Hexadecimal (base16) |
Binary (base2) |
|---|---|---|---|
| byte 1 | 17 | 11 | 0001 0001 |
| byte 2 | 3 | 03 | 0000 0011 |
| byte 3 | 0 | 00 | 0000 0000 |
| byte 4 | 107 | 6B | 0110 1011 |
| byte 5 | 0 | 00 | 0000 0000 |
| byte 6 | 3 | 03 | 0000 0011 |
| add the bytes (subtotal) | 130 | 82 | 1000 0010 |
| two's compliment (make negative) - This is the LRC | -130 | 7E | 0111 1110 |
| total of all bytes including the lrc is 0 | 0 | 00 | 0000 0000 |
The single hex LRC byte is 7E
The LRC byte is then split into two ASCII bytes with the rest of the data.
The two ASCII bytes for the LRC are then 37 (the ASCII code for 7) and 45 (the ASCII code for E)
ASCII vs RTU example:
Using the same example shown above to request registers 40108 to 40110 from slave address 17.
11 03 00 6B 00 03
The complete ASCII request is made by first adding the message delimiting characters. A colon is added to the start of the message, the LRC, carriage return and line feed are added to the end:
: 1 1 0 3 0 0 6 B 0 0 0 3 7 E CR LF
Each character is now treated as an ASCII character and replaced with it's hex value to give the final message.
3A 3131 3033 3030 3642 3030 3033 3745 0D 0A
This Modbus ASCII request size is 17 bytes.
...............
The equivalent Modbus RTU message would be:
11 03 00 6B 00 03 76 87
This Modbus RTU request size is 8 bytes.