LRC calculation

G

Thread Starter

Glen

I have a question about LRC generation.

I'm working on a system that will use MODBUS communication over a serial line in an ASCII transmission mode. The specification and implementation guide says, "The LRC is calculated by adding together successive 8-bit bytes in the message...". But is the LRC calculation performed before or after the message is converted to ASCII format?

Maybe I'm just overlooking it, but I've looked in both the Implementation Guide and the Protocol Reference but neither seems to say at what point the LRC calculation is performed.

Thanks in advance,
Glen
 
Quote from page 38 of "MODBUS over serial line specification and implementation guide V1.0" at www.Modbus.org

"A procedure for generating an LRC is:
1. Add all bytes in the message, excluding the starting 'colon' and ending CRLF. Add them into an 8–bit field, so that
carries will be discarded.
2. Subtract the final field value from FF hex (all 1's), to produce the ones–complement.
3. Add 1 to produce the twos–complement."

---So you calculate based on the ASCII bytes in the message, but without the start and end flags.
The LRC must then be converted to ASCII with the high character placed first in the message, followed by the low character. The document also includes an example.

RAH
 
Modbus messages may be of two sorts, binary (RTU), or ASCII. In the case of RTU the Longnitudinal Reduncy Check (CRC) is carried out on the raw bianry data bytes, usually one by one as they arrive.

In the case of the ASCII proctocol, the test is actually a Checksum (as you described), and the addition is carried out on the ASCII values as they are received (They are **allready in ASCII**).

If the message is 'ABC' then you receive:

0x41 0x42 0x43

the checksum is 0x41+0x42+0x43=0xC6

Which in ASCII will be:

0x43 0x36
 
I had the same confusion looking at the Modbus info, but the LRC is calculated before converting to ASCII.
 
Thanks, I did see the section you quoted and have read it again several times; but my question remains.

I am confused about step #1 of the procedure. Step #1 says "Add all bytes of the message,..."; but at this point is my message in ASCII format? In other words, if I am addressing controller 11d (17h) do I add 0x01 + 0x07 ... or do I add 0x31 + 0x37...? (One form being the ASCII version of the other.)

And do you know of any section of the Modbus specs that address question? It seems that some of the answers to my original post contradicted one another.

Thanks,
Glen
 
Thanks for the response Brian.

I checked out the Technical Note (TN) that you referred me to; but if it answered my question then I must have missed it.

The TN told me that the LRC = 20 bits and “checks the content of the message exclusive of the beginning colon (3A) and the CRLF (0D0A); but it didn’t seem to tell me at what point to add up all the bytes of the message, when it is in hex or ASCII format.

In the example they provided the 1st step yields:

:1103006B0003CSCRLF

the 2nd step converts each ASCII character to its Hex equivalent:

3A313130333030364230303033CS0D0A

At which point do I sum up all the bytes, step one or step two? The LCR will be different depending on at what point it is calculated.

Thanks,
Glen
 
A

Alex Pavloff

<P>That Siemens tech note is confusing to me because its describes the "hex" and "ascii" as different values. They're not. Heck, that "hex string" they've got isn't even delimited like most things I (as a programmer) expect to see. I'll break the modbus string out for you in 3 different formats</P>

<PRE>
ASCII: : 1 1 0 3 0 0 6 B 0 0 0 3
-CS- CR LF
HEX: 0x3A 0x31 0x31 0x30 0x33 0x30 0x30 0x36 0x42 0x30 0x30 0x30 0x33
-CS- 0x0D 0x0A
DECIMAL: 58 49 49 48 51 48 48 54 66 48 48 48 51
-CS- 13 10
</PRE>

<P>All three of there are exactly the same thing -- the only that that's changing is how we're looking at the data. Adding the the numbers
togethers will result in the same value, no matter "when" you do it or what number base you're using.</P>

<P>Alex Pavloff - [email protected]<BR>
Eason Technology -- www.eason.com</P>
 
C

Chiron Consulting

>> Glen,
>>
>> Check out this site:
>>
>> http://www.schneider-electric.ca/www/en/techpaper/html/tn054.htm

> Thanks for the response Brian.
>
> I checked out the Technical Note (TN) that you referred me to; but if it answered my question then I must have missed it. <

See the last line of the third paragraph under the heading "ASCII",
which reads:

"The checksum is calculated after the message is converted to binary."

Regards,
Greg Goodman
Chiron Consulting
 
S
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
[email protected]
Niobrara R&D Corp.
 
Scott Henson wrote:
> You add up the bytes for the checksum before you convert the message to ASCII.
>
> For example,...
>=============snip=====================
> So the trick is to calculate the LRC before you convert the message to ASCII <

OK, I have finally got it. Sorry to be so slow on this issue. Thanks to everyone for the input and all the concrete examples. After hearing it about a dozen times, expressed a dozen different ways, the light went ON. Thanks again.
 
S

Steve Ciricillo

Good grief!

Glen, you are absolultely correct. Some of the disinformation given to you in this thread is scary. For starters, refer to this previous discussion on this point.
http://modbus.control.com/dev/1026168422/index_html

Essentially the LRC is calculated on the binary representation of the ascii bytes, either before they are converted to ascii when sending or after they are converted from ascii when receiving. The calculated LRC (in binary) may then be compared to the received LRC THAT HAS FIRST ALSO BEEN CONVERTED FROM 2 BYTES OF ASCII TO BINARY.

The Apr 17, 2003 3:55 pm, by Anonymous reply is particularly appalling. Can't blame the person for remaining Anonymous!

"In the case of RTU the Longitudinal Reduncy Check (CRC) is carried out on the raw binary data bytes, usually one by one as they arrive."

In the case of RTU the "Cyclic Redundancy Check (CRC) is performed on the binary data. This is a 16 bit algorithm and is significantly different than the 8 bit checksum scheme employed for LRC.

"In the case of the ASCII proctocol... the addition is carried out on the ASCII values as they are received."

Patently UNTRUE. The addition must be on the binary versions of the ascii.

Now I am concerned about what you wrote.
> In other words, if I am addressing controller 11d (17h) do I add 0x01 + 0x07 ... or do I add 0x31 + 0x37...? (One form being the ASCII version of the other.)
>

The address field in ASCII mode is a 2 byte ASCII representation of the HEX code for the decimal address. Example, if your device address is 11d (your example) then I presume you meant 11 decimal, which in HEX is 0Bh, not 17h. I think you switched them around. 11h = 17d. Carrying this through, 11d = 0Bh = address in ASCII of 0x30 + 0x42 ('0', 'B').

See the other thread as I suggested. Good luck.

Regards,
Steve C.

> Thanks, I did see the section you quoted and have read it again several times; but my question remains.
>
> I am confused about step #1 of the procedure. Step #1 says "Add all bytes of the message,..."; but at this point is my message in ASCII format? In other words, if I am addressing controller 11d (17h) do I add 0x01 + 0x07 ... or do I add 0x31 + 0x37...? (One form being the ASCII version of the other.)
>
> And do you know of any section of the Modbus specs that address question? It seems that some of the answers to my original post contradicted one another.
>
> Thanks,
> Glen
 
S

Steve Ciricillo

Pursuant to my previous reply.

The only place in the PI-MBUS-300 document where the correct reference is made is in the comments of the source code listing on page 111. There the comment clearly states that the buffer pointer points to a buffer containing BINARY data. The supporting text on the previous pages however give incomplete, misleading or otherwise incorrect detail on the calculation of the LRC.

You and I are not the only ones who have stumbled over this issues. I hope this has helped.

Regards,
Steve C.
 
G

Greg Goodman

> The only place in the PI-MBUS-300 document where the correct reference is made is in the comments of the source code listing on page 111.

The original Modbus doc seems misleading, but is not incorrect. The document consistently refers to the binary values as "8-bit"; ASCII values are 7-bit values, or at least they were when the document was written.

"The LRC field is an 8-bit binary value... The LRC is calculated by adding together successive 8-bit bytes in the message ... When the 8-bit LRC (2 ASCII characters) is transmitted ..."

The document's authors clearly thought that describing a value as an 8-bit value distinguished it adequately from its 2-byte ASCII representation.

More recent documents have done a better job of clarifying the situation. The Tech Note mentioned in a previous post unambiguously says to convert the ASCII message contents to binary first.

Section 3.4.2 of the Daniels Modbus Communications Model 2500 document (Part Number 3-9000-545 Rev D, Nov 1992) says:

"The error check sequence for the ASCII mode is LRC. The error check is an 8-bit binary number represented and transmitted as two ASCII hexadecimal (hex) characters. The error check is produced by converting the hex characters to binary, adding the binry characters without wraparound carry, and two's complementing the result. At the received end the LRC is recalculated and compared to the sent LRC. The color, CR, LF and any embedded non-ASCII hex characters are ignored in calculating the LRC."

Not that anybody looks to Daniel for rigorous treatment of the Modbus standard. :^)

Regards,

Greg Goodman
Chiron Consulting
 
C

Curt Wuollet

If worse comes to worse, I'll dig up the working stuff I wrote. Years ago though.

Regards

cww
 
Top