GPS Parsing Datalogger Code Oddities
Hello everyone,
I have built a "hybrid state machine GPS parsing datalogger" for a BS2p.--That makes me sound so important! The code records up to 10 minutes of GPS data at 9600 baud, by using the 7 remaining "program slots" for 14k of data storage. The code is listed below.
Problems I am having:
I cannot find out if I am getting a proper value for altitude. It consistently reads, "7", "1" or even "0," when I am on the 5th floor of a parking garage. The Grand Studio GPS antennae I am using has a altitude resolution of +/- 20 meters, so I do not know if it is reading correctly or I have bad code. ?? I think it is a bad parse.
I am not complaining, but I cannot figure out why I getting a 9600 baud rate (every second), when the Grand Studio antennae I am using is supposed to max out at 4800 baud (every 2 seconds).--This isnt really a problem, I am just curious. ??
Why is there a 3 second lapse in data between every·STORE command that changes which slot is being WRITTEN to, --not transferring execution over to another slot mind you, just WRITING to another slot.·?? My code might explain it better than I can.
If I didnt explain well enough what I am asking, please run/look at·the code listed below to see my problems listed above.
Finally, I am parsing 2 different sentences; "RMC" and GGA." Is the data contained in both messages the same? ie. Is the latitude/longitude of "GGA" the same as the latitude/longitude of the "RMC" sentence just xmitted in a different sentence.--Or are they calculated from different sattellites/methods and xmitted seperately?
BEGIN GPS DATALOGGER CODE:
' {$STAMP BS2p}
' {$PBASIC 2.5}
'Pins/Constants
GPSio·········· PIN···· 15
GPSraw········· PIN···· 14
accelSwitch···· PIN···· 03
MEMORYSIZE····· CON···· 2020 'must be made divisible by 20 (20B per block + 6b Header/Footer)
'Variables
slotNum VAR Nib
address VAR Word
dayMonth VAR Word
year VAR Byte
hrs VAR Byte
mins VAR Byte
secs VAR Byte
latLeft VAR Word
latRight VAR Word
longLeft VAR Word
longRight VAR Word
speed1 VAR Word
speed2 VAR Nib
course1 VAR Word
course2 VAR Nib
numSats VAR Nib
alt1 VAR Word
'Initialize
INPUT accelSwitch
INPUT GPSraw
LOW GPSraw
slotNum = 0
address = 0
dayMonth = 0
year = 0
hrs = 0
mins = 0
secs = 0
latLeft = 0
latRight = 0
longLeft = 0
longRight = 0
speed1 = 0
speed2 = 0
course1 = 0
course2 = 0
numSats = 0
alt1 = 0
main:
GOTO slotNumControl
'never returns to main unless a loss of power
'end main
slotNumControl:
slotNum = slotNum + 1····· 'enables 14k (2047 bytes X 7) for storage in multiple slots
·························· 'this is the only function where slotNum/address are initialized during runtime
SELECT slotNum············ 'each slot holds approx. 3.5 minutes of data at 9600 baud.
····· CASE < 1
········ END
····· CASE > 4
········ END
····· CASE = 1
······ STORE slotNum
······ address = 0
······ GOTO waitForAccel
····· CASE = 2
······ STORE slotNum
······ address = 0
······ GOTO collectData·· 'end dataSlot for flight1
····· CASE = 3
······ STORE slotNum
······ address = 0
······ GOTO waitForAccel
····· CASE = 4
······ STORE slotNum
······ address = 0
······ GOTO collectData·· 'end dataSlot for flight2, 5 more slots available
ENDSELECT
'end slotNumControl
waitForAccel:
SELECT accelSwitch
····· CASE = 0
········ GOTO waitForAccel
····· CASE ELSE
········ GOTO collectData
ENDSELECT
'end waitForAccel
collectData:
'Parse GPRMC sentence by counting commas, dayMonth & year also serve as headers/footers for each programSlot datablock
'$GPRMC,hrsminssecs.sss,validity bit,latLeft.latRight,N,longLeft.LongRight,W,speed1.speed2,course1.course2,dayMonthyear,...,CRC
SERIN GPSio, 500,[noparse][[/noparse]WAIT("RMC,"), WAIT(",") , WAIT(","), WAIT(","), WAIT(","), WAIT(","),
················· WAIT(","), WAIT(","), WAIT(","), DEC4 dayMonth, DEC2 year]
WRITE address, dayMonth.HIGHBYTE
address = address + 1
WRITE address, dayMonth.LOWBYTE
address = address + 1
WRITE address, year
address = address + 1
'end 3 byte header for slotX datablock
DO WHILE address < MEMORYSIZE
'Parse GPRMC sentence by counting bytes & commas
'$GPRMC,hrsminssecs.sss,validity bit,latLeft.latRight,N,longLeft.LongRight,W,speed1.speed2,course1.course2,dayMonthyear,...,CRC
SERIN GPSio,500,[noparse][[/noparse]WAIT("RMC,"),DEC2 hrs, DEC2 mins, DEC2 secs, WAIT(","), DEC latLeft, DEC latRight, SKIP 3,
················ DEC longLeft, DEC longRight, SKIP 3, DEC speed1, DEC speed2, DEC course1, DEC course2]
WRITE address, hrs
address = address + 1
WRITE address, mins
address = address + 1
WRITE address, secs
address = address + 1
WRITE address, latLeft.HIGHBYTE
address = address + 1
WRITE address, latLeft.LOWBYTE
address = address + 1
WRITE address, latRight.HIGHBYTE
address = address + 1
WRITE address, latRight.LOWBYTE
address = address + 1
WRITE address, longLeft.HIGHBYTE
address = address + 1
WRITE address, longLeft.LOWBYTE
address = address + 1
WRITE address, longRight.HIGHBYTE
address = address + 1
WRITE address, longRight.LOWBYTE
address = address + 1
WRITE address, speed1.HIGHBYTE
address = address + 1
WRITE address, speed1.LOWBYTE
address = address + 1
WRITE address, speed2
address = address + 1
WRITE address, course1.HIGHBYTE
address = address + 1
WRITE address, course1.LOWBYTE
address = address + 1
WRITE address, course2
address = address + 1
'Parse GPGGA sentence for altitude & number of satellites (0-12) by counting commas
'$GPGGA,hrsminssecs.SSS,latLeft.latRight,N,longLeft.LongRight,W,positionIndicator,numSatellites,HDOP,MSLaltitude,...,CRC
SERIN GPSio, 500,[noparse][[/noparse]WAIT("GGA,"), WAIT(",") , WAIT(","), WAIT(","), WAIT(","), WAIT(","),
················· WAIT(","), DEC numSats, WAIT(","), DEC alt1]
WRITE address, numSats
address = address + 1
WRITE address, alt1.HIGHBYTE
address = address + 1
WRITE address, alt1.LOWBYTE
address = address + 1
LOOP
'Parse GPRMC sentence by counting commas, dayMonth & year also serve as headers/footers for each programSlot datablock
'$GPRMC,hrsminssecs.sss,validity bit,latLeft.latRight,N,longLeft.LongRight,W,speed1.speed2,course1.course2,dayMonthyear,...,CRC
SERIN GPSio, 500,[noparse][[/noparse]WAIT("RMC,"), WAIT(",") , WAIT(","), WAIT(","), WAIT(","), WAIT(","),
················· WAIT(","), WAIT(","), WAIT(","), DEC4 dayMonth, DEC2 year]
'start 3 byte footer for slotX datablock
WRITE address, dayMonth.HIGHBYTE
address = address + 1
WRITE address, dayMonth.LOWBYTE
address = address + 1
WRITE address, year
address = address + 1
GOTO slotNumControl
'endCollectData
END GPSDATALOGGER CODE
BEGIN GPS DATALOGGER READER CODE:
' {$STAMP BS2p}
' {$PBASIC 2.5}
'This program is used to retrieve the recorded values from all program slots and DEBUGs them to a
'monitor. The raw data is then copied/pasted into a spreadsheet for conversions and graphing.
STORE 1··········· 'must manually change to read each slot seperately, multislot control doesnt work for reading ALL the data. ??
'Pins/Constants
MEMORYSIZE····· CON···· 2020 'must be made divisible by 20 + extra (20B per block + 6b Header/Footer)
'Variables
address VAR Word
dayMonth VAR Word
year VAR Byte
hrs VAR Byte
mins VAR Byte
secs VAR Byte
latLeft VAR Word
latRight VAR Word
longLeft VAR Word
longRight VAR Word
speed1 VAR Word
speed2 VAR Nib
course1 VAR Word
course2 VAR Nib
numSats VAR Nib
alt1 VAR Word
'Initialize
dayMonth = 0
year = 0
hrs = 0
mins = 0
secs = 0
latLeft = 0
latRight = 0
longLeft = 0
longRight = 0
speed1 = 0
speed2 = 0
course1 = 0
course2 = 0
numSats = 0
alt1 = 0
main:
address = 0
READ address, dayMonth.HIGHBYTE
address = address + 1
READ address, dayMonth.LOWBYTE
address = address + 1
DEBUG "dayMonth: ", DEC dayMonth, CR
READ address, year
address = address + 1
DEBUG "year: ", DEC year, CR
'end 3 byte header for slotX dataBlock
DO
READ address, hrs
address = address + 1
READ address, mins
address = address + 1
READ address, secs
address = address + 1
DEBUG "HHMMSS: ", DEC hrs, ":", DEC mins, ":", DEC secs, CR
READ address, latLeft.HIGHBYTE
address = address + 1
READ address, latLeft.LOWBYTE
address = address + 1
READ address, latRight.HIGHBYTE
address = address + 1
READ address, latRight.LOWBYTE
address = address + 1
DEBUG "latitude: ", DEC latLeft, ".", DEC latRight, " N", CR
READ address, longLeft.HIGHBYTE
address = address + 1
READ address, longLeft.LOWBYTE
address = address + 1
READ address, longRight.HIGHBYTE
address = address + 1
READ address, longRight.LOWBYTE
address = address + 1
DEBUG "longitude: ", DEC longLeft, ".", DEC longRight, " W", CR
READ address, speed1.HIGHBYTE
address = address + 1
READ address, speed1.LOWBYTE
address = address + 1
READ address, speed2
address = address + 1
DEBUG "knots: ", DEC speed1, ".", DEC speed2, CR
READ address, course1.HIGHBYTE
address = address + 1
READ address, course1.LOWBYTE
address = address + 1
READ address, course2
address = address + 1
DEBUG "heading in degrees: ", DEC course1, ".", DEC course2, CR
READ address, numSats
address = address + 1
DEBUG "number of satellites: ", DEC numSats, CR
READ address, alt1.HIGHBYTE
address = address + 1
READ address, alt1.LOWBYTE
address = address + 1
DEBUG "altitude: ", DEC alt1, CR
LOOP WHILE address < MEMORYSIZE
'start 3 byte footer for slotX dataBlock
READ address, dayMonth.HIGHBYTE
address = address + 1
READ address, dayMonth.LOWBYTE
address = address + 1
DEBUG "dayMonthFooter: ", DEC dayMonth, CR
READ address, year
address = address + 1
DEBUG "yearFooter: ", DEC year, CR
END
END GPS DATALOGGER READER CODE
OK folks, I would appreciate any feedback on my "hybrid state machine."
Any answers to my questions above or suggestions to improve my code will be devoured.
Feel free to use the above code as you want. It runs.
Thanks,
Karl
·
I have built a "hybrid state machine GPS parsing datalogger" for a BS2p.--That makes me sound so important! The code records up to 10 minutes of GPS data at 9600 baud, by using the 7 remaining "program slots" for 14k of data storage. The code is listed below.
Problems I am having:
I cannot find out if I am getting a proper value for altitude. It consistently reads, "7", "1" or even "0," when I am on the 5th floor of a parking garage. The Grand Studio GPS antennae I am using has a altitude resolution of +/- 20 meters, so I do not know if it is reading correctly or I have bad code. ?? I think it is a bad parse.
I am not complaining, but I cannot figure out why I getting a 9600 baud rate (every second), when the Grand Studio antennae I am using is supposed to max out at 4800 baud (every 2 seconds).--This isnt really a problem, I am just curious. ??
Why is there a 3 second lapse in data between every·STORE command that changes which slot is being WRITTEN to, --not transferring execution over to another slot mind you, just WRITING to another slot.·?? My code might explain it better than I can.
If I didnt explain well enough what I am asking, please run/look at·the code listed below to see my problems listed above.
Finally, I am parsing 2 different sentences; "RMC" and GGA." Is the data contained in both messages the same? ie. Is the latitude/longitude of "GGA" the same as the latitude/longitude of the "RMC" sentence just xmitted in a different sentence.--Or are they calculated from different sattellites/methods and xmitted seperately?
BEGIN GPS DATALOGGER CODE:
' {$STAMP BS2p}
' {$PBASIC 2.5}
'Pins/Constants
GPSio·········· PIN···· 15
GPSraw········· PIN···· 14
accelSwitch···· PIN···· 03
MEMORYSIZE····· CON···· 2020 'must be made divisible by 20 (20B per block + 6b Header/Footer)
'Variables
slotNum VAR Nib
address VAR Word
dayMonth VAR Word
year VAR Byte
hrs VAR Byte
mins VAR Byte
secs VAR Byte
latLeft VAR Word
latRight VAR Word
longLeft VAR Word
longRight VAR Word
speed1 VAR Word
speed2 VAR Nib
course1 VAR Word
course2 VAR Nib
numSats VAR Nib
alt1 VAR Word
'Initialize
INPUT accelSwitch
INPUT GPSraw
LOW GPSraw
slotNum = 0
address = 0
dayMonth = 0
year = 0
hrs = 0
mins = 0
secs = 0
latLeft = 0
latRight = 0
longLeft = 0
longRight = 0
speed1 = 0
speed2 = 0
course1 = 0
course2 = 0
numSats = 0
alt1 = 0
main:
GOTO slotNumControl
'never returns to main unless a loss of power
'end main
slotNumControl:
slotNum = slotNum + 1····· 'enables 14k (2047 bytes X 7) for storage in multiple slots
·························· 'this is the only function where slotNum/address are initialized during runtime
SELECT slotNum············ 'each slot holds approx. 3.5 minutes of data at 9600 baud.
····· CASE < 1
········ END
····· CASE > 4
········ END
····· CASE = 1
······ STORE slotNum
······ address = 0
······ GOTO waitForAccel
····· CASE = 2
······ STORE slotNum
······ address = 0
······ GOTO collectData·· 'end dataSlot for flight1
····· CASE = 3
······ STORE slotNum
······ address = 0
······ GOTO waitForAccel
····· CASE = 4
······ STORE slotNum
······ address = 0
······ GOTO collectData·· 'end dataSlot for flight2, 5 more slots available
ENDSELECT
'end slotNumControl
waitForAccel:
SELECT accelSwitch
····· CASE = 0
········ GOTO waitForAccel
····· CASE ELSE
········ GOTO collectData
ENDSELECT
'end waitForAccel
collectData:
'Parse GPRMC sentence by counting commas, dayMonth & year also serve as headers/footers for each programSlot datablock
'$GPRMC,hrsminssecs.sss,validity bit,latLeft.latRight,N,longLeft.LongRight,W,speed1.speed2,course1.course2,dayMonthyear,...,CRC
SERIN GPSio, 500,[noparse][[/noparse]WAIT("RMC,"), WAIT(",") , WAIT(","), WAIT(","), WAIT(","), WAIT(","),
················· WAIT(","), WAIT(","), WAIT(","), DEC4 dayMonth, DEC2 year]
WRITE address, dayMonth.HIGHBYTE
address = address + 1
WRITE address, dayMonth.LOWBYTE
address = address + 1
WRITE address, year
address = address + 1
'end 3 byte header for slotX datablock
DO WHILE address < MEMORYSIZE
'Parse GPRMC sentence by counting bytes & commas
'$GPRMC,hrsminssecs.sss,validity bit,latLeft.latRight,N,longLeft.LongRight,W,speed1.speed2,course1.course2,dayMonthyear,...,CRC
SERIN GPSio,500,[noparse][[/noparse]WAIT("RMC,"),DEC2 hrs, DEC2 mins, DEC2 secs, WAIT(","), DEC latLeft, DEC latRight, SKIP 3,
················ DEC longLeft, DEC longRight, SKIP 3, DEC speed1, DEC speed2, DEC course1, DEC course2]
WRITE address, hrs
address = address + 1
WRITE address, mins
address = address + 1
WRITE address, secs
address = address + 1
WRITE address, latLeft.HIGHBYTE
address = address + 1
WRITE address, latLeft.LOWBYTE
address = address + 1
WRITE address, latRight.HIGHBYTE
address = address + 1
WRITE address, latRight.LOWBYTE
address = address + 1
WRITE address, longLeft.HIGHBYTE
address = address + 1
WRITE address, longLeft.LOWBYTE
address = address + 1
WRITE address, longRight.HIGHBYTE
address = address + 1
WRITE address, longRight.LOWBYTE
address = address + 1
WRITE address, speed1.HIGHBYTE
address = address + 1
WRITE address, speed1.LOWBYTE
address = address + 1
WRITE address, speed2
address = address + 1
WRITE address, course1.HIGHBYTE
address = address + 1
WRITE address, course1.LOWBYTE
address = address + 1
WRITE address, course2
address = address + 1
'Parse GPGGA sentence for altitude & number of satellites (0-12) by counting commas
'$GPGGA,hrsminssecs.SSS,latLeft.latRight,N,longLeft.LongRight,W,positionIndicator,numSatellites,HDOP,MSLaltitude,...,CRC
SERIN GPSio, 500,[noparse][[/noparse]WAIT("GGA,"), WAIT(",") , WAIT(","), WAIT(","), WAIT(","), WAIT(","),
················· WAIT(","), DEC numSats, WAIT(","), DEC alt1]
WRITE address, numSats
address = address + 1
WRITE address, alt1.HIGHBYTE
address = address + 1
WRITE address, alt1.LOWBYTE
address = address + 1
LOOP
'Parse GPRMC sentence by counting commas, dayMonth & year also serve as headers/footers for each programSlot datablock
'$GPRMC,hrsminssecs.sss,validity bit,latLeft.latRight,N,longLeft.LongRight,W,speed1.speed2,course1.course2,dayMonthyear,...,CRC
SERIN GPSio, 500,[noparse][[/noparse]WAIT("RMC,"), WAIT(",") , WAIT(","), WAIT(","), WAIT(","), WAIT(","),
················· WAIT(","), WAIT(","), WAIT(","), DEC4 dayMonth, DEC2 year]
'start 3 byte footer for slotX datablock
WRITE address, dayMonth.HIGHBYTE
address = address + 1
WRITE address, dayMonth.LOWBYTE
address = address + 1
WRITE address, year
address = address + 1
GOTO slotNumControl
'endCollectData
END GPSDATALOGGER CODE
BEGIN GPS DATALOGGER READER CODE:
' {$STAMP BS2p}
' {$PBASIC 2.5}
'This program is used to retrieve the recorded values from all program slots and DEBUGs them to a
'monitor. The raw data is then copied/pasted into a spreadsheet for conversions and graphing.
STORE 1··········· 'must manually change to read each slot seperately, multislot control doesnt work for reading ALL the data. ??
'Pins/Constants
MEMORYSIZE····· CON···· 2020 'must be made divisible by 20 + extra (20B per block + 6b Header/Footer)
'Variables
address VAR Word
dayMonth VAR Word
year VAR Byte
hrs VAR Byte
mins VAR Byte
secs VAR Byte
latLeft VAR Word
latRight VAR Word
longLeft VAR Word
longRight VAR Word
speed1 VAR Word
speed2 VAR Nib
course1 VAR Word
course2 VAR Nib
numSats VAR Nib
alt1 VAR Word
'Initialize
dayMonth = 0
year = 0
hrs = 0
mins = 0
secs = 0
latLeft = 0
latRight = 0
longLeft = 0
longRight = 0
speed1 = 0
speed2 = 0
course1 = 0
course2 = 0
numSats = 0
alt1 = 0
main:
address = 0
READ address, dayMonth.HIGHBYTE
address = address + 1
READ address, dayMonth.LOWBYTE
address = address + 1
DEBUG "dayMonth: ", DEC dayMonth, CR
READ address, year
address = address + 1
DEBUG "year: ", DEC year, CR
'end 3 byte header for slotX dataBlock
DO
READ address, hrs
address = address + 1
READ address, mins
address = address + 1
READ address, secs
address = address + 1
DEBUG "HHMMSS: ", DEC hrs, ":", DEC mins, ":", DEC secs, CR
READ address, latLeft.HIGHBYTE
address = address + 1
READ address, latLeft.LOWBYTE
address = address + 1
READ address, latRight.HIGHBYTE
address = address + 1
READ address, latRight.LOWBYTE
address = address + 1
DEBUG "latitude: ", DEC latLeft, ".", DEC latRight, " N", CR
READ address, longLeft.HIGHBYTE
address = address + 1
READ address, longLeft.LOWBYTE
address = address + 1
READ address, longRight.HIGHBYTE
address = address + 1
READ address, longRight.LOWBYTE
address = address + 1
DEBUG "longitude: ", DEC longLeft, ".", DEC longRight, " W", CR
READ address, speed1.HIGHBYTE
address = address + 1
READ address, speed1.LOWBYTE
address = address + 1
READ address, speed2
address = address + 1
DEBUG "knots: ", DEC speed1, ".", DEC speed2, CR
READ address, course1.HIGHBYTE
address = address + 1
READ address, course1.LOWBYTE
address = address + 1
READ address, course2
address = address + 1
DEBUG "heading in degrees: ", DEC course1, ".", DEC course2, CR
READ address, numSats
address = address + 1
DEBUG "number of satellites: ", DEC numSats, CR
READ address, alt1.HIGHBYTE
address = address + 1
READ address, alt1.LOWBYTE
address = address + 1
DEBUG "altitude: ", DEC alt1, CR
LOOP WHILE address < MEMORYSIZE
'start 3 byte footer for slotX dataBlock
READ address, dayMonth.HIGHBYTE
address = address + 1
READ address, dayMonth.LOWBYTE
address = address + 1
DEBUG "dayMonthFooter: ", DEC dayMonth, CR
READ address, year
address = address + 1
DEBUG "yearFooter: ", DEC year, CR
END
END GPS DATALOGGER READER CODE
OK folks, I would appreciate any feedback on my "hybrid state machine."
Any answers to my questions above or suggestions to improve my code will be devoured.
Feel free to use the above code as you want. It runs.
Thanks,
Karl
·
Comments
Rick
▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔▔
Chris Savage
Parallax Engineering
I wanted to attach the code but it was over the 5MB? attachment size.--Actually, I was surprised that I was allowed to post all the code. I just tried it anyway figuring it would bounce back to me telling me it was over a size limit.· ?? Sorry.
I agree with all of the provided altitude discrepancies and after further testing I think I have a good parse on altitude.
Does anyone have any insight as to·why there is a·3 second WRITE lapse·whenever a·STORE command is·issued?
Why do I get a 9600 baud rate on a 4800 baud rate antennae?
Is the data on the GGA and RMC sentences the same data xmitted·as different sentences or are they completely different data from different········ satellites/sources?
What would be a good model of air pressure gauge to interface w/ a BS2p or a Propellor? I have been meaning to ask this for awhile and have kept an eye out in your sensor store, but there are none.
Any info is appreciated,
Karl
http://geocities.com/SiliconValley/Orchard/6633/altimeter.html
cheers, David