Android Question Inaccurate GSP-time with Garmin-GLO-2 (Bluetooth-GPS-Receiver)

Filippo

Expert
Licensed User
Longtime User
Hi ,

I have bought a Garmin GLO 2 for testing.
I can use it to access and analyze all NMEA data.
Only one thing is not working properly and that is the GPS time! It deviates from the internal GPS time by 3-4 seconds and I don't know where this is coming from.
For the GSP time I use the NMEA-Sentence $GPGGA.

Maybe I have a mistake somewhere and don't realize it, or someone has a better solution.
Or it is simply because the NMEA sentences cannot provide the exact GPS time.

This picture shows the correct GSP time of a cell phone that uses the internal GPS receiver:
1733745773195.png


This picture shows the inaccurate GSP time of a cell phone with the Garmin GLO-2 GPS receiver:
1733745828619.png



This below is the classe(clsNMEA) used by me:
B4X:
#Event: SatelliteReceived (GPSSat As List)
#Event: LocationChanged (location1 As Location)

Sub Class_Globals
    'NMEA-Variablen
    Private satelliteNumber As Short
    Private pseudoRandomCode As Short
    Private azimuth As Short
    Private elevation As Short
    Private noOfMessages As Short
    Private gPGSVsequence As Short
    Private lstGPSSat As List
    Private DefaultTimeFormat As String
    Private offspan As Double
    Private oldLatitude, oldLongitude As Double

    Type myGPSSatellite(azimuth As Float, Prn As Int, Snr As Float, elevation As Float, UsedInFix As Boolean)

    Private location1 As Location
    
    Private mEventName As String 'ignore
    Private mCallBack As Object 'ignore
End Sub

'Initializes the object. You can add parameters to this method if needed.
Public Sub Initialize(Callback As Object, EventName As String)
    mEventName = EventName
    mCallBack = Callback

    DefaultTimeFormat = DateTime.TimeFormat
    offspan = DateTime.GetTimeZoneOffsetAt(DateTime.now) * DateTime.TicksPerHour
    
    lstGPSSat.Initialize
    location1.Initialize
End Sub

' Processes information from the GPS receiver
Public Sub ParseSentence(sentence As String) As Boolean
    Dim Ps As Boolean
    ' Discard the sentence if its checksum does not match calculated checksum
    If Not (IsValid(sentence)) Then
        Return False
    End If

    Log("sentence=" & sentence)

    ' Divide the sentence into words and Look at the first word to decide where to go next
    Dim words() As String = GetWords(sentence)
        
    ' Divide the sentence into words and Look at the first word to decide where to go next
    Select Case words(0)
        Case "$GPGSV", "$GLGSV"     ' A "Satellites in View" sentence was recieved
            ' Indicate that the sentence was recognised
            Ps = ParseGPGSV(words)
        Case "$GPGGA", "$GNGGA"     ' Global positioning system fixed data
            ' Indicate that the sentence was recognised
            Ps = Parse_GPGGA(words)
'        Case "$GPRMC", "$GNRMC"    ' A "Recommended Minimum" sentence was found!
'            ' Indicate that the sentence was recognised
'            Ps = Parse_GPRMC(words)
        Case "$GPVTG"    ' Track Made Good and Ground Speed.
            Ps = Parse_GPVTG(words)
        Case Else
            ' Indicate that the sentence was not recognised
            Ps = False
    End Select

    If location1.Latitude > 0 And location1.Speed > 0 And location1.Time > 0 Then
        If oldLatitude <> location1.Altitude Or oldLongitude <> location1.Longitude Then
            oldLatitude = location1.Altitude
            oldLongitude = location1.Longitude

            CallSub2(mCallBack, mEventName & "_LocationChanged", location1)
            Dim location1 As Location
            location1.Initialize
        End If           
    End If

    Return Ps
End Sub

Private Sub IsValid(sentence As String) As Boolean
    ' Compare the characters after the asterisk to the calculation
    Return GetChecksum(sentence)
End Sub

' Calculates the checksum for a sentence
Private Sub GetChecksum(sentence As String) As Boolean
    Dim checksum As Int
    Dim startIndex, endIndex As Int
    Dim givenChecksum As Int
    
    startIndex = sentence.IndexOf("$") + 1
    endIndex = sentence.IndexOf("*")
    
    If startIndex <= 0 Or endIndex <= 0 Or endIndex <= startIndex Then
        Return False
    End If
    
    checksum = Asc(sentence.CharAt(startIndex))
    
    For i = startIndex + 1 To endIndex - 1
        checksum = Bit.Xor(checksum, Asc(sentence.CharAt(i)))
    Next
    
    Try
        givenChecksum = Bit.ParseInt(sentence.SubString(endIndex + 1), 16)
    Catch
        Return False
    End Try
    
    Return checksum = givenChecksum
End Sub

Private Sub GetWords(sentence As String) As String()
    'strip off final * + checksum
    Dim wrd() As String
    If sentence.Length > 3 Then
        sentence = Left(sentence, sentence.Length - 3)
    End If
    'Divide sentence into individual words
    wrd = Regex.Split(",", sentence)
    Return wrd
End Sub

Private Sub ParseGPGSV(words() As String) As Boolean
    ' number of messgaes in complete message
    If Not (strEmpty(words(1))) Then
        noOfMessages = words(1)
    End If
    ' GPGSV sequence
    If Not (strEmpty(words(2))) Then
        gPGSVsequence = words(2)
    End If
 
    'Neues GPS-Status
    If noOfMessages > gPGSVsequence And gPGSVsequence = 1 Then
        lstGPSSat.Clear()
    End If

    'Each sentence contains four blocks of satellite information.
    'Read each block and report each satellite's information
    Dim count As Short
    For count = 1 To 4
        'identify satellite
        If gPGSVsequence <> 0 Then satelliteNumber = (gPGSVsequence - 1) * 4 + count
        ' Does the sentence have enough words to analyse?
        If words.Length - 1 >= (count * 4 + 3) Then
            ' Yes.  Proceed with analysing the block.  Does it contain any information?

            If Not (strEmpty(words(count * 4))) And Not (strEmpty(words(count * 4 + 1))) _
                              And Not (strEmpty(words(count * 4 + 2))) _
                              And Not (strEmpty(words(count * 4 + 3))) Then
                ' Yes. Extract satellite information and report it
                pseudoRandomCode = words(count * 4)
                elevation = words(count * 4 + 1)
                azimuth = words(count * 4 + 2)
                'signalToNoiseRatio = words(count * 4 + 3).Replace("*","") 'Änderung von mir

                Dim GPSSat As myGPSSatellite
                GPSSat.Initialize
                GPSSat.Azimuth = azimuth
                GPSSat.Prn = satelliteNumber
                GPSSat.Snr = pseudoRandomCode
                GPSSat.Elevation = elevation
                GPSSat.UsedInFix = True

                lstGPSSat.Add(GPSSat)
            End If
        End If
    Next

    If noOfMessages = gPGSVsequence Then
        CallSub2(mCallBack, mEventName & "_SatelliteReceived", lstGPSSat)
    End If

    ' Indicate that the sentence was recognised
    Return True
End Sub

' Interprets a $GPGGA message
Private Sub Parse_GPGGA(words() As String) As Boolean
    ' Divide the sentence into words
    ' satellite-derived time?
    If Not(strEmpty(words(1))) And words(6) > 0 Then ParseTime(words(1))
    ' location?
    If Not(strEmpty(words(2))) And Not (strEmpty(words(4))) And words(6) > 0 And words(7) > 6 Then ParseLatLon(words(2), words(4))
    'GPS quality indicator (0=invalid; 1=GPS fix; 2=Diff. GPS fix)
    If Not(strEmpty(words(6))) Then ParseGPSQuality(words(6))
    'HDOP - Horizontal dilution of position
    If Not(strEmpty(words(8))) Then ParseAccuracy(words(8))
    'Altitude
    If Not(strEmpty(words(9))) And IsNumber(words(9)) Then ParseAltitude(words(9))
    'Altitude Units
    Return True
End Sub

Private Sub Parse_GPRMC(words() As String) As Boolean
    ' Divide the sentence into words
    ' satellite-derived time?
    If Not(strEmpty(words(1))) Then ParseTime(words(1))
    ' location?
    If Not(strEmpty(words(3))) And Not (strEmpty(words(5))) Then ParseLatLon(words(3), words(5))
    'Speed over the ground in knots
    If Not(strEmpty(words(7))) Then ParseSpeed(words(7))

    Return True
End Sub

Private Sub Parse_GPVTG(words() As String) As Boolean
    If Not(strEmpty(words(5))) Then ParseSpeed(words(5))
    ' Indicate that the sentence was recognised
    Return True
End Sub

Private Sub ParseGPSQuality(word As String)
    location1.Accuracy = word
End Sub

Private Sub ParseAccuracy(word As String)
    location1.Accuracy = word
End Sub

Private Sub ParseSpeed(word As String)
    location1.Speed = word / 1.852
End Sub

Private Sub ParseTime(word As String)
    Select word.Length
        Case 6
            DateTime.TimeFormat = "HHmmss"
        Case 8
            DateTime.TimeFormat = "HHmmss.S"
        Case 9
            DateTime.TimeFormat = "HHmmss.SS"
        Case 10
            DateTime.TimeFormat = "HHmmss.SSS"
    End Select
    
    location1.Time = DateTime.TimeParse(word) + offspan
    DateTime.TimeFormat = DefaultTimeFormat
End Sub

Private Sub ParseLatLon(latWord As String, lonWord As String)
    Dim myval1 As Double
    Dim myval2 As Double

    ' Parse Latitude
    myval1 = latWord.SubString2(0, 2) ' First two characters
    myval2 = latWord.SubString(2) ' Remaining characters
    myval2 = myval2 / 60.0
    location1.Latitude = NumberFormat(myval1 + myval2, 1, 14)

    ' Parse Longitude
    myval1 = lonWord.SubString2(0, 3) ' First three characters
    myval2 = lonWord.SubString(3) ' Remaining characters
    myval2 = myval2 / 60.0
    location1.Longitude = NumberFormat(myval1 + myval2, 1, 15)
End Sub

Private Sub ParseAltitude(Word As String) 'ignore
    location1.Altitude = Word
End Sub

Private Sub strEmpty(st As String) As Boolean
    If st.Length = 0 Or st.Trim = "" Then Return True
    Return False
End Sub

Private Sub Left(Text As String, Length As Int) As String
    If Length>Text.Length Then Length=Text.Length
    Return Text.SubString2(0, Length)
End Sub
 

agraham

Expert
Licensed User
Longtime User
The problem may be that the time you are parsing is the time that the fix was taken, not the time that the $GPGGA sentence was received by your app. I think that the $GPZDA sentence might be what you need for the actual time but the Garmin may not output that - I don't know.
 
Upvote 0

Filippo

Expert
Licensed User
Longtime User
Hi @agraham ,

Thank you for your reply.
Yes, as you say, Garmin does not release this Sentence.
Too bad, I bought this device because many of my customers are very happy with this GPS receiver, but if you can't get accurate GPS time with it, then it's not so good.

The 6 Sentence should also be issued by Garmin, but they are not.
1733759018858.png
 
Upvote 0
Top