[Home]  [Edit this page]  [Recent Changes]  [Special Pages]  [Help
Wireless Atomic Time

Wireless Atomic Time

Time is the cornerstone of GPS technology because distances are measured at the speed of light. Each GPS satellite contains four atomic clocks which it uses to time its radio transmissions within a few nanoseconds. One fascinating feature is that with just a few lines of code, these atomic clocks can be used to synchronize a computer’s clock with millisecond accuracy. The second word of the $GPRMC sentence, “040302.663,” contains satellite-derived time in a compressed format. The first two characters represent hours, the next two represent minutes, the next two represent seconds, and everything after the decimal place is milliseconds. So, the time is 4:03:02.663 AM. However, satellites report time in universal time (GMT+0), so the time must to be adjusted to the local time zone.

[VB.NET]
'********************************************************
'**  Support for satellite-derived time
'********************************************************
Public Class NmeaInterpreter
  ' Raised when the current location has changed
  Public Event PositionReceived(ByVal latitude As String, 
                                ByVal longitude As String)
  Public Event DateTimeChanged(ByVal dateTime As DateTime)
  ' Processes information from the GPS receiver
  Public Function Parse(ByVal sentence As String) As Boolean
    ' Discard the sentence if its checksum does not match our     
    ' calculated checksum
    If Not IsValid(sentence) Then Return False
    ' Look at the first word to decide where to go next
    Select Case GetWords(sentence)(0)
      Case "$GPRMC"      ' A "Recommended Minimum" sentence was found!
        Return ParseGPRMC(sentence)
      Case Else
        ' Indicate that the sentence was not recognized
        Return False
    End Select
  End Function
  ' Divides a sentence into individual words
  Public Function GetWords(ByVal sentence As String) As String()
    Return sentence.Split(","c)
  End Function
  ' Interprets a $GPRMC message
  Public Function ParseGPRMC(ByVal sentence As String) As Boolean
    ' Divide the sentence into words
    Dim Words() As String = GetWords(sentence)
    ' Do we have enough values to describe our location?
    If Words(3) <> "" And Words(4) <> "" And Words(5) <> "" And _
       Words(6) <> "" Then
      ' Yes. Extract latitude and longitude
      Dim Latitude As String = Words(3).Substring(0, 2) & "°" ' Append hours
      Latitude = Latitude & Words(3).Substring(2) & """"    ' Append minutes
      Latitude = Latitude & Words(4)     ' Append the hemisphere
      Dim Longitude As String = Words(5).Substring(0, 3) & "°" ' Append hours
      Longitude = Longitude & Words(5).Substring(3) & """"    ' Append minutes
      Longitude = Longitude & Words(6)     ' Append the hemisphere
      ' Notify the calling application of the change
      RaiseEvent PositionReceived(Latitude, Longitude)
    End If
    ' Do we have enough values to parse satellite-derived time?
    If Words(1) <> "" Then
      ' Yes. Extract hours, minutes, seconds and milliseconds
      Dim UtcHours As Integer = CType(Words(1).Substring(0, 2), Integer)
      Dim UtcMinutes As Integer = CType(Words(1).Substring(2, 2), Integer)
      Dim UtcSeconds As Integer = CType(Words(1).Substring(4, 2), Integer)
      Dim UtcMilliseconds As Integer
      ' Extract milliseconds if it is available
      If Words(1).Length > 7 Then           
        UtcMilliseconds = CType(Words(1).Substring(7), Integer)      
      End If
      ' Now build a DateTime object with all values
      Dim Today As DateTime = System.DateTime.Now.ToUniversalTime
      Dim SatelliteTime As New System.DateTime(Today.Year, Today.Month, _
        Today.Day, UtcHours, UtcMinutes, UtcSeconds, UtcMilliseconds)
      ' Notify of the new time, adjusted to the local time zone
      RaiseEvent DateTimeChanged(SatelliteTime.ToLocalTime)
    End If
    ' Indicate that the sentence was recognized
    Return True
  End Function
  ' Returns True if a sentence's checksum matches the calculated checksum
  Public Function IsValid(ByVal sentence As String) As Boolean
    ' Compare the characters after the asterisk to the calculation
    Return sentence.Substring(sentence.IndexOf("*") + 1) = _
                                                   GetChecksum(sentence)
  End Function
  ' Calculates the checksum for a sentence
  Public Function GetChecksum(ByVal sentence As String) As String
    ' Loop through all chars to get a checksum
    Dim Character As Char
    Dim Checksum As Integer
    For Each Character In sentence
      Select Case Character
        Case "$"c
          ' Ignore the dollar sign
        Case "*"c
          ' Stop processing before the asterisk
          Exit For
        Case Else
          ' Is this the first value for the checksum?
          If Checksum = 0 Then
            ' Yes. Set the checksum to the value
            Checksum = Convert.ToByte(Character)
          Else
            ' No. XOR the checksum with this character's value
            Checksum = Checksum Xor Convert.ToByte(Character)
          End If
      End Select
    Next
    ' Return the checksum formatted as a two-character hexadecimal
    Return Checksum.ToString("X2")
  End Function
End Class


last edited (December 20, 2004) by jperson, Number of views: 3018, Current Rev: 3 (Diff)

[Edit this page]  [Page history]  [What links here]  [Discuss this topic]  [Printer Friendly]  

Members

Username:

Password:


Register
Forgot Password?




Programmers Heaven - for .NET, Java, C/C++ and WEB Developers!
© 1996-2008 Community Networks Ltd. All rights reserved. Reproduction in whole or in part, in any form or medium without express written permission is prohibited. Violators of this policy may be subject to legal action. Please read Terms Of Use and Privacy Statement for more information. Development by Tore Nestenius at .NET Consultant - Synchron Data.