Welcome, guest | Sign In | My Account | Store | Cart

Calculates the checksum of an NMEA sentence (GPS data).

Python, 46 lines
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#!/usr/bin/env python

import re

""" Calculate  the checksum for NMEA sentence 
    from a GPS device. An NMEA sentence comprises
    a number of comma separated fields followed by
    a checksum (in hex) after a "*". An example
    of NMEA sentence with a correct checksum (of
    0x76) is:
    
      GPGSV,3,3,10,26,37,134,00,29,25,136,00*76"
"""

def checksum(sentence):

    """ Remove any newlines """
    if re.search("\n$", sentence):
        sentence = sentence[:-1]

    nmeadata,cksum = re.split('\*', sentence)

    calc_cksum = 0
    for s in nmeadata:
        calc_cksum ^= ord(s)

    """ Return the nmeadata, the checksum from
        sentence, and the calculated checksum
    """
    return nmeadata,'0x'+cksum,hex(calc_cksum)

if __name__=='__main__':

    """ NMEA sentence with checksum error (3rd field 
       should be 10 not 20)
    """
    line = "GPGSV,3,3,20,26,37,134,00,29,25,136,00*76\n"

    """ Get NMEA data and checksums """

    data,cksum,calc_cksum = checksum(line)

    """ Verify checksum (will report checksum error) """ 
    if cksum != calc_cksum:
        print "Error in checksum for: %s" % (data)
        print "Checksums are %s and %s" % (cksum,calc_cksum)

The checksum function is passed an NMEA sentence and returns the NMEA data, the checksum that was appended to the sentence when it was generated and the locally calculated checksum. A NMEA sentence may be read directly from a GPS device and therefore could contain a newline at the end. If so, this is removed. The example above verifies an NMEA sentence by comparing the two checksums returned by the checksum function. The example sentence has been corrupted, resulting in error message.

2 comments

beni hess 12 years, 6 months ago  # | flag

first of all, you must love regular expressions ... for a simple split and strip ;)

second, it's maybe better to keep the checksum a number not a string

import operator
def checksum(sentence):
    sentence = sentence.strip('\n')
    nmeadata,cksum = sentence.split('*', 1)
    calc_cksum = reduce(operator.xor, (ord(s) for s in nmeadata), 0)

    return nmeadata,int(cksum,16),calc_cksum
greg p 12 years, 5 months ago  # | flag

I thought this might be useful to people so I made it into an online utility to calculate NMEA sentence checksums.

Created by Alan Holt on Tue, 2 Jun 2009 (MIT)
Python recipes (4591)
Alan Holt's recipes (3)

Required Modules

Other Information and Tasks