Today is...
Friday, February 15, 2019
Welcome to Control.com, the global online
community of automation professionals.
Featured Video...
Wiring and programming your servos and I/O just got a lot easier...
Help keep our servers running...
Longitudinal Redundancy Check (LRC)
Need an example for calculating the LRC for ASCII modbus protocol.

I'm having a difficult time grasping the proper way to calculate the LRC for ASCII Modbus protocol. I turned to the web for examples, however, they seem to conflict with the explanation given in the Modbus protocol reference guide. Can you tell me, for example, if my ASCII message frame was, :3A 09 03 03 1F 00 28 LRC CR LF, how exactly is the LRC calculated? The parity is even (I'm still not sure whether that matters or not). Please be specific, remember, I couldn't understand the original explanation. Thank you very much for your help!

This seems to explain it.

http://modbus.control.com/dev/1026163379/index_html

Hello

I have A question about LRC I am written a program. by I must enter a number and then he counts me on the instruction "print CR (7, aa\$)" check-hums out from this number:
2 = e0
3 = d0

How is the Algorhitum of this LRC??

By Scott Henson on 14 January, 2005 - 9:05 am

If you do a search for LRC you will find this description from April of 2003.

Apr 23, 2003 3:18 pm, by Scott Henson
Glen,
You add up the bytes for the checksum before you convert the message to ASCII.

For example, to send a Holding Register Read to unit 247 of register 5002 with a count of 10 you would build the following Modbus message (in hex):

F7 03 13 89 00 0A

If you were sending the message as RTU you would calculate the CRC16 and tack it on the end and the message on the wire would be:

F7 03 13 89 00 0A 04 35

Now to send the same message as ASCII you would calculate the checksum by adding up the bytes and negating the answer:

F7+03+13+89+00+0A=1A0
negating 1A0 = FE60

You only use the lower byte for the LRC which is 60. The new message with the checksum is now:

F7 03 13 89 00 0A 60

To send this on the wire it now needs to be converted to ASCII and have the colon and CR LF tacked on:

3A 46 37 30 33 31 33 38 39 30 30 30 41 36 30 0D 0A

So the trick is to calculate the LRC before you convert the message to ASCII

Scott Henson
shenson@niobrara.com
Niobrara R&D Corp.

The LRC is calculated by adding each byte, then taking the twso compliment, from after colon (3Ah) up to the CR LF.

All values in Hex..
09 + 03 + 03 + 1F + 00 + 28 = 56.
Then Compliment = A9.
A9 + 1 (to make two's compliment) = AA.
AA should be the LRC...

Hope that clears it up.
Andrew
www.equustek.com

By David Kelly on 24 February, 2005 - 9:59 am

The problem that drove me to this site just now is the wording "...up to the CRLF". The LRC is immediately before the CRLF. I doubted the simple routine intended one to calculate LRF on the LRF in the incoming packet. But thats what the text seems to say. Examples provided here say differently.

So the answer is, "after the colon and up to (not including) the LRC".

By Rathinakumar Raviselvan.C.R on 22 March, 2007 - 1:14 am

I have written few examples and a simple C
program to calculate the LRC. I have not tested
the C program properly.

Calculating a LRC for a command bytes is easy.
All you have to do is add the bytes one by one
and discard the carry (if any) and the find the
2's complement of the final result.

2's complement is nothing but 1's complement + 1.

1's complement can be obtained just by inverting
all the 1s as 0 and vice versa, of a byte.

1's complement can also be found by subtracting
the number (byte) from 0xFF.

Here I write a few examples, which I believe will explain the algorithm better. (All the numbers are in Hexadecimal format).

Example 1:

Single byte: AA

Since it's a single byte command, there are no
other numbers to be added, so just we have to
find its 2's complement.

1's complement of AA = FF � AA = 55.<br>
2's complent of AA = 55 + 1 = 56.

So the LRC is 56.

Example 2: Two byte command.

7E, A6.

Step 1. 7E + A6 = 124.<br>
Step 2. After discarding the carry = 24.<br>
Step 3. 1's complement of 24 = FF-24 = DB<br>
Step 4. 2's complement of 24 = DB + 1 = DC.

So LRC of 7E,A6 is DC.

Example 3:
01, 01, 00, 07, C0

Step 1. 01+01 = 02<br>
Step 2. 02+00 = 02<br>
Step 3. 02+07 = 09<br>
Step 4. 09+C0 = C9<br>
Step 5. 1's complement of C9 = FF-C9 = 36<br>
Step 6. 2's complement of C9 = 36+1 = 37.

So the LRC of the above mentioned bytes is 37.

This program is tested in Turbo C compiler only
for few examples. Please change 'CMNDarray' array
elements with the bytes of your command set then
the value of'count' accordingly.

`#include<stdio.h>#include<conio.h>void main(){ unsigned char LRC = 0x00; unsigned char CMNDarray[]= {0x01, 0x01, 0x00,                             0x07, 0xC0}; int index, count; count = 5; clrscr(); for (index = 0; index<count; index++) {   LRC = CMNDarray[index]+LRC;  // printf(" LRC temp is %X ",LRC);  // printf(" index is %d ",index);  // printf(" count is %d ",count); }  LRC = 0xFF-LRC; // 1's complement  LRC = LRC+1;      // 2's complements                            printf(" LRC Calculated is %X ",LRC);}`

By Jim McMurran on 5 November, 2013 - 8:10 pm

There a couple of tricks, first LRC is calculated With raw data not the ASCII formatted data.

also the : is not used in the calculations nor are the CR LF
Parity is for the serial protocol and has no impact on LRC.