3/10/2020 2:08 PM  
Joined: 10/31/2018 Last visit: 8/16/2024 Posts: 26 Rating: (0) 
Hi All I'm trying to get the LGF_CRC16 to work in a project, and it keeps giving the wrong CRC compared to the Sunshine2k calculator. Is there a reason it does not work for Modbus? Regards Alan  
Last edited by: The Helping Hand at: 03/10/2020 17:21:07New subject after splitting 

3/10/2020 2:55 PM  
Joined: 4/11/2012 Last visit: 9/6/2024 Posts: 181 Rating: (34) 
Some steps you can take to narrow the issue:

This contribution was helpful to1 thankful Users 
3/11/2020 10:11 AM  
Joined: 10/31/2018 Last visit: 8/16/2024 Posts: 26 Rating: (0) 
The block only accepts an array on the input. But as can be seen from the two screenshots attached. I have 0x00 0x00 in the array, the same as the sunshine2k calculator. The results are different? 
3/11/2020 10:12 AM  
Joined: 10/31/2018 Last visit: 8/16/2024 Posts: 26 Rating: (0) 
Second attachment 
3/11/2020 11:12 AM  
Joined: 4/11/2012 Last visit: 9/6/2024 Posts: 181 Rating: (34) 
I checked the LGF_CRC16 now. There are multiple ways to do the CRC calculation and I have only used one. But the method used in the LGF_CRC16 library seems to be fully opposite to the method I have used. It shifts Left? I have used the CRC calculation method defined in Modbus documentation. Check attachment or the document linked below. The Poly defined in that document is 0xA001, and this leads us to the Wikipedia article: https://en.wikipedia.org/wiki/Cyclic_redundancy_check#Polynomial_representations_of_cyclic_redundancy_checks There it can be seen that each CRC calculation has different Polynomial, but the Poly can be Normal or Reversed. CRC16IBM (used by modbus) Normal poly is 0x8005 but Reversed poly is 0xA001. The Modbus specification uses the 0xA001 Poly, so the Reversed poly. With that Poly and with shift right (instead of left) the CRC calculation works. I can't help further with the LGF_CRC16 function. I have created my own CRC calculation function using the Modbus CRC calculation diagram. (I even created a separate CRC calculation to safety program using that diagram.) 
This contribution was helpful to1 thankful Users 
3/11/2020 12:15 PM  
Joined: 10/31/2018 Last visit: 8/16/2024 Posts: 26 Rating: (0) 
Hi Elonen Thank you for all the help. Is there any chance you could send me the library containing your block, or the code inside your block? Regards Alan 
3/11/2020 1:48 PM  
Joined: 4/11/2012 Last visit: 9/6/2024 Posts: 181 Rating: (34) 
Check the modbus CRC calculation specification diagram from the above message. The actual code is very short.
That's it. There are two loops: The byte loop and the Bit loop. The bit loop is located inside the byte loop. The Poly is the 16#A001 with this formula. You can use the LGF_CRC16 function as a baseline, it has similar program structure even though the operations are a bit different. 
12/8/2023 8:48 AM  
Joined: 5/26/2016 Last visit: 12/8/2023 Posts: 1 Rating: (2) 
REGION Initialization and input data processing // Input array size calculation #tempLowerLimit := LOWER_BOUND(ARR := #array, DIM := #ARRAY_FIRST_DIMENSION); #tempUpperLimit := UPPER_BOUND(ARR := #array, DIM := #ARRAY_FIRST_DIMENSION); // Defining initial value for algorithm #tempCRC := #initValue; END_REGION REGION CRC calculation FOR #tempIndexArray := #tempLowerLimit TO #tempUpperLimit DO // Perform division using XOR function for appropriate word in array (with shift byte into LSB of 16bit CRC) #tempCRC := #tempCRC XOR BYTE_TO_WORD(#array[#tempIndexArray]); FOR #tempIndexCRC := #CRC_LOOP_LOWER_LIMIT TO #CRC_LOOP_UPPER_LIMIT DO // Check if LSB is set IF #tempCRC.%X0 THEN // Shift left and perform division by mask polynomial using XOR function #tempCRC := SHR(IN := #tempCRC, N := #SHIFT_ONE_BIT) XOR #mask; ELSE // Shift left without division #tempCRC := SHR(IN := #tempCRC, N := #SHIFT_ONE_BIT); END_IF; END_FOR; END_FOR; END_REGION REGION Outputs assignment #ModbusCRC16 := #tempCRC; // no error handling needed ENO := TRUE; END_REGION

This contribution was helpful to2 thankful Users 
Follow us on