News:

Let's find out together what makes a PIC Tick!

Main Menu

GPS and decoding NMEA Sentence Decoding

Started by midali, Sep 18, 2021, 01:34 PM

Previous topic - Next topic

midali

Hi to all.
1. I have problems with reading the coordinates in the sense that oscillate the values . For example, LA = ( xxxx.5903 to xxxx.6054) and LO = (xxxxx.0730 to xxxxx.0760) . I tried with Ublox M6N and Ublox M8N .What can be the causes ?

2. I used this code for read GPGGA sentence, but I think that it's complicated . Any examples for a easy sentences reading are welcome.

Include "lcd.bas"
Cls
                         
                                                   
PORTC.7 = 1
Symbol GPS_RX = PORTC.7

'---GPGGA---
Dim H       As Byte        ' HOLDS THE HOUR   
Dim M       As Byte        ' HOLDS THE MINUTES   
Dim S       As Byte        ' HOLDS SECONDS   
Dim ND      As Word        ' HOLDS NORTH/SOUTH DEGREE   
Dim NM      As Byte        ' HOLDS NORTH/SOUTH MINUTES   
Dim NMD     As Word        ' HOLDS NORTH/SOUTH MINUTES DECIMAL   
Dim WD      As Word        ' HOLDS EAST/WEST DEGREE   
Dim WM      As Byte        ' HOLDS EAST/WEST MINUTES   
Dim WMD     As Word        ' HOLDS EAST/WEST MINUTES DECIMAL   
Dim NS      As Byte        ' POSITION NORTH OR SOUTH   
Dim EW      As Byte        ' POSITION EAST OR WEST   
Dim FIX     As Byte        ' SIGNAL QUALITY   
Dim NSAT    As Byte        ' NUMBER OF SATELLITES USED   
Dim ALT     As Byte        ' ALTITUDE WHOLE NUMBER   
Dim ALO     As Byte        ' ALTITUDE DECIMAL

Dim baud    As Word = 84
'$GPGGA,145856,4610.6101,N,02121.0619,E,1,04,1.5,127.6,M,-36.9,M,,,*59
Print At 1,1 , "WAIT.."
DelayMS 2000

'--------------------------MAIN-----------------------------
Main:
GoSub GPGGA

Print At 1,1 , "LA: " , Dec4 ND, ".", Dec4 NMD
Print At 2,1 , "LO: " , Dec5 WD, ".", Dec4 WMD

GoTo Main

'------------------------- GPGGA-----------------------------
GPGGA:
SerIn GPS_RX, baud,[Wait("$GPGGA,"),Dec2 H,Dec2 M,Dec2 S, Wait(","),_           
                                     Dec4 ND,Wait("."),Dec4 NMD,Wait(","),NS,Wait(","),_           
                                     Dec5 WD,Wait("."),Dec4 WMD,Wait(","),EW,Wait(","),_
                                     Dec1 FIX,Wait(","),_           
                                     Dec2 NSAT,Wait(","),Wait(","),Dec ALT,Wait("."),Dec ALO]                                         
Return

I was inspired from here : http://www.shantek.net/gps/NMEA_SentenceDecoding.html#gpgga

Thank you !

Craig

#1
Hello Midali

I am using a MQ8 From Ublox on a project, some of this code was on the old Forum which I
Changed to suit my needs and works very well. You can Download U-Center On the Ublox
Site for free and then check your GPS Readings through there it is very smart and works well.
https://www.u-blox.com/en/product/u-center

Regards
Craig



Device = 24FJ64GA004
'==========================================================================================
' Setup "USART's" - RS232 For GPS & PC Testing
' "LOWER" XTAL Speed & Switch PLL OFF - if INVERTING IS NOT Happening
' Setup the MAX-M8Q-UBLOX-GPS
'------------------------------------------------------------------------------------------
        Declare RSIn_Pin                        = PORTC.0                       ' Rx INPUT  - Pin Ublox Max8Q GPS on PORTC.2
        Declare RSOut_Pin                     = PORTC.1                       ' Tx OUTPUT - Pin Ublox Max8Q GPS on PORTC.1
        Declare Serial_Baud                    = 9600                            ' 9600 Baud Speed (default: 9600,8N1)
        Declare RSIn_Mode                    = 1                                  ' DATA MUST BE "NON-INVERTED = 1" When using PIC24FJ After It Goes Through the Max3232 Chip
                                                                                                 ' If INVERTING IS NOT Happening then "LOWER" Xtal Speed & Switch PLL OFF!!!!

