My most recent challenge has been adding the MAVlink protocol to my GCS project. So far, it has been my experience that one of the most difficult parts of pulling protocol messages apart is cracking the Checksum formula. A quick Google search will return hundreds of examples in C or assembler...but try finding one in Visual Basic. They mostly don't exist. uBlox and MediaTek have one method, SiRF has another, NMEA has it's own....

Then there's MAVlink. Their Comm Protocol page http://pixhawk.ethz.ch/wiki/mavlink/#mavlink_packet_documentation shows a link to a SAE AS5669A document found here: http://www.sae.org/servlets/productDetail?PROD_TYP=STD&PROD_CD=AS5669A in which they want $63 to purchase a standards PDF which still won't tell me what I need to know to decode their checksum. Apparently, they're using a crc16 checksum which includes bit shifting. A task not easily handled by .NET. So I've downloaded an converted 4 different checksum functions (1 in C, 2 in C# and 1 in VB6) to VB.NET. None of which will successfully generate the checksums I'm getting from the latest MAVlink APM output.

So I refer back to the MAVlink Comm Protocol document. Perhaps I'm looking at the wrong data. In the case of NMEA, they don't include $ or * in the checksum calculation. In uBlox, they don't include the leading uB in the checksum... but what do you know. They make no mention in the specification as to what they don't include. Is it everything? Do they leave off the "U"... no way to tell so I guess we assume everything is included. But so far, no luck in cracking this nut.... I've got about 8 hours in it so far.

So some might say, skip the Checksum for now. Just read the "U" as the header and the next byte is the payload length...and go from there. Well this is an EPIC FAIL of the MAVlink specification. In a purely homogenous environment where ONLY MAVlink messages exist, worst case (assuming no transmission fails) you'll only loose the first message by false positive on the header. Then it gets pitched on the next pass and you're off and running. "U" is recognized, length of message, checksum matches, all is good. Decode, discard, on to the next. Trouble is if you're not in a 100% MAVlink environment or you have to be ready to handle other protocols, then a "U" has a 1 in 255 change of occurring in a non MAVlink sentence. By having a 2 character header (like SiRF, MediaTek and uBlox), there is a 1 in 65,025 chance of having a false positive. By having a 3 character header (like ArduPilot, NMEA and UDB) there's a 1 in 16,581,375 chance of a false positive.

Does anyone have any clue how to correctly calculate a crc16 checksum in VB.NET? There are lots of "lightening fast" crc16 routines out these that make use of external C DLL's or some assembler code. I'm not interested in lightening fast... I just need it to work.
E-mail me when people leave their comments –

You need to be a member of diydrones to add comments!

Join diydrones

Comments

  • Developer
    Im already doing it in C# .net, have a look at the APM planner, im sending raw GPS and IMU messages.
  • nice to see that you're adding support. The code portion above is a good start. Did you see that the CRC is also part of the open source code? Just translate the C commands to VB. If it helps, the checksum is the same polynomial as in the X.25 ITU standard. And yes, the start sign is not part of the checksum, so anything after the U should be included. Hope this helps, let me know if you have additional questions on the protocol.
  • Happy -

    We use the below for CRC32 in VB.net. You might be able to adapt it for CRC16. It is a function call that is called per the following:

    Dim CRC32 As Integer
    CRC32 = XsumCRC32(&HFFFFFFFF, doitbyte)

    where doitbyte is a byte array with the data youwant to checksum, and the first variable is the starting value for the CRC...



    Public Function XsumCRC32(ByVal CRC_acc As Integer, ByVal CRC_input As Byte()) As Integer

    Dim j As Integer
    Dim i As Byte
    Dim POLY As Integer = &HEDB88320

    Try

    For j = 0 To (CRC_input.GetUpperBound(0))
    CRC_acc = CRC_acc Xor CRC_input(j)
    For i = 0 To 7
    If ((CRC_acc And &H1) = &H1) Then

    CRC_acc = Convert.ToInt32(((CRC_acc And &HFFFFFFFE) \ 2&) And &H7FFFFFFF)
    CRC_acc = CRC_acc Xor POLY
    Else
    CRC_acc = Convert.ToInt32(((CRC_acc And &HFFFFFFFE) \ 2&) And &H7FFFFFFF)
    End If
    Next i
    Next j
    XsumCRC32 = CInt(CRC_acc)
    Catch ex As Exception

    Debug.Print(ex.Message)

    End Try
    End Function
    VB.NET Shop
  • Here's a VB6 version which didn't generate matching checksums with the MAVlink APM output.

    http://www.di-mgt.com.au/src/basCRC16.txt
  • Thanks Dean, but I downloaded both...but they didn't seem to help..
  • Unmanned Systems and Robotics Interoperability Center
    Under software you can download:
    JAUS++ is an open source C++ implementation of both the JAUS Reference Architecture and SAE standard (AS5669A, AS5710, and AS6009) available under the BSD license.

    I also found this:
    SAE AS5669A
    東進ハイスクール評判ナビ/人気講師も多数在籍する予備校!
    流行語大賞も受賞した話題の先生が在籍する、東進ハイスクールとはどのような予備校なのか徹底調査! 気になる講師陣や、講義の内容、学費などをご紹介しています。
This reply was deleted.