Share My Creation NMEA Checksum

I was looking at the forum and noticed a NMEA checksum routine in the BASIC4PPC and thought i would create a B4A routine . The code is below and the attached ZIP file is the source.

Not sure if it is any use to anyone

Enjoy

B4X:
'Activity module
Sub Process_Globals
   'These global variables will be declared once when the application starts.
   'These variables can be accessed from all modules.
End Sub

Sub Globals
   'These global variables will be redeclared each time the activity is created.
   'These variables can only be accessed from this module.
   Dim Button1 As Button
   Dim EditText1 As EditText
   Dim Label1 As Label
   Dim Label2 As Label
   Dim RadioButton1 As RadioButton
   Dim RadioButton2 As RadioButton
   Dim RadioButton3 As RadioButton
End Sub
Sub Activity_Create(FirstTime As Boolean)
   Activity.LoadLayout ("display")
End Sub
Sub Activity_Resume
End Sub
Sub Activity_Pause (UserClosed As Boolean)
End Sub
Sub NMEA_Checksum(NMEA As String)
Dim stPos As Int, spPos As Int, a As Int, checksum As Int, charInt As Int,chk As String 
a=0
Do While a<NMEA.Length-1
   If NMEA.CharAt(a)="$" AND stPos=0 Then stPos=a+1
   If NMEA.CharAt(a)="*" AND spPos=0 Then spPos=a-1
   If stPos<>0 AND spPos<>0 Then a=NMEA.Length-2
   a=a+1
Loop
checksum=0 
If stPos<>0 AND spPos<>0 AND spPos>stPos Then 
   For a=stPos To spPos
      charInt = Asc(NMEA.CharAt(a))
      checksum = Bit.Xor(checksum,charInt)
   Next
   Return Bit.ToHexString(checksum).ToUpperCase
Else
   Return Null
End If
End Sub
Sub Button1_Click
Dim ret As String 
   ret = NMEA_Checksum(EditText1.Text)
If ret = Null Then 
   Label2.Text="Checksum: NULL"
Else
   If ret.Length =1 Then ret="0" & ret
   Label2.Text="Checksum: " & ret
End If
End Sub
Sub RadioButton3_CheckedChange(Checked As Boolean)
   EditText1.Text =RadioButton3.Text 
End Sub
Sub RadioButton2_CheckedChange(Checked As Boolean)
   EditText1.Text =RadioButton2.Text 
End Sub
Sub RadioButton1_CheckedChange(Checked As Boolean)
   EditText1.Text =RadioButton1.Text 
End Sub
 

Attachments

  • NMEA Checksum.zip
    7.3 KB · Views: 603

Stulish

Active Member
Licensed User
Longtime User
Slight Change

I have changed the Checksum code to what is below, as i didn't realise there was a String.LastIndexOf command, it still works correctly but gets rid of the For/Next loop looking for the start and end of sentence


B4X:
Sub NMEA_Checksum(NMEA As String)
Dim stPos As Int, spPos As Int, a As Int, checksum As Int, charInt As Int,chk As String 
a=0
stPos = NMEA.LastIndexOf ("$")+1
spPos = NMEA.LastIndexOf ("*")-1
checksum=0 
If stPos<>0 AND spPos<>0 AND spPos>stPos Then 
   For a=stPos To spPos
      charInt = Asc(NMEA.CharAt(a))
      checksum = Bit.Xor(checksum,charInt)
   Next
   Return Bit.ToHexString(checksum).ToUpperCase
Else
   Return Null
End If
End Sub
 

PD5DJ

Member
Licensed User
Longtime User
Hi,

I was searching how to calculate the Checksum for a NMEA sentence and found your posts..

How is the checksum be calculated.. or what is calculated?
I never understood that.. :eek:

For example.. i am trying to make a little application that displays a valid $GPRMC sentence from the variables below..

I have the following variables:

Time_hours
Time_minutes
Time_seconds
Lattitude_hours
Lattitude_minutes
Latttitude_seconds
Lat_hems
Longitude_hours
Longitude_minutes
Longitude_seconds
Longitude_hems
Bearing
Speed
Date_Day
Date_Month
Date_Year

Any hints how to calculate the checksum with these parameters?
:sign0163:

Thanks in advance!

This is a little testcode im testing with..
I have a string that cointains a full GPRMC sentence.. and i know the Checksum is 1A
But the output through your code gives 1F.. what am i missing here?

B4X:
'Activity module
Sub Process_Globals
   'These global variables will be declared once when the application starts.
   'These variables can be accessed from all modules.

End Sub

Sub Globals
   'These global variables will be redeclared each time the activity is created.
   'These variables can only be accessed from this module.
   Dim gpstext As String : gpstext = "$GPRMC,040302.663,A,3939.7,N,10506.6,W,0.27,358.86,200804,,*1A"
   Dim temp As String
   Dim EditText1 As EditText
   Dim Label1 As Label
End Sub

Sub Activity_Create(FirstTime As Boolean)
   Activity.LoadLayout("StartScherm")
   
End Sub

Sub Activity_Resume

End Sub

Sub Activity_Pause (UserClosed As Boolean)

End Sub


Sub NMEA_Checksum(NMEA As String)
Dim stPos As Int, spPos As Int, a As Int, checksum As Int, charInt As Int,chk As String 
a=0

stPos = NMEA.LastIndexOf ("$")+1
spPos = NMEA.LastIndexOf ("*")-1
checksum=0 
If stPos<>0 AND spPos<>0 AND spPos>stPos Then 
    For a=stPos To spPos
        charInt = Asc(NMEA.CharAt(a))
        checksum = Bit.Xor(checksum,charInt)
    Next
    Return Bit.ToHexString(checksum).ToUpperCase
Else
    Return Null
End If
   
End Sub
Sub Calc_Click
   temp = NMEA_Checksum(gpstext)
   Label1.Text="Checksum: " & temp
End Sub
 
Last edited:

Stulish

Active Member
Licensed User
Longtime User
if you use an online checker program like - NMEA MTK checksum calculator

then the output come out as 1F as in my example, i have used this code with many commercial products and it works fine.

To calculate the checksum you parse all characters between $ and * from the NMEA sentence and just XOR the first character with the next character, until the end of the string.

B4X:
Do While a<NMEA.Length-1
    If NMEA.CharAt(a)="$" AND stPos=0 Then stPos=a+1
    If NMEA.CharAt(a)="*" AND spPos=0 Then spPos=a-1
    If stPos<>0 AND spPos<>0 Then a=NMEA.Length-2
    a=a+1
Loop

the code above just looks through the string (because not all serial data in the buffer will start at $ and end with the *checksum), and find the position after the star (stPos) and the position before the * (spPos).

B4X:
checksum=0 
If stPos<>0 AND spPos<>0 AND spPos>stPos Then 
    For a=stPos To spPos
        charInt = Asc(NMEA.CharAt(a))
        checksum = Bit.Xor(checksum,charInt)
    Next
    Return Bit.ToHexString(checksum).ToUpperCase
Else
    Return Null
End If

The next part of the code above will then check that the start and stop position are actually valid and then loop from beginning to end, first assigning the ASCII value of the character to the charInt variable and then xOr'ing the checksum variable.

I hope this helps, if not let me know and i will try to give some more detail.

Regards

Stu
 
Last edited:

Stulish

Active Member
Licensed User
Longtime User
I take it you already have the breakdown of the RMC sentence but i thought i would post for clarity:

RMC - Recommended Minimum Specific GNSS Data

Time, date, position, course and speed data provided by a GNSS navigation receiver. This sentence is transmitted at intervals not exceeding 2-seconds and is always accompanied by RMB when a destination waypoint is active. RMC and RMB are the recommended minimum data to be provided by a GNSS receiver. All data fields must be provided, null fields used only when data is temporarily unavailable.

$--RMC,hhmmss.ss,A,llll.ll,a,yyyyy.yy,a,x.x,x.x,xxxxx,x.x,a,a*hh<CR><LF>

Field Names:
1. UTC of Position fix
2. Status (A=Data valid, V=Navigation receiver warning)
Note: The positioning system Mode Indicator field supplements the positioning system Status field, the Status field shall be set to V = Invalid for all values of Indicator mode except for A = Autonomous and D = Differential. The positioning system Mode Indicator and Status fields shall not be null fields.
3. Latitude
4. Latitude hemisphere (N or S)
5. Longitude
6. Longitude hemisphere (E or W)
7. Speed over the ground (in Knots)
8. course over the Ground (in degrees True)
9. Date (ddmmyy)
10. Magnetic Variation
11. degrees E/W
Note: Easterly variation (E) subtracts from True course. Westerly variation (W) adds to True course
12. Mode Indicator
Note:positioning system Mode Indicator:
A = Autonomous mode
D = Differential mode
E = Estimated (dead reckoning) mode
M = Manual input mode
S = Simulator mode
N = Data not valid​

 

PD5DJ

Member
Licensed User
Longtime User
Hi,

Thanks for the excellent explanation!

I really understand the whole sequence much better now :)

I played with it, and it works flawlessly now :)

Many thanks!!!
 

Stulish

Active Member
Licensed User
Longtime User
No problems, glad to be of help :)
 
Top