Menu

Getting values from GPS without big serial buffers

mmotte
2015-03-05
2015-05-07
  • mmotte

    mmotte - 2015-03-05

    Smaller Pic chips can get GPS data with out hundreds of bytes of buffers to store the GPS sentences. The sentences are delimited by commas. By counting commas you can select any piece of data in that sentence.


    ~~~~~~~~~

    ' FILE: GPS_NO_BUF_Parser_16F886.gcb
    ' DATE: 03/4/2015
    ' VERSION: 0.95
    ' AUTHOR: Mike Otte
    '
    ' Description.
    '
    '
    ' This file was compile using the Great Cow Basic compiler.
    '
    ' This demonstration code is distributed in the hope that it will be useful,
    ' but WITHOUT ANY WARRANTY; without even the implied warranty of
    ' MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    ' GNU General Public License for more details.
    '
    ' ----- Configuration
    '
    'GPS ST22 was used
    'A 4 line LCD and a 5 pos navigation switch
    '

    'General hardware configuration
    #chip 16F886,8
    
    'LCD connection settings
    #define LCD_IO 4
    #define LCD_DB4 PORTB.4
    #define LCD_DB5 PORTB.5
    #define LCD_DB6 PORTB.6
    #define LCD_DB7 PORTB.7
    #define LCD_RS PORTB.1
    #define LCD_RW PORTB.2
    #define LCD_Enable PORTB.3
    
    ' Button direction Variables
    #define LBut PORTA.5 'Left
    #define PBut PORTA.4 'Push
    #define DBut PORTA.3 'Down
    #define RBut PORTA.2 'Right
    #define UBut PORTA.1 'Up
    
    'USART settings
    #define USART_BAUD_RATE 9600
    #define USART_BLOCKING
    
    dir PORTB.0 In          ' interrupt not used yet
    dir PORTA in            'Buttons 5way
    'Set USART  pin
    Dir PORTC.7 In          ' GPS data in to '886 Hardware serial port
    Dir PORTC.6 Out         ' GPS data out of '886 serial port -
    
    Dim DataStr As String * 12   'string storage
    
    CLS
    PRINT "Demo GPS Ser Parsing"
    locate 1,2
    PRINT " GCBASIC "
    wait 2 s
    CLS
    

    'NMEA GPS Messages start With $GP
    '$GPGGA is Global positioning fix
    '$GPGSA is Active Satellites
    '$GPVTG is Velocity Course Groundspeed
    '$GPRMC is Recommened Minimum specific
    '$GPGGA,Time,lat,N/S,Long,E/W,fix,sats,HDOP,Alt,unit,GeoID,unit,age,diffCS<CR><LF>
    '$GPGSA,M/A,Fix/2D/3D,Sat1,Sat2....Sat12,PDOP,HDOP,VDOP
    CS<CR><LF>
    '$GPVTG,True,T, Mag,M,speed,K,ModeCS<CR><LF>
    '$GPRMC,UTC,A/V,lat,N/S,Long,E/W,speed,course,date,,,mode
    CS<CR><LF>

    ' which NMEA sentence string are we looking at and which position is the data
    position = 1 ' Which comma position is the data after

    Do
    CLS
    'get_val(0x47,0x47,0x41,position)
    get_val("G","G","A",position)
    Print DataStr
    locate 1,0
    wait 1 s
    get_val("G","S","A",position)
    Print DataStr
    locate 2,0
    wait 1 s
    get_val("V","T","G",position)
    Print DataStr
    Locate 3,0
    wait 1 s
    get_val("R","M","C",position)
    Print DataStr

    ' buttons used to change target position fo rdemo
    IF UBut = 0 Then
    position = position +1
    If position > 10 Then position = 10

          end if
    

    IF DBut = 0 Then
    position = position -1
    If position <1 Then position = 1
    end if

    wait 1 S

    loop

    'NMEA GPS Messages start With $GP
    '$GPGGA is Global positioning fix
    '$GPGSA is Active Satellites
    '$GPVTG is Velocity Course Groundspeed
    '$GPRMC is Recommened Minimum specific
    'idea from PICBASIC snippet author Mike Coffey

    sub get_val(Able,Baker,Charlie,target)

    Look:
    comma = 0

    HSerReceive temp           'Look for $ start of message
    If temp <> 0x24 then  goto Look
    HSerReceive temp           'Look for G - every msg
    If temp <> 0x47 then  goto Look
    HSerReceive temp           'Look for P - every msg
    If Temp <> 0x50 then  goto Look
    HSerReceive temp           'Look for G or first unique letter of sentence
    If Temp <> Able then  goto Look
    HSerReceive temp           'Look for G or second unique letter
    If Temp <> Baker then  goto Look
    HSerReceive temp           'Look for A or third unique letter
    If Temp <> Charlie then  goto Look
    

    comma:
    HSerReceive temp 'Looking for ,
    If Temp = 0x2c then
    comma = comma + 1 ' counting commas

       If comma = target Then   ' check if we are there
         HSerReceive temp
         strL = 0
    
       Do until temp = 0x2c     'check if another comma which says the end of data
         strL = strL + 1        'I realize that at the end of sentence there is no comma
         DataStr(strL) = temp   ' and could check for a star too
         HSerReceive temp       ' store data in string variable
       Loop
    
       DataStr(0) = strL        'Set the length of the string
       goto done
     End If
    
    End If
    

    goto comma ' l;ook for another comma

    done: ' this is the way out
    end Sub
    ~~~~~~~


     
  • mmotte

    mmotte - 2015-03-13

    Getting one piece of data at a time certainly limits need for memory but when you need 7 different pieces from the same GPS message it seems lossy to wait another second for each piece. It was taking 8 secs to update my first screen. So I experimented with a couple different subroutines to gather multiple data pieces into multiple string variables.Yes, That uses more memory but it only takes a second( that is the speed that the GPS updates at).

    Here is the workhorse sub routine(s) and it is generic so you can get up to 10 pieces of data from any one of the GPS messages at a time.

    It is called with 4 attributes:
    Able,Baker,Charlie are the unique GPS message prefix after "$GP" and you can use the letters in quotes like "G","G","A"

    4 th attribute is the number of fields you want returned. You can return up to 10 but watchout if the message doesn't have that many fields. That hasn't been trapped.

    Example call is below.


    ~~~~
    'This sub demonstrates getting multiple character fields out of the gps sentence
    'and storing them as strings
    'Starting after the first comma
    'Fields are
    'Datastr1 thru DataStr10
    'Now we are getting the whole thing
    ' some messages are shorter and some are longer
    ' this routine looks for up to 10 fields only
    ' if you need another field get them individually

    sub get_multiple(Able,Baker,Charlie,numflds)

    Look4:
    comma = 0

    HSerReceive temp           'Look for $ start of message
    If temp <> 0x24 then  goto Look4
    HSerReceive temp           'Look for G - every msg
    If temp <> 0x47 then  goto Look4
    HSerReceive temp           'Look for P - every msg
    If Temp <> 0x50 then  goto Look4
    HSerReceive temp           'Look for G or first unique letter of sentence
    If Temp <> Able then  goto Look4
    HSerReceive temp           'Look for G or second unique letter
    If Temp <> Baker then  goto Look4
    HSerReceive temp           'Look for A or third unique letter
    If Temp <> Charlie then  goto Look4
    
    HSerReceive temp
    
    get_Hser_string
    DataStr1 = Datastr
    comma++
    If comma = numflds Then goto Done4
    get_Hser_string
    DataStr2 = Datastr
    comma++
    If comma = numflds Then goto Done4
    get_Hser_string
    DataStr3 = Datastr
    comma++
    If comma = numflds Then goto Done4
    get_Hser_string
    DataStr4 = Datastr
    comma++
    If comma = numflds Then goto Done4
    get_Hser_string
    DataStr5 = Datastr
    comma++
    If comma = numflds Then goto Done4
    get_Hser_string
    DataStr6 = Datastr
    comma++
    If comma = numflds Then goto Done4
    get_Hser_string
    DataStr7 = Datastr
    comma++
    If comma = numflds Then goto Done4
    get_Hser_string
    DataStr8 = Datastr
    comma++
    If comma = numflds Then goto Done4
    get_Hser_string
    DataStr9 = Datastr
    comma++
    If comma = numflds Then goto Done4
    get_Hser_string
    DataStr10 = Datastr
    

    done4: ' this is the way out
    end Sub

    'We are going to get all the chars until the next comma
    'and put them into a string with the correct char count in string(0)
    '
    sub get_Hser_string
    HSerReceive temp
    strL = 0
    Do until temp = 0x2c 'check if another comma which says the end of data
    strL = strL + 1 ' Get the Latitude
    DataStr(strL) = temp ' store data in string variable 1
    HSerReceive temp
    Loop
    DataStr(0) = strL 'Set the length of the string
    End sub

    *********
    
    To call the sub you need to know the GPS message that you want data from and have to keep track of what is in each string when you are using the data.
    
    **********
    

    '$GPGGA,Time,lat,N/S,Long,E/W,fix,sats,HDOP,Alt,unit,GeoID,unit,age,diffCS<CR><LF>
    '$GPGSA,M/A,Fix/2D/3D,Sat1,Sat2....Sat12,PDOP,HDOP,VDOP
    CS<CR><LF>
    '$GPVTG,True,T, Mag,M,speed,K,ModeCS<CR><LF>
    '$GPRMC,UTC,A/V,lat,N/S,Long,E/W,speed,course,date,,,mode
    CS<CR><LF>

    Do
    select Case screen
    case 1:
    locate 0,0

       get_multiple("G","G","A",7)    ' get first 7 fields
    
       Print "Time="
       Print DataStr1
       locate 1,0
       Print "Lat="
       Print DataStr2
       Print " "
       Print DataStr3
       locate 2,0
       Print "Long="
       Print DataStr4
       Print " "
       Print DataStr5
    

    ~~~~~


    Attached is the full operating file with another practice sub and a picture of the GPS proto operating.

    GL
    Mike

     
  • mmotte

    mmotte - 2015-03-13

    The GPS GCB file didn't attach.

     
  • viscomjim

    viscomjim - 2015-03-15

    Brilliant!!! Can't wait to try this. Thank you for your efforts on this!!!

     
  • Marc in the Dark

    Hi mmotte. This is fantastic, but...
    Im trying to compile this for a 18f4550 and getting this error:
    Error: GCASM: Duplicate, conflicting definition for DONE

    It compiles for 16f877a but not 18f4550.

    Any Ideas?

     
  • mmotte

    mmotte - 2015-05-06

    search for "done" give 14 "done(s)". 2 = done, 2= done3 and the rest are done4. I remember adding done3 and done4 for other destinations to fall out of the loop to.

    I would suggest searching and renaming different sets of "done" using other names like "fini" or " wayout"

    this program was meant as a demo program and as such has multiple ways of doing the same thing. Use what you find useful!

     
  • Marc in the Dark

    Thanks for the reply.
    Did as you suggested and it compiled straight away. (I should have thought of that...)

    Anyways thanks for the reply and for the gps demo. Its extremely useful!

    Marc.

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.