'=======================================================================================
' Value extraction variables For GPS_UBlox
'---------------------------------------------------------------------------------------
        Dim BbLOOP                          As Byte                                ' General purpose loop Variable for GPS
        Dim EXTRACT_ITEM                As Byte
        Dim COMMA_COUNT            As Byte
        Dim CHARPOS                       As Byte
        Dim Char                               As Byte

'=====================================================
' Variables Used In UBlox_MAXM_Q8 -GPS
'---------------------------------------------------------------------------------------
        Dim DAY                                As Byte
        Dim MONTH                           As Byte
        Dim YEAR                                As Byte
        Dim HOURS                            As Byte
        Dim MINUTES                         As Byte
        Dim SECONDS                         As Byte
        Dim LAT_DEG                          As String * 20
        Dim LATITUDE_DEGREES         As Byte
        Dim LATITUDE_MINUTES        As Byte
        Dim LATITUDE_SECONDS       As Byte
        Dim LATITUDE_BEARING        As Byte
        Dim LONGITUDE_DEGREES    As Byte
        Dim LONGITUDE_MINUTES   As Byte
        Dim LONGITUDE_SECONDS   As Byte
        Dim LONGITUDE_BEARING    As Byte
        Dim FIX_TYPE                        As Byte
        Dim SATELLITES_IN_VIEW      As Byte
        Dim RX_BUFF [200]               As Byte
        Dim DATA_STRING [20]         As Byte
        Dim GPS_Counter                 As Byte
        Dim CompassLT                    As Byte                     ' Holds the "N" or "S" Direction of the GPS Compass
        Dim CompassLN                   As Byte                     ' Holds the "E" or "W" Direction of the GPS Compass
       
' Clear Variables
        GPS_Counter                       = 0                            ' Clear Variable GPS_Counter
        DirHold                               = 0
        CompassLT                         = 0
        CompassLN                           = 0

GoTo UBlox_GPS

'============================================================================
' UBlox - MAX M8Q - GPS/GNSS Module - RS232 Using The RCin Command
'============================================================================
UBlox_GPS:

GoTo MAIN_PROGRAM_LOOP                                      ' Jump over the subroutines               

'----------------------------------------------------------------------------
' [EXTRACT A VALUE BASED ON THE COMMA THAT IT FOLLOWS]
' Locates and extracts the value following the comma placed in EXTRACT_ITEM
' The extracted text is returned in array DATA_STRING with a NULL terminator
' If an invalid value is found, then 000000 will be returned in the array
'============================================================================

EXTRACT_THE_VALUE:                                                               
    StrN DATA_STRING = "0000000000000000000"             ' Fills String up and Clears it with Zeros!
    COMMA_COUNT = 0                                                      ' Reset the comma counting variable
    CHARPOS = 0                                                                  ' Start at the beginning of the array
    Repeat
        Char = RX_BUFF[CHARPOS]                                         ' Scan the array to parse
        If Char = "," Then Inc COMMA_COUNT                        ' Increment COMMA_COUNT if a comma is found
        If COMMA_COUNT = EXTRACT_ITEM Then                  ' Have we found the correct comma ?
            BbLOOP = 0                                                            ' Yes. So....
            Repeat                                                                     ' Form a loop
                Inc CHARPOS                                                       ' Skip over the comma and keep scanning the array
                Char = RX_BUFF[CHARPOS]                                 ' Extract the pieces of the value into CHAR
                If Char = 0 Then Break
                If Char = "," Then Break
                DATA_STRING[BbLOOP] = Char                           ' Fill DATA_STRING with the value for DATE!
                Inc BbLOOP                                                         ' Point to the next data piece
            Until CHARPOS >= 199                                          ' Keep looping until a terminator is found
            DATA_STRING[BbLOOP] = 0                                    ' Add a NULL to DATA_STRING used to get the DATE! 
            Break
        EndIf
        Inc CHARPOS
    Until CHARPOS >= 199
    Return

'------------------------------------------------------------------------------
' [PARSE GPS DATA]
' Extract the location data from the GPS strings
' The Date is returned in byte array DATA_STRING
' All the rest are returned in their respective variables
'==============================================================================
    PARSE_GPS:
    RsIn Wait("$GNGGA,"),Str RX_BUFF\63                             ' Pull the GPGGA string from the GPS data
    BbLOOP = 0
     Repeat
      RX_BUFF[BbLOOP] = RX_BUFF[BbLOOP] - 48               ' Convert ASCII to INT and load array RX_BUFF
      Inc BbLOOP
     Until BbLOOP > 63                                                       ' If the Time Is 19:45:30, Then it is broken down as follows:-
    HOURS   = RX_BUFF_1 + (RX_BUFF_0 * 10) + 2             ' ADD 2Hrs For Africa, HOURS = 19 Hours - (Rx_Buff_0 = [1*10] = 10 Hours) + (Rx_Buff_1 = 9) Gives 19 Hours
    MINUTES = RX_BUFF_3 + (RX_BUFF_2 * 10)                  ' MINUTES = 45 Minutes - (Rx_Buff_2 = [4*10] = 40 Minutes) + (Rx_Buff_3 = 5) Gives 45 Minutes
    SECONDS = RX_BUFF_5 + (RX_BUFF_4 * 10)                 ' SECONDS = 30 Seconds - (Rx_Buff_4 = [3*10] = 30 Seconds) + (Rx_Buff_5 = 0) Gives 30 Seconds

'------------------------------------------------------------------------------
' Positions Corrected for use with U-Blox5 GPS modules
'==============================================================================
    LATITUDE_DEGREES = RX_BUFF_11 + (RX_BUFF_10 * 10)                               ' LATITUDE_DEGREES = RX_BUFF_11 + (RX_BUFF_10 * 10)
    LATITUDE_MINUTES = RX_BUFF_13 + (RX_BUFF_12 * 10)                               ' LATITUDE_MINUTES = RX_BUFF_13 + (RX_BUFF_12 * 10)
    LATITUDE_SECONDS = RX_BUFF_17 + RX_BUFF_16 + (RX_BUFF_15 * 10)       ' LATITUDE_SECONDS = RX_BUFF_16 + (RX_BUFF_15 * 10)
    LATITUDE_BEARING = RX_BUFF_21 + 48                                                        ' LATITUDE_BEARING = RX_BUFF_21 + 48
    LONGITUDE_DEGREES = (RX_BUFF_23 * 100) + (RX_BUFF_24 * 10) + RX_BUFF_25
    LONGITUDE_MINUTES = RX_BUFF_30 + (RX_BUFF_29 * 10)
    LONGITUDE_SECONDS = RX_BUFF_34 + RX_BUFF_33 + (RX_BUFF_32 * 10)    ' LONGITUDE_SECONDS = RX_BUFF_33 + (RX_BUFF_32 * 10)
    LONGITUDE_BEARING = RX_BUFF_35 + 48
    FIX_TYPE = RX_BUFF_37
    SATELLITES_IN_VIEW = RX_BUFF_40 + (RX_BUFF_39 * 10)

'------------------------------------------------------------------------------
' Find the date of the fix
'==============================================================================
    RsIn Wait("$GNRMC,"),Str RX_BUFF\63                                          ' Pull the GPRMC string from the GPS data
    EXTRACT_ITEM = 8                                                                       ' Parse the value after the 8th comma
    GoSub EXTRACT_THE_VALUE
    Return
   
'------------------------------------------------------------------------------
    MAIN_PROGRAM_LOOP:
         
        HRSOut2 Str RX_BUFF                                                              ' TESTING PURPOSES To PC
        GoSub PARSE_GPS
  If FIX_TYPE > 0 Then
     
'========================================================================
' DATE "Switch ON Is You Want To SEE The DATE!!"
'------------------------------------------------------------------------
       'Print At 1,1,"DATE ",DATA_STRING#0,DATA_STRING#1,"-",DATA_STRING#2,DATA_STRING#3,"-",39,DATA_STRING#4,DATA_STRING#5,"       "

'========================================================================
' TIME "Switch ON Is You Want To SEE The TIME!!"
'------------------------------------------------------------------------
        ' string2Hold = ":"
        ' string2Print = "T:" + Str$(Dec2 HOURS) + string2Hold                   ' string2Print =  "L" + Str$(SDec LATITUDE_DEGREES) + string2Hold
        ' printStringV(MS16v, string2Print, 4, 1)                             

        ' string2Hold = ":"
        ' string2Print = Str$(Dec2 MINUTES) + string2Hold
        ' printStringV(MS16v, string2Print, 4, 40)

        ' string2Print = Str$(Dec2 SECONDS)
        ' printStringV(MS16v, string2Print, 4, 62)

