Access your GPS Radio with VB.Net code

What follows is the code for a module that can be inserted into a VB.net project. Call the sub with the comm port that the GPS radio is on and you are set. Also add a Serial Port Control to your form and name it “serialPort”. Timeout is required in case an incorrect serial port has been specified.

Programming note: Even with the timeout set in the code, the application will lock up if an incorrect, but active comm port has been specified. If you know of a fix post it in the comments.

Imports System
Imports System.IO.Ports

Module gps

    Public strLatitude As String = ""
    Public strLongitude As String = ""

    Public Sub queryGPS(ByVal cPort As String)
        Dim loopCount As Integer = 0
        Dim GPSOutput As String = ""
        Dim GPSGPRMCStr As String = ""
        Dim newLineStr As String = "$"
        Dim aStrSplitItems() As String
        Dim NSHemi As String = ""
        Dim EWHemi As String = ""
        Dim EW As Integer = 0
        Dim NS As Integer = 0
        Dim commQuit As Boolean = False
        Dim portClosed As Boolean = False
        Dim dblLatitude As Double = 0
        Dim dblLongitude As Double = 0
        Dim wsLatitude As String = ""
        Dim wsLongitude As String = ""
        'Set sentence to parse from GPS Output. Use GPRMC GPGLL, or GPGGA
        Dim strSentence As String = "GPRMC"

        'Reset coordinate variables()
        strLatitude = ""
        strLongitude = ""

        On Error GoTo Errhandler

        'Calls Serial Port Control on main form. Add Serial Port Control to form and name it "serialPort"
        'Timeout is required in case an incorrect serial port has been specified. Application will freeze
        'if timeout is missing or too lengthy.
        frmMain.serialPort = New SerialPort("COM" & cPort, 4800, Parity.None, 8, StopBits.One)
        frmMain.serialPort.ReadTimeout = 5
        frmMain.serialPort.Open()

