Calculates the checksum of an NMEA sentence (GPS data).
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.
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
I thought this might be useful to people so I made it into an online utility to calculate NMEA sentence checksums.