Figuring out the CRC

I am working on building a program to communicate with the Kegboard. I have most of the protocol figured out but the CRC is giving me fits. Before I process a message, I would like to make sure that I received all of the data correctly. According to the serial protocol documentation, the CRC is on the header and payload data. When I use my code to calculate the CRC, I never get a match and I have absolutely no idea what to look for as I don’t know if my coding of the CRC matches what the Kegboard is doing.

For example, line A below is a temperature_reading message from the Kegboard. In line B, I have removed the footer (CRC and trailer). This is the byte string that I feed into my CRC code. I get 31 4D. I have spent the better part of two days trying to figure this out. I have tried different CRC implementations and they all give me different results which leads me to believe that maybe there is a seed value that I am missing. I have looked at the CRC code for the Kegboard on Github and nothing is jumping out at me but I also don’t know Python.

A: 4B 42 53 50 20 76 31 3A 11 00 1F 00 01 17 74 68 65 72 6D 6F 2D 33 31 30 30 30 30 30 34 66 36 64 32 62 65 32 38 02 04 C0 F3 5E 01 03 95 D A

B: 4B 42 53 50 20 76 31 3A 11 00 1F 00 01 17 74 68 65 72 6D 6F 2D 33 31 30 30 30 30 30 34 66 36 64 32 62 65 32 38 02 04 C0 F3 5E 01

My CRC: 31 4D

Any ideas?

I didn’t get any responses to this so I just had to keep trying. My code was getting the data from the kegboard but every once in a while when it was busy (usually when the flow meters were sending data very quickly), the data would get truncated and would really mess with my code. If I could check the CRC, that would tell me if I had good data to work with.

I had tried multiple examples of the CRC and never got a return result that matched what was in the data so I figured that I was either missing some kind of seed value or there was multiple implementations of the CRC-16-CCITT. It was the latter.

I found this great site on CRC: It has a calculator where you can enter an ASCII or byte string and it will show the CRC values for multiple implementations. I entered a sample byte string that I had received from the kegboard less the footer. When I checked the results, there was a match. The kegboard uses the “Kermit” implementation of the CRC-16-CCITT. A couple of Google searches later and I had some code that implemented the Kermit CRC checksum.

If anyone is interested, here is the code to calculate it. You need to create an array to hold the lookup table and then call CreateKermitTable to generate the values. Once you do this, just call CalcChecksum passing in the byte array to get the CRC checksum.

Private Function CalcCheckSum(ByVal Bytes() As Byte) As UShort
    Dim CRC As UShort = 0
    For i = 0 To Bytes.Length - 1
        CRC = (CRC >> 8) Xor KermitTable((CRC Xor (&HFF And Bytes(i))) And &HFF)
    Dim loByte = (CRC And &HFF00) >> 8
    Dim hiByte = (CRC And &HFF) << 8
    Return (loByte Or hiByte)
End Function

Private Sub CreateKermitTable()
    Dim temp, a As UShort
    For i = 0 To KermitTable.Length - 1
        temp = 0
        a = i
        For j = 0 To 7 'Loop Once for each bit in the byte
            If ((temp Xor a) And &H1) <> 0 Then 'And &h1 checks if (temp Xor a) is odd
                temp = (temp >> 1) Xor &H8408 'If it is divide by 2 then Xor 1000010000001000
                temp >>= 1 'Else just divide by 2
            End If
            a >>= 1 'a = a divide by 2
        KermitTable(i) = temp
End Sub


What sort of program do you have in mind?


Well, I really like the concept of the Kegbot but I am a Windows programmer. I was able to get it working but I was always running into issues that took me a long time to fix. I also wanted to extend the functionality to limit my beverage intake. I am also planning on hooking it up to a soda machine that I have next my kegerator to limit the number of sodas that my kids consume.

I had given up when I was thinking about it one day and came to the realization that the Kegboard probably wasn’t communicating using native USB. More than likely, the Arduino was emulating a com port. When I had a free moment, I connected the device to a machine with a com port and after tweaking the settings for a few minutes, I saw that the device was continuously streaming data. I did a search for a serial protocol document and found one. I pretty much have the communications library done and am working on my application. I keep running into little issues but I think that I will have something that I can use in a week or so.