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.

beni hess 14 years, 10 months ago

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)