CRC Help

I need some help with a CRC. I have fair experience with Arduino programming, however I don't even know where to start here. I'm sure the answer is simple and I'm over complicating it. Here is what I read from a protocol manual for a device I want to communicate with.

"The ROC Plus protocol applies a cyclical redundancy check (CRC) to the message string to produce a 16-bit remainder. This remainder is referred to as the CRC-16 code. The CRC-16 code is appended to the end of the message string. The ROC800 uses the 16-bit polynomial CRC-16: X16 + X15 + X2 + 1 The ROC800 uses the standard GPLIB CRC routine, and calculates CRC by table lookup, with the initial condition (seed) of 0000 (zeros)."

any help would be greatly appreciated.

Pete Wright

This webpage has some code which appears to compute the required CRC and has test examples.

Pete

Welcome to the most confusing world of CRC. The beauty (not) of CRC is that there are as many options as there are implementations. So much for standards. Everybody thinks his/her polynomial is best. You can develop the code given the polynomial, which you have, or try to find the name of the poly and find code already written for it. As an example, the most common 8 bit CRC uses the Dallas-Maxim inverse polynomial which can be found everywhere.

uint8_t crc8(byte *_cptr)
{   // With Dallas/Maxim inverse polynomial, returns 8-bit CRC
    //
    byte _len = strlen((char*)_cptr);
    byte _crc = 0;
    while (_len--) 
    {
        byte _byte = *_cptr++;
        for (byte i = 8; i; i--)
        {
            byte _mix = (_crc ^ _byte) & 0x01;
            _crc >>= 1;
            if (_mix) _crc ^= 0x8C;
            _byte >>= 1;
        }
    }
    return _crc;
}

If you decide to do it yourself, understand that the seed 0000 should be written as 0x0000 as you start the twos compliment math with a string twice as wide as the result.

Good luck.

On the webpage I linked, the code shown in the second message does not correspond to the output.
These lines of code:

  crc = CRC16_ARC(test3, 8);
  printf("Manual   check value: 0x%04X, test ", crc);
  if (crc==0x7611) printf("passed.\n"); else printf("failed!\n");

can't possibly have produced this line of output:

Manual   check value: 0x1176, test passed.

The third line of code should be;

  if (crc==0x1176) printf("passed.\n"); else printf("failed!\n");

Pete

uses the standard GPLIB CRC routine

Well, you can start by looking for this "GPLIB" that they mention.
Unfortunate, it seems to be a pretty common name ("General Purpose Library") :frowning:

Um. This looks nice: CRC Series, Part 3: CRC Implementation Code in C/C++ | Barr Group

The code on the webpage I linked works and calculates exactly the CRC required by the OP.

Pete

Wow, thanks for the replies. Gives me some homework to do.

I will post again once I have an answer.