'========================================================================
' LATITUDE Reading
'------------------------------------------------------------------------
       
        string2Hold = "*"                                                                                 ' "LT "
        string2Print = "LT" + Str$(Dec2 LATITUDE_DEGREES) + string2Hold   
        Print_At(arialn8,0,5,Str string2Print + "     ",0)

        string2Hold = "."
        string2Print = Str$(Dec2 LATITUDE_MINUTES) + string2Hold
        Print_At(arialn8,0,50,Str string2Print + "     ",0)
             
        string2Hold = $22                                                                                  ' ($27 = ') and ($22 = ")
        string2Print = Str$(Dec3 LATITUDE_SECONDS) + string2Hold             
        Print_At(arialn8,0,70,Str string2Print + "     ",0)
             
        DirHold = LATITUDE_BEARING                                                               ' (83 Dec = $52 Hex  = South-Direction)
        If DirHold = 83 Then
         string2Hold = "S"                                                                                   ' $53
         CompassLT = "S"                                                                                   ' Load the South "S" Direction into variable CompassLT
         High PORTC.9 : DelayMS 100 : Low PORTC.9                                         ' Switch Buzzer On Then Off
         GPS_Counter = 2                                                                                   ' Set Flag to tell System it has Aquired the Satellite,reading North or South
        ElseIf DirHold <> 83 Then
         string2Hold = "N"
         CompassLT = "N"                                                                                  ' Load the North "N" Direction into variable CompassLT
        EndIf
       
        string2Print = string2Hold
        Print_At(arialn8,0,100,Str string2Print + "     ",0)
             
'==================================================================
' LONGITUDE Reading
'------------------------------------------------------------------
        string2Hold = "*"                                                                                      ' "LN "
        string2Print = "LN" + Str$(Dec2 LONGITUDE_DEGREES) + string2Hold   
'        Print_At(arialn8,2,5,Str string2Print + "     ",0)

        string2Hold = "."
        string2Print = Str$(Dec2 LONGITUDE_MINUTES) + string2Hold
'        Print_At(arialn8,2,50,Str string2Print + "     ",0)

        string2Hold = $22                                                                                     ' ($27 = ') and ($22 = ")
        string2Print = Str$(Dec3 LONGITUDE_SECONDS) + string2Hold           
'        Print_At(arialn8,2,70,Str string2Print + "     ",0)

        DirHold = LONGITUDE_BEARING                                                               ' (83 Dec = $52 Hex = South-Direction)
        If DirHold = 69 Then
         string2Hold = "E"                                                                                     ' $53
         CompassLN = "E"                                                                                     ' Load the East "E" Direction into variable CompassLN
        '' High PORTC.9 : DelayMS 100 : Low PORTC.9
        ElseIf DirHold <> 69 Then
         string2Hold = "W"
         CompassLN = "W"                                                                                   ' Load the West "W" Direction into variable CompassLN
        EndIf

        string2Print = string2Hold
'        Print_At(arialn8,2,100,Str string2Print + "     ",0)

        '' HRSOut2 Str RX_BUFF                                                   
        '' Print At 3,1, "FIX TYPE ", Dec1 FIX_TYPE,"  "         
        '' Print At 4,1, "SATELLITES ",Dec SATELLITES_IN_VIEW,"    "
        Else
       '  printStringV(MS24v, "NO   SAT", 4, 0)                                                      ' print var width font as line 4, postion 0
         Repeat
          GoSub PARSE_GPS
         Until FIX_TYPE > 0
  EndIf

        If GPS_Counter = 2 Then                                                                          ' North or South has been detected by Satellite
         GPS_Counter = 0
         GoTo main                                                               
        EndIf
     
  GoTo MAIN_PROGRAM_LOOP     
     

midali

Hello Craig,
thank you for sharing!

What helps RX_pin from Ublox ?

Craig

#3
Midali

I think google the parts Data Sheet to have a look at it's Pin outs and get an understanding of how it connects to a Max3232.
M8Q UBlox Gps Circuit Layout .pdf