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,VDOPCS<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,,,modeCS<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
~~~~~~~
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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.
**********
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?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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!
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
'
'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,VDOPCS<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,,,modeCS<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
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
comma:
HSerReceive temp 'Looking for ,
If Temp = 0x2c then
comma = comma + 1 ' counting commas
goto comma ' l;ook for another comma
done: ' this is the way out
end Sub
~~~~~~~
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
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
'$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,VDOPCS<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,,,modeCS<CR><LF>
Do
select Case screen
case 1:
locate 0,0
~~~~~
Attached is the full operating file with another practice sub and a picture of the GPS proto operating.
GL
Mike
The GPS GCB file didn't attach.
Brilliant!!! Can't wait to try this. Thank you for your efforts on this!!!
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?
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!
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.