Posted by: Ger Rietman | September 25, 2008

How to calculate the NMEA checksum

Some manufacturers (and software developers…) do not bother too much when it comes to the checksum in NMEA sentences. Probable reasons for this could be:

  1. The checksum algorithm used is not a very reliable method of checking for transmission errors or invalidating the received data
  2. There is no standard method in the NMEA protocol defined to ask for a retransmission in case of an invalid checksum
  3. Instruments do transmit a continuous stream of sentences and the data is normally refreshed every second or faster so you get a retransmit anyway, although with slightly modified data of course

Yet, since it is better than having no method at all for validating, I do recommend to always transmit a valid checksum and to always check the validity of the checksum of received sentences.

Calculating the checksum is very easy. It is the representation of two hexadecimal characters of an XOR of all characters in the sentence between – but not including – the $ and the * character.

Lets assume the following NMEA sentence:

$GPGLL,5300.97914,N,00259.98174,E,125926,A*28

In this sentence the checksum is the character representation of the hexadecimal value 28. The string that the checksum is calculated over is

GPGLL,5300.97914,N,00259.98174,E,125926,A

To calculate the checksum you parse all characters between $ and * from the NMEA sentence into a new string.  In the examples below the name of this new string is stringToCalculateTheChecksumOver. Then just XOR the first character with the next character, until the end of the string.

Below you find a code example in Java script, VB.Net and C#.

In Java script:

var checksum = 0;
for(var i = 0; i < stringToCalculateTheChecksumOver.length; i++) {
  checksum = checksum ^ stringToCalculateTheChecksumOver.charCodeAt(i);
}

In C#:

int checksum = 0;
for (inti = 0; i < stringToCalculateTheChecksumOver.length; i++){
checksum ^= Convert.ToByte(sentence[i]);}

In VB.Net:

Dim checksum as Integer = 0
For Each Character As Char In stringToCalculateTheChecksumOver 
          checksum = checksum Xor Convert.ToByte(Character)
Next
 

What is left is to transform the checksum into two hexadecimal characters, and that is it. In VB.Net and C# you can use the ToString function for this, e.g. strChecksum=checksum.ToString(“X2”).

Advertisements

Responses

  1. I made an online utility to calculate NMEA checksums here. I think it gets the same results as yours.

  2. Couldn’t get your C# version to work, but here’s mine:
    // Compute the MTK checksum and display it
    // adapted from http://www.hhhh.org/wiml/proj/nmeaxor.html
    public static string Checksum(string Value)
    {
    // Compute the checksum by XORing all the character values in the string.
    int checksum = 0;
    for(var i = 0; i < Value.Length; i++) {
    checksum = checksum ^ Convert.ToUInt16(Value.ToCharArray()[i]);
    }

    // Convert it to hexadecimal (base-16, upper case, most significant nybble first).
    string hexsum = checksum.ToString("X").ToUpper();
    if (hexsum.Length < 2) {
    hexsum = ("00" + hexsum).Substring(hexsum.Length);
    }

    // Display the result
    return hexsum;
    }

    • Thanks just what I needed….

  3. In Javascript the checksum can be represented in Hex as

    checksumHexString = checksum.toString(16).toUpperCase();

    Thanks for the XOR info!!

  4. I’m not that much of a internet reader to be honest but
    your blogs really nice, keep it up! I’ll go ahead and bookmark your
    site to come back later. All the best

  5. C++11: uint8_t crc_calculator::calculate(std::string const & x) {
    the-nmea-checksum/
    auto calculator = [](const uint8_t & g, const std::string::value_type & x) { return g^x; };
    return std::transform(x.cbegin(), x.cend(), static_cast(0), calculator);
    }

    Which could be called from a functor, etc, etc.

    • Rather, std::accumulate, not std::transform. My mistake.

  6. SABES COMO HACERLO CON ARDUINO?

    • El mismo algoritmo puede ser programado?

  7. Create C# code it solve my problem a work very fine – thanks

    • Thank you for your feedback!

  8. Should we start with index 0 or 1?

    • You should start with 0, as shown in the examples.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Categories

%d bloggers like this: