No announcement yet.

question serial communication CRC16_CCITT

  • Filter
  • Time
  • Show
Clear All
new posts

  • question serial communication CRC16_CCITT

    I wanted to use the com_CRC16_CCITT function to check my serial data.
    So I made a c# application for this.

    But the function is not available for the 4DGL, it is present in the Goldalox version.

    Could somebody help me out?


  • #2

    Hi Raymond,

    I had the same problem a while ago and I have written two solutions, one is optimized for speed and the other is optimized for code size. Note that the CRC value depends on the initial value, which may be different for different variations of the standard.


    [quote]func CRC_CCITT(var crc,var DataPtr,var DataLen)
    //crc contains either the initial CRC value or the CRC result from previous data block
    //DataPtr is a pointer to the data block, with the data to be checked. Data can be divided in several blocks, and processed one after the other
    //DataLen is the length of the data block in bytes
    //99 bytes, 330 us per character
    var n,m,character;


    • #3

      For testing I use on 4D
      [quote]buff[0] := 0x10; // 16
      buff[1] := 0x10;
      buff[2] := 0x10;
      buff[3] := 0x10;
      buff[4] := 0x10;
      buff[5] := 0x10;
      buff[6] := 0x10;
      buff[7] := 0x10;
      buff[8] := 0x10;
      crc := CRC_CCITT(0xFFFF,buff,9); // CRC_CCITT function see post above
      This gives: 6258
      In c# it gives: 3689

      What is my mistake?

      c# code used:

      byte[] buff = null;
      buff = new byte[9];

      // Our data
      buff[0] = 0x10; // 16
      buff[1] = 0x10;
      buff[2] = 0x10;
      buff[3] = 0x10;
      buff[4] = 0x10;
      buff[5] = 0x10;
      buff[6] = 0x10;
      buff[7] = 0x10;
      buff[8] = 0x10;InitialCrcValue crcvalue = new InitialCrcValue();
      Crc16Ccitt crc = new Crc16Ccitt(crcvalue);
      ushort crcCH = crc.ComputeChecksum(buff);
      // byte[] crcBuffer = crc.ComputeChecksumBytes(buff);
      // ushort crcCheck = crc.ComputeChecksum(buff);
      MessageBox.Show(crcCH.ToString()); // RESULT 3689

      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Text;

      namespace SimpleSerial
      public enum InitialCrcValue { Zeros, NonZero1 = 0xffff, NonZero2 = 0x1D0F }

      public class Crc16Ccitt
      const ushort poly = 0x1021;
      ushort[] table = new ushort[256];
      ushort initialValue = 0;

      public ushort ComputeChecksum(byte[] bytes)
      ushort crc = this.initialValue;
      for (int i = 0; i < bytes.Length; i++)
      crc = (ushort)((crc > 8) ^ (0xff & bytes[i]))]);
      return crc;

      public byte[] ComputeChecksumBytes(byte[] bytes)
      ushort crc = ComputeChecksum(bytes);
      return new byte[] { (byte)(crc >> 8), (byte)(crc & 0x00ff) };

      public Crc16Ccitt(InitialCrcValue initialValue)
      this.initialValue = (ushort)initialValue;
      ushort temp, a;
      for (int i = 0; i < table.Length; i++)
      temp = 0;
      a = (ushort)(i


      • #4

        Hi Raymond,

        One mistake that I have spotted immediately is the initialization of your buffer in 4DGL. If you have a buffer of nine elements, you actually have 18 bytes, because each element is a word (two bytes). So initializing to 0x10 actually initializes the first byte to 16 and the second byte to zero. The CRC function is byte oriented, so your code did not convert (16,16,16,16,16,16,16,16,16) but (16,0,16,0,16,0,16,0,16).

        There may be other problems, but this is the first thing to take into account.



        • #5

          How can I make the following text crc?
          buff[0] := 'm';buff[1] := 'm';
          buff[2] := 'm';
          buff[3] := 'm';
          buff[4] := 'm';
          buff[5] := 'm';
          buff[6] := 'm';
          buff[7] := 'm';
          buff[8] := 'm';

          crcglobal := CRC_CCITT(0xFFFF,buff,9);

          But does not work properly, where wrong?
          I use for calculation
          Please help me with an example similar to my...Thanks in advance


          • #6

            CRC_CCITT is expecting a string, what you have passed it is not a string, but an array of words with a value in the low order byte of each.

            Your simplistic example could probably be fixed with

            to(buff) ;
            print("mmmmmmmmm") ;

            But I wonder if you need to understand strings a bit better.

            Try reading app note P2006


            • #7

              I tested but not correct crc, please look picture...

              to(buff); print("mmmmmmmmm");crcglobal := CRC_CCITT(0xFFFF,buff,9); // CRC_CCITT function see post aboveprint([HEX]crcglobal);//result crc 1872 Attached files


              • #8

                Sorry, now that I look at the user supplied code I see your call should be

                crcglobal := CRC_CCITT(0xFFFF,str_Ptr(buff),9); // CRC_CCITT function see post above

                This gives 6C46 which doesn't agree with your web page, so I have another web page.


                Aren't bugs wonderful


                • #9

                  Thank you very much...
                  This calculator use seed 0x0000, but in example use 0xFFFF, it is caused.
                  Thanks, work very nice...