readLine:
        Dim cCount As Integer = 0

        If portClosed = True Then
            frmMain.serialPort.Open()
            portClosed = False
        End If
        'Read GPS data from Device - Geographic Position, Latitude/Longitude
        GPSOutput = frmMain.serialPort.ReadLine.ToString
        GPSGPRMCStr = GPSOutput

        'Test string for debugging without a good GPS signal
        'GPSGPRMCStr = "GPRMC,174607.000,A,3411.3450,N,07946.0365,W,0.44,160.26,020910,,*12"

        If GPSGPRMCStr.Contains(strSentence) Then
            commQuit = True

            For i = 1 To Len(GPSGPRMCStr.ToString)
                If Mid$(GPSGPRMCStr.ToString, i, 1) = "," Then cCount = cCount + 1

                Select Case strSentence 'Set the line the program reads in the DIM statement above
                    Case "GPRMC"
                        Select Case cCount
                            Case 3 'Start collecting latitude
                                strLatitude = strLatitude & Mid$(GPSGPRMCStr.ToString, i, 1)
                            Case 4 'Get Hemisphere
                                NSHemi = NSHemi & Mid$(GPSGPRMCStr.ToString, i, 1)
                            Case 5 'Start Collecting longitude
                                strLongitude = strLongitude & Mid$(GPSGPRMCStr.ToString, i, 1)
                            Case 6 'Get Hemisphere
                                EWHemi = EWHemi & Mid$(GPSGPRMCStr.ToString, i, 1)
                        End Select
                    Case "GPGGA"
                        Select Case cCount
                            Case 2 'Start collecting latitude
                                strLatitude = strLatitude & Mid$(GPSGPRMCStr.ToString, i, 1)
                            Case 3 'Get Hemisphere
                                NSHemi = NSHemi & Mid$(GPSGPRMCStr.ToString, i, 1)
                            Case 4 'Start Collecting longitude
                                strLongitude = strLongitude & Mid$(GPSGPRMCStr.ToString, i, 1)
                            Case 5 'Get Hemisphere
                                EWHemi = EWHemi & Mid$(GPSGPRMCStr.ToString, i, 1)
                        End Select
                    Case "GPGLL"
                        Select Case cCount
                            Case 1 'Start collecting latitude
                                strLatitude = strLatitude & Mid$(GPSGPRMCStr.ToString, i, 1)
                            Case 2 'Get Hemisphere
                                NSHemi = NSHemi & Mid$(GPSGPRMCStr.ToString, i, 1)
                            Case 3 'Start Collecting longitude
                                strLongitude = strLongitude & Mid$(GPSGPRMCStr.ToString, i, 1)
                            Case 4 'Get Hemisphere
                                EWHemi = EWHemi & Mid$(GPSGPRMCStr.ToString, i, 1)
                        End Select
                End Select
            Next
        Else
            GoTo readLine
        End If
        strLatitude = Microsoft.VisualBasic.Right(strLatitude, Len(strLatitude) - 1)
        NSHemi = Microsoft.VisualBasic.Right(NSHemi, Len(NSHemi) - 1)
        strLongitude = Microsoft.VisualBasic.Right(strLongitude, Len(strLongitude) - 1)
        EWHemi = Microsoft.VisualBasic.Right(EWHemi, Len(EWHemi) - 1)

        If NSHemi <> "" Then
            If NSHemi = "N" Then NSHemi = "" Else NSHemi = "-"
            If EWHemi = "E" Then EWHemi = "" Else EWHemi = "-"
        End If

        'Convert Lat and Long to decimel
        '********************************************************************
        'Strip leading Zeros
        dblLatitude = CDbl(strLatitude.ToString)
        dblLongitude = CDbl(strLongitude.ToString)
        'Add polarity
        If NSHemi = "-" Then
            dblLatitude = dblLatitude * -1
            NS = -1
        Else
            NS = 1
        End If
        If EWHemi = "-" Then
            dblLongitude = dblLongitude * -1
            EW = -1
        Else
            EW = 1
        End If

        'Move decimel place two places to the left
        dblLatitude = dblLatitude / 100
        dblLongitude = dblLongitude / 100

        'Get values left of decimel
        Dim leftLat As Integer = Math.Abs(dblLatitude)
        Dim leftLong As Integer = Math.Abs(dblLongitude)

        'Get values right of decimel
        Dim rightLat As Double = Math.Abs(dblLatitude) - Math.Abs(leftLat)
        Dim rightLong As Double = Math.Abs(dblLongitude) - Math.Abs(leftLong)

        'Convert to minutes
        rightLat = (rightLat * 100) / 60
        rightLong = (rightLong * 100) / 60

        'Lat/Long in decimel, in case you need decimel degrees instead of degrees/minutes/seconds.
        wsLatitude = Trim(Str(CDbl(strLatitude) * NS))
        wsLongitude = Trim(Str(CDbl(strLongitude) * EW))

        'Lat/long in Degrees/Minutes/Seconds in decimel form
        strLatitude = Trim(Str((leftLat + rightLat) * NS))
        strLongitude = Trim(Str((leftLong + rightLong) * EW))

        frmMain.serialPort.ReadBufferSize = 0
        frmMain.serialPort.Close()
        portClosed = True

        '*********************************************************************
        'Comment out else section when deployed. Work with results in main sub
        '*********************************************************************
        'Sometimes reception is poor and it takes more than one pass of the data to get a fix
        'This section forces another read of the GPS device when the coordinates are null or
        'contain zeros. Note: The application as written will fail on the prime meridian when
        'at the equator.
        If strLatitude = "" Or strLongitude = "" Or strLatitude = "0" Or strLongitude = "0" And commQuit = True Then
            loopCount = loopCount + 1
            If loopCount > 10 Then
                MsgBox("The GPS device is currently not getting a fix, please try again later." _
                      & Chr(10) & GPSOutput, vbOKOnly, "Satellite Communication Unavailable")
                Exit Sub
            Else
                GoTo readLine
            End If
        Else
            'Access web service from arc to return a list of addresses within a certain range of the inspector's location.
            'Web Service is currently in SC stateplane.

            'A google test.
            'System.Diagnostics.Process.Start("http://maps.google.com/maps?q=" & strLatitude & "%2C" & strLongitude)
        End If
        '********************************************************************
        Exit Sub
Errhandler:

        Select Case Err.Number
            Case 5
                Resume Next
            Case 13
                'MsgBox(Err.Number & " " & Err.Description)
                Resume Next
            Case 57
                'MsgBox(Err.Number & " " & Err.Description)
                MsgBox("Comm Port not available", MsgBoxStyle.Exclamation, "Communication Error.")
                Exit Sub
            Case 91
                'MsgBox(Err.Number & " " & Err.Description)
                Resume Next
            Case 8002
                'GPSComm.PortOpen = False
                MsgBox("Comm Port not available", MsgBoxStyle.Exclamation, "Communication Error.")
                'GPSComm.PortOpen = True
                Resume Next
                Exit Sub
            Case Else
                MsgBox(Err.Number & " " & Err.Description)
                Resume
                Resume Next
        End Select
    End Sub
End Module

 

Advertisements
Previous Post
Leave a comment

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: