CODESYS - the IEC 61131-3 automation software

Welcome to the official CODESYS Forum by 3S-Smart Software Solutions GmbH | A member of the CODESYS Group
Deutsche Version English version russian version 
It is currently Tue Dec 11, 2018 12:31 pm

All times are UTC+01:00




Post new topic  Reply to topic  [ 9 posts ] 
Author Message
 Post subject: CHECKSUM FUNCTION
PostPosted: Mon Jun 04, 2018 1:29 pm 
Offline

Joined: Mon Jun 04, 2018 12:04 am
Posts: 8
Hi guys a have a 36 bytes array and I have to calculate the checksum for it, fallowing the manufacture indication.
Also I have a Function made by somebody else in JAVASCRIPT but I don't really know to converted to codesys ST.

Known Example 1 in HEX :
36 Bytes = 00 00 01 EF 00 00 01 00 12 34 00 00 05 13 25 B0 12 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Checksum = A6

Known Example 2 in HEX :
36 bytes = 00 00 01 EF 00 00 01 00 12 34 56 78 10 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
Checksum = 6E

Instructions by manufacture to calculate the checksum also in the attached picture:
"""
Each bit of a byte coming is XOR with the bit 0 of CRC check register, the result of the XOR is used to change the bit 4 and 3 with a XOR as well then all bits are shifted to the right for the next bit.
"""

JAVA SCRIPT FUNCTION
"""
function _byte_xor(chks, byte) {

var tmp1;
var tmp2;

for (i = 0; i < 8 ; i++)
{
tmp1 = byte && (0x01 << i); (*Mask bit i*)
tmp1 = tmp1 >> i; (* Get it to bit 0*)
tmp2 = chks && 0x01; (* Get checksum bit 0*)
tmp2 = tmp1 ^ tmp2; (* XOR bits 0*)
chks = (chks && 0xFE) && tmp2; (* Put the XOR result in checksum bit 0*)
tmp1 = (chks && 0x08) ^ (tmp2 << 3); (* XOR bits 3*)
chks = (chks && 0xF7) && tmp1; (* Put the XOR result in checksum bit 3*)
tmp1 = (chks && 0x10) ^ (tmp2 << 4); (* XOR Bit 4*)
chks = (chks && 0xEF) && tmp1; (* Put the XOR result in checksum bit 4*)
tmp2 = chks && 0x01; (* Get checksum bit 0*)
tmp2 = tmp2 << 7; (* Move it to bit 7*)
chks = chks >> 1; (* Shift checksum right 1 bit*)
chks = chks && tmp2; (* Rotate calculated bit 0 into bit 7*)
}
return chks;
}
"""
I have tried in a old fashion way by converting the bits in Boolean but it doesn't really work.
I appreciate your help in advance .


You do not have the required permissions to view the files attached to this post.


Top
   
 Post subject: Re: CHECKSUM FUNCTION
PostPosted: Mon Jun 04, 2018 6:15 pm 
Offline

Joined: Tue Dec 03, 2013 11:52 pm
Posts: 93
Not sure if this helps but OSCAT has a function called CRC_GEN. If you pass the 32byte array (According to the picture you attached only 32bytes are used in the checksum) into it using the following values I was able to generate a HEX of A6 and 6E for the examples given.

