PDA

View Full Version : NMEA CheckSum Routine



Tom Gonser
- 21st March 2005, 00:21
Folks:

Thanks to help here, I worked together a routine that generates a checksum which is now working with an externally connected GPS. This can be used when making a checksum for NMEA sentences for example. I was looking ALL OVER for this routine, so I am posting it here in case someone else might also be trying to do this.

Below I build an array with a bunch of data that is being used to create a $GPWPL sentence, which is a Waypoint. To do this, I am reading from a data source that contains important info like lat, long, n/s/e/w, and waypoint name.

Setting each array value to an ASCII value by appending +"0" to the variable data is a key! Then, run it throught a loop which eliminates the '$' and the '*' because these are not computed in a checksum. (1-35) The result is a HEX checksum that will be accepted by GPS units.

' create checksum '************** Checksum:
WPT_array[0]="$"
WPT_array[1]="G"
WPT_array[2]="P"
WPT_array[3]="W"
WPT_array[4]="P"
WPT_array[5]="L"
WPT_array[6]=","
WPT_array[7]=Dec_lat1 DIG 3+"0"
WPT_array[8]=Dec_lat1 DIG 2+"0"
WPT_array[9]=Dec_lat1 DIG 1+"0"
WPT_array[10]=Dec_lat1 DIG 0+"0"
WPT_array[11]="."
WPT_array[12]=Dec_lat2 DIG 3+"0"
WPT_array[13]=Dec_lat2 DIG 2+"0"
WPT_array[14]=Dec_lat2 DIG 1+"0"
WPT_array[15]=Dec_lat2 DIG 0+"0"
WPT_array[16]=","
WPT_array[17]=S_byte
WPT_array[18]=","
WPT_array[19]=Dec_long1 Dig 4+"0"
WPT_array[20]=Dec_long1 Dig 3+"0"
WPT_array[21]=Dec_long1 Dig 2+"0"
WPT_array[22]=Dec_long1 Dig 1+"0"
WPT_array[23]=Dec_long1 Dig 0+"0"
WPT_array[24]="."
WPT_array[25]=Dec_long2 Dig 3+"0"
WPT_array[26]=Dec_long2 Dig 2+"0"
WPT_array[27]=Dec_long2 Dig 1+"0"
WPT_array[28]=Dec_long2 Dig 0+"0"
WPT_array[29]=","
WPT_array[30]=E_byte
WPT_array[31]=","
WPT_array[32]=TracID Dig 2+"0"
WPT_array[33]=TracID Dig 1+"0"
WPT_array[34]=TracID Dig 0+"0"
WPT_array[35]=","
WPT_array[36]="*"

cksum=0
for p = 1 to 35
cksum = cksum^(WPT_array[p])
Next P
Serout2 AGPSout, 16572, [Str WPT_array\37, HEX Cksum,13,10]

If anyone has a shorter way to do this, please share!

Tom

Art
- 5th July 2005, 00:56
I'll have a go,

'mode 188 is 4800 baud @ 4MHz.


'
SendByte:
serout2 portwhatever,188,[array_byte] 'send array byte
return
'
cksum = 0
array_byte = "$" 'send "$" qualifier
gosub SendByte '
For index = 1 to 35 '
array_byte = WPT_array[index] 'copy array byte to serial buffer
gosub SendByte 'send data byte
cksum = cksum ^ array_byte 'calc checksum
Next index '
array_byte = "*" '
gosub SendByte '
array_byte = cksum 'load checksum into serial buffer
gosub SendByte 'send checksum
'

Cheers, Art.

acjacques
- 6th June 2015, 22:24
I have followed the the suggestion and i wrote this code that is now working in the magnetic compass.
heading is my compass variable (001 ~359)
crc is the nmea checksum

crccalc:
crc= "H"^"D"^"M"^"," ^ ((heading DIG 0)+"0") ^ ((heading DIG 1)+ "0") ^ ((heading DIG 2)+"0")^"."^ "0"
Return

the output is like this:
$HDM,279.0*4F


acjacques