CRC16 checksum

saucekorn69

Member
Join Date
Mar 2005
Location
Quebec
Posts
27
Hi everyone,
I'm curently developing a driver under VB.NET using the DF1 protocol,
in order to communicate with an Allen Bradley's PLC.


I'm really stuck with the CRC Checksum. I've made a class which
calculate the CRC checksum, the protocol is giving me an example to
verify the validity of my CRC value but I'm not able to get it.


I'm talking about the CRC-16, having X^16 + X^15 + X^2 + X^0 for
plynomial value.


Here is the example of a sent packet (I don't even know if this is only Hexadecimal values) :


10 02 07 11 41 00 53 B9 00 00 00 00 00 00 00 00 00 00 00 00 10 03


According to the document, CRC value of this packet has to be 6B 4C.

Here is the class's main code:
--------------------------------------------------------------


Private CRC_Register As Long = &HFFFF
Private Const POLYNOMIAL_VALUE As Long = &HA001

Public Sub AddByte(ByVal ByteValue As Int16)

Dim sLowCRC As Short, sHighCRC As Short
Dim iEven As Integer

SplitLong(CRC_Register, sLowCRC, sHighCRC)

MakeLong(CRC_Register, (sLowCRC Xor ByteValue), sHighCRC)

For i As Integer = 1 To 8

iEven = CRC_Register Mod 2

CRC_Register = CRC_Register >> 1

If iEven = 1 Then
CRC_Register = CRC_Register Xor POLYNOMIAL_VALUE
End If

Next

End Sub
---------------------------------------------------------------
Can someone tell me what's wrong with this, I ca desperately not have the good solution...


Thank you for helping.


Nicolas Chaillou.
------------------------------ --------------------------------------------------
EXA System
Montréal QUEBEC
 
First of all I have a free VB.NET compatible DF1 driver on my Company's web site at

www.tomantron.com

Secondly as far as your calc goes, make sure that you are using
only one DLE in your data and include ETX.
Third you need to work with UNSIGNED variables. CRC_Register should be ULONG. I don't know why you initialize it to &HFFFF?
 
I've read in some place that I have to initialize it with 0XFFFF.

I know that you already developped a driver, but I have to make my own driver.

So, I do have to inclue only one time the DLE value, and ETX Value ?

SO,do I calculate all the value, except the others DLE value ?
 
Read Page 5-6 of publication 1770-6.5.16 it explains it.

One more pointer. Micrologix 1200 and 1500 now does not support
protected typed logical read/write with three address fields as documented in DF1 manual (above publication) instead it supports a two address field read/write. This is not documented in the manual.
There is some supplemental info on this on AB's web site.
For example it's mentioned in G16610 - Device net knowledgebase
document. That really sucks. My driver won't work with ML1200 and ML1500 because of that. I am not willing to spend anymore time on
correcting it at this time.
 
I think you need to initialize the register to 0x0000. It looks like you have written a VB equivalent to the example from the DF1 manual. On page 5-6 of the manual it says to clear the 16 bit register used for the CRC value on step 1.

I seem to recall having to initialize the CRC register for a MODBUS RTU CRC to 0xffff. That may be what you are thinking.
 
Even if I set the crc register to 0, it doesn't seem to change my result... :cry: does anyone know where i can check an example of a CRC checksum ?
 
Nicolas: Try calculating it without either of the DLEs or the STX but do include the ETX.



One more pointer. Micrologix 1200 and 1500 now does not support protected typed logical read/write with three address fields as documented in DF1 manual (above publication) instead it supports a two address field read/write.

Really?!?!?! I read the knowledge base document you posted and I don't necessarily read that into it. Are you saying that your command 0x0f 0xa2 and 0x0f 0xaa don't work anymore?
 
Thanks !!!!

Thanks CJH, you just found my problem !!!

It was so stupid, but not mentionned in any place in DF1 protocol documentation.

I really enjoy this forum, you guys rock !! :site:
 
This is my last piece of advice. Check this snippet of my code:Dim i As Integer

Dim Low_CRC_Byte As Byte = 0

Dim Data As Byte = 0

For
i = 0 To DataPointer
Data = ReceivedData(i)

Low_CRC_Byte = (Low_CRC_Byte
Xor Data) 'Exclusive OR data and low CRC byte store results in low CRC byte

This is what I do right at the beginning of the routine.
ReceivedData is an array of bytes representing the data.
I don't see where you are looping through the data?
Also notice that I am using a byte which is an unsigned variable.
I repeat again you must not use signed variables!



 

Similar Topics

As it's the holidays, I'm a little bored, so looking back on something I did a while back thought I would post it just incase someone may be...
Replies
10
Views
1,852
Hello, I'm running on an AB ControlLogix and need to generate a 16-bit CRC, to ensure data integrity when transferring to another system. I have...
Replies
4
Views
7,056
ALL TEAM I'm working on a project using connected component workbench (CCW) from Allan Bradley PLC and I have tried to implement CRC16 but my...
Replies
0
Views
1,487
Hello guyzz, I have a problem that sounds something like this: I need to read from Citect a energy meter (Type Algodue UPT210) over RS-485 and...
Replies
9
Views
5,279
Hi all, like the title of the thread, I'm looking some sample code for realize the CRC16 routine using S7 STL or SCL language for Modubs RTU...
Replies
8
Views
7,935
Back
Top Bottom