Code:
VAR
    aMessageHex : ARRAY[0..31] OF BYTE := [16#00, 16#00, 16#01, 16#00, 16#12, 16#34, 16#56, 16#78, 16#10, 16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#00];
                                        //[16#00, 16#00, 16#01, 16#00, 16#12, 16#34, 16#00, 16#00, 16#05, 16#13, 16#25, 16#B0, 16#12, 16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#00];
    nPL : INT := 8;
    nPN : DWORD := 46;
    nINIT : DWORD := 5;
    xREV_IN : BOOL := TRUE;
    xREV_OUT : BOOL := FALSE;
    nXOR_OUT : DWORD;
    nGEN : DWORD;
END_VAR

nGEN := BASIC.CRC_GEN( PT:= ADR(aMessageHex),
                                     SIZE:= SIZEOF(aMessageHex),
                                     PL:= nPL,
                                     PN:= nPN,
                                     INIT:= nINIT,
                                     REV_IN:= xREV_IN,
                                     REV_OUT:= xREV_OUT,
                                     XOR_OUT:= nXOR_OUT);


Top
   
 Post subject: Re: CHECKSUM FUNCTION
PostPosted: Mon Jun 04, 2018 7:47 pm 
Offline

Joined: Mon Jun 04, 2018 12:04 am
Posts: 8
I really appreciate your time and effort and I would like to say : THANK YOU VERY MUCH !!!
I've been looking for a solution for weeks now and you really made my day :)

Hope I wont bother to much and wander if you can help me with some additional information .

I don't really understand why only 32 Bytes are used in the DT: Row ?

I would really appreciate if you can give me another example with all the 36 bytes as per below formulation as this is actually the format that I need to send out for reporting.
"""
Byte Value Description
00 0xE0 Command (LIVE EVENTS)
01 0x21 Century
02 0x18 Year
03 0x05 Month
04 0x00 Day
05 0x20 Hour
06 0x20 Minute
07 0x02 Event Group Number ( Alarm Partition STATUS)
08 0x12 Event Sup-group Number (Arm Partition)
09 0x02 Partition Number ( Partition 2)
10 0x12 WAGO Given Serial Number digit 1 and 2
11 0x34 WAGO GivenModule Serial Number digit 3 and 4
12 0x56 WAGO GivenModule Serial Number digit 5 and 6
13 0x78 WAGO GivenModule Serial Number digit 7 and 8
14-35 0x00 N/U
36 0xXX Checksum Note 1
"""
Basically this is a code generation in order to send SMS and GPRS data to Me, my family and Security dispatch Company thru a Regular Reporting GPS/GPRS Module Used on the market for the : House Alarm System that I made in WAGO PLC 750 Series fallowing their protocol.

Hope you will sort me out this time as well.
I really appreciate your effort and time as I know how much I've been putting in my self and maybe one day Ill be able to help others.
Cheers !!!


Top
   
 Post subject: Re: CHECKSUM FUNCTION
PostPosted: Mon Jun 04, 2018 11:02 pm 
Offline

Joined: Tue Dec 03, 2013 11:52 pm
Posts: 93
Just to make sure we are clear I am giving you an answer based off of my best guess and previous experience.

To me the first 4 bytes of the data "00 00 01 EF" in the message are just a definition of where/what to do with the following bytes. This is also said about the 36th byte since it is just a checksum (Making sure all the data is intact and not corrupt). So the message in the data above shows "--" and since it shows "--" for the checksum I strongly believe that in the example message anything with a "--" in the DT row is not counted towards the end checksum.

An example of doing 36 bytes instead (Using the values you provided) is:
Code:
VAR
    aMessageHex : ARRAY[0..36] OF BYTE := [16#E0, 16#21, 16#18, 16#05, 16#00, 16#20, 16#20, 16#02, 16#12, 16#02, 16#12, 16#34, 16#56, 16#78, 16#00,
                                    16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#00, 16#00,
                                    16#00, 16#00, 16#00, 16#00];    //Bytes 0-35 are the message and byte 36 is the checksum
    nPL : INT := 8;
    nPN : DWORD := 46;
    nINIT : DWORD := 5;
    xREV_IN : BOOL := TRUE;
    xREV_OUT : BOOL := FALSE;
    nXOR_OUT : DWORD;
    nGEN : DWORD;
END_VAR

nGEN := BASIC.CRC_GEN( PT:= ADR(aMessageHex),
                                 SIZE:= SIZEOF(aMessageHex)-1,
                                 PL:= nPL,
                                 PN:= nPN,
                                 INIT:= nINIT,
                                 REV_IN:= xREV_IN,
                                 REV_OUT:= xREV_OUT,
                                 XOR_OUT:= nXOR_OUT);
                                 
aMessageHex[SIZEOF(aMessageHex)-1] := DWORD_TO_BYTE(nGEN);


The end result is a checksum value of 108 OR 6C in hex. Hopefully this checks out against your javascript function.


Top
   
 Post subject: Re: CHECKSUM FUNCTION
PostPosted: Tue Jun 05, 2018 9:07 pm 
Offline

Joined: Mon Jun 04, 2018 12:04 am
Posts: 8
Thank you very much for your help , I really appreciate it.
I'm one of those guys that likes to understand the process behind not just copy the code provided .
How did you get the parameters right :
nPL : INT := 8;
nPN : DWORD := 46;
nINIT : DWORD := 5;

I have looked on the manual provided by OSCAT library and is not a regular known CRC but there is an online calculator , did you use that one ?
Thanks again and hope not asking to much again.


Top
   
 Post subject: Re: CHECKSUM FUNCTION
PostPosted: Tue Jun 05, 2018 9:54 pm 
Offline

Joined: Tue Dec 03, 2013 11:52 pm
Posts: 93
nPL was used for 8bits (size of the checksum value that is coming across in the message)

nPN and nINIT were setup in a loop that stopped once both of your examples checksum matched. Without more examples it is hard to be certain that those are the right parameters but since they both matched it is a good start.


Top
   
 Post subject: Re: CHECKSUM FUNCTION
PostPosted: Thu Jun 07, 2018 10:57 pm 
Offline

Joined: Mon Jun 04, 2018 12:04 am
Posts: 8
Thank you very much for your reply again.
I have managed to get the first checsum working based on your indications and it checks out on other DATA as well.
Now I'm facing a different type of checksum which is for all the 36 bytes and from what I have discovered with the ONLINE CHECK SUM CALCULATOR " https://www.scadacore.com/tools/program ... alculator/ " that is a NORMAL CheckSum8 Modulo 256 , Sum of Bytes % 256 .
Can I use the same OSCAT CRC_GEN or there is another way ?
Example below :
No1:
e0 14 12 06 07 16 05 01 01 00 00 00 00 00 00 49 6e 74 72 61 72 65 20 20 20 20 20 20 20 20 20 00 00 00 00 00
Checksum 25 ( HEX )
No2 :
e0 14 12 06 07 16 05 00 01 00 00 00 00 00 00 49 6e 74 72 61 72 65 20 20 20 20 20 20 20 20 20 00 00 00 00 00
Checksum : 24 (HEX)

Thanks again.


Top
   
 Post subject: Re: CHECKSUM FUNCTION
PostPosted: Fri Jun 08, 2018 2:07 pm 
Offline

Joined: Mon Jun 04, 2018 12:04 am
Posts: 8
I managed to get the final 8 bit Modulo Checksum calculation for the 35 bytes as per below :

FUNCTION_BLOCK CALC_CRC
VAR_INPUT
aMessageIN : ARRAY [0..36] OF BYTE ; (* BYTES TO BE CALCULATED / EXCEPT BYTE 36 - checksum*)
END_VAR
VAR_OUTPUT
aMessageOUT : ARRAY [0..36] OF BYTE ; (* COMPLETE ARRAY INCLUDING CHECKSUM*)
END_VAR

***************************************************************
VAR
i: INT:=0;
ByteSUM: DWORD;
checksumWord: DWORD;
END_VAR

ByteSUM:=0;
FOR i := 0 TO 35 DO
ByteSUM := ByteSUM + aMessageIN[i];
END_FOR
checksumWord := ByteSUM MOD 256;
(*checksumBYTE:= INT_TO_BYTE (checksumINT);*)
aMessageOUT:=aMessageIN;
aMessageOUT[SIZEOF(aMessageIN)-1] := DWORD_TO_BYTE(checksumWord);


Top
   
 Post subject: Re: CHECKSUM FUNCTION
PostPosted: Fri Jun 08, 2018 3:31 pm 
Offline

Joined: Tue Dec 03, 2013 11:52 pm
Posts: 93
Glad you got it working.


Top
   
Display posts from previous:  Sort by  
Post new topic  Reply to topic  [ 9 posts ] 

All times are UTC+01:00


Who is online

Users browsing this forum: No registered users and 3 guests


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot post attachments in this forum

Search for:
Jump to:  
Powered by phpBB® Forum Software © phpBB Limited