GPS NMEA parser

Post details of your projects here.
Post Reply
YahooArchive
Posts: 1463
Joined: Fri Oct 19, 2012 5:11 am

GPS NMEA parser

Post by YahooArchive » Thu Oct 25, 2012 12:09 am

Good day, folks!

As depicted in the photo, that I posted in the group album this past
weekend, I have an 'mite on which I have installed a GPS
daughterboard which is detailed here:
(http://www.sparkfun.com/commerce/produc ... cts_id=779).

The GPS Module is an EM-411 which is very similar to the EM-406 which
is detailed here:
http://www.sparkfun.com/commerce/produc ... cts_id=465.
The only difference is that Tx & Rx are swapped.

The GPS puts outs TTL NMEA data at various baud settings - the
protocol is detailed in this document:
http://www.sparkfun.com/datasheets/GPS/ ... anual1.pdf.

I have the GPS TTL output going to one of the GPIO pins on the 'mite
(I also have some status LEDs on several of the GPIO pins). I am
able to get the 'mite to listen to the datastream and print it, but I
am having a bit of an issue that I would like to solicit your
feedback on.

In reading the 'basic manual, I see where there are basically two
serial input commands - SERIN and RXD. I have tried to implement
both, at various baud settings, and am experiencing some
frustration. The program only captures and displays ~50% of the
sentences at best and ~20% at worst, driven by baud selection (&
code). Also, it seems to halt, waiting for up to .5 seconds for a
byte when ever a SERIN or RXD is commanded. I suspect that this is
by design.

During my testing, I commented out a lot of the code and put simple
counters in place and I was able to determine that it has to do with
the string handling, and also the delays induced by 'Print'.

I am surprized as the chip is running at 60MHz (I believe) and yet it
can't keep up (I know, it's the code... :-). Is RXD the wrong way to
go? (It seems that the machine will wait for a byte before
proceeding. Ditto with SerIn...). Is the baud rate betweent he
board and the host CPU possibly contributing?

Can someone please take a look at the following and advise how I
might go about getting the code to capture all of the sentences?

It seems that the simple loop implemented is a pretty efficient way
of handling the retrieval of the sentence data from the incoming
port, but for some reason, I am not having the success I expected. I
am guessing that I will need to approach it entirely differently with
using a feature of the 2103 that I am not yet familiar with, or deal
with the incoming data stream differently, in order to facilitate
buffering...

Please review and advise.

Thanks in advance.

- Tod Wulff





' -----[ Title ]------------------------------------------------------
'
' File...... NMEA PARSER.bas
' Purpose... PARSING NMEA SENTENCES
' Author.... Tod Wulff
' Started... 24FEB07
' Updated... STILL IN PRE-ALPHA STAGES... ;-)
'
' -----[ Program Description ]----------------------------------------
'
' THIS PROGRAM IS THE BEGINING OF A GPS NMEA SENTENCE PARSING UTILITY
' THE HARDWARE IS A ARMMITE BY CORIDIUM WITH AN EM-401/411 DAUGHTER
' BOARD ATTACHED. THE GPIO PINS HAVE 12 LEDS WITH CURRENT LIMITING
' RESISTORS. YES, 12 LEDS BEING DRIVEN AT THE SAME TIME IS NOT GOOD
' (SEEING AS THEY ARE NOT BURRERED), SO I WON'T CODE IT THAT WAY...
'
'
'
'
' -----[ Revision History ]-------------------------------------------
'
' 24FEB07 INITIAL BUILD EFFORTS
'
' -----[ Constants ]--------------------------------------------------
'
CONST HI=1
CONST LO=0
CONST GPSRXPORT=9 ' THE GPS' TX IS HOOKED TO
PORT 9
CONST GPSTXPORT=10 ' THE GPS' RX IS HOOKED TO
PORT 10
CONST DOUT=HI ' SETTING VAR FOR EASE OF
READING
CONST DIN=LO

CONST RUNLED=11 ' RUNNING LED = LED 11
(MOST SIGNIFICANT)
CONST ACTLED=10 ' THIS LED'S IS USED TO
DENOTE LOOP ACTIVITY
'
' -----[ Variables ]--------------------------------------------------
'
DIM LEDON(12) ' SETUP VARIABLES FOR THE
12 LEDS
DIM LEDOFF(12)
DIM LEDPORT(12)
DIM LEDTOGGLE(12)
DIM GPSSENTENCE$(256) ' SET UP STRING VAR FOR GPS
SENTENCE
STROBEDELAY=1 ' STROBE LED SEQUENCE DELAY'
' -----[ Initialization ]---------------------------------------------
'
RESTORE
FOR I = 0 TO 11 ' INIT THE 12 LEDS
READ LEDON(I) ' GRAB THE ON STATE
READ LEDOFF(I) ' GRAB THE OFF STATE
READ LEDPORT(I) ' GRAB THE PORT #
READ LEDTOGGLE(I) ' INIT EACH LED'S TOGGLE VAR
DIR(LEDPORT(I))=DOUT ' SET EACH LED'S PORT AS AN
OUTPUT
OUT(LEDPORT(I))=LEDOFF(I) ' AND INIT EACH LED AS OFF
NEXT I

BAUD(GPSRXPORT) = 19200 ' SET THE BAUD RATE FOR THE
GPS INPUT
DIR(GPSRXPORT)=DIN ' SET THE RX PORT AS AN
INPUT TO LISTEN
DIR(GPSTXPORT)=DIN ' SET THE TX PORT AS AN
INPUT TO SNOOP
GPSSENTENCE$="" ' NULL THE SENTENCE
'
' -----[ Main Code ]--------------------------------------------------
'
GOSUB STROBELEDS ' CUTE LITTLE SEQUENCE TO
ACKNOWLEDGE LIFE
GOSUB DISPLAYRUN ' ANNUNCIATE LED 11
AS 'RUNNING'

DO ' BEGIN MAIN LOOP

GPSSENTENCE$="" ' NULL OUT THE SENTENCE
STRING

WHILE RXDATA <> 36 ' LOOP WAITING FOR THE
BEGINING
GOSUB BLINKACTLED
RXDATA = RXD(GPSRXPORT) ' SENTENCE ALWAYS BEGINS
WITH $ (ASCII 36)
LOOP

GPSSENTENCE$ = CHR(36) ' START THE SENTENCE
WHILE RXDATA <> 42 ' LOOP TO 'BUILD' BY
CONCATENATING
RXDATA = RXD(GPSRXPORT) ' THE RX BYTE TO THE STRING
UNTIL AN *
GPSSENTENCE$ = GPSSENTENCE$ + CHR(RXDATA) ' (DENOTING END OF PAYLOAD)
IS RECEIVED
LOOP

RXDATA = RXD(GPSRXPORT) ' ONCE * RECEIVED, GET THE
LAST TWO BYTES
GPSSENTENCE$ = GPSSENTENCE$ + CHR(RXDATA) ' WHICH ARE THE CHECKSUM
BYTES
RXDATA = RXD(GPSRXPORT) ' CONCATENATING THEM ONTO
THE SENTENCE
GPSSENTENCE$ = GPSSENTENCE$ + CHR(RXDATA)

PRINT GPSSENTENCE$ ' PRINT THE RESULTS

LOOP ' END MAIN LOOP
'
' -----[ Subroutines ]------------------------------------------------
'
DISPLAYRUN:
OUT(LEDPORT(RUNLED))=LEDON(RUNLED) ' TURN ON THE 'RUNNING'
LED...
RETURN
'--------------
BLINKACTLED:
OUT(LEDPORT(ACTLED))=LEDON(ACTLED) ' TOGGLE THE ACT LED ON/OFF
DENOTES ACTIVITY
OUT(LEDPORT(ACTLED))=LEDOFF(ACTLED)
RETURN
'--------------
STROBELEDS: ' SEQUENCE TO FIRE OFF ALL
THE LEDS
FOR I=0 TO 11 ' (ONE AT A TIME) IN
SUCCESSION FROM
OUT(LEDPORT(I))=LEDON(I) ' LEAST SIGNIFICANT TO MOST
SIGNIFICANT
WAIT (STROBEDELAY)
OUT(LEDPORT(I))=LEDOFF(I)
NEXT I
RETURN
'
' -----[ Data ]-------------------------------------------------------
'
LED_TABLE: ' ON,OFF,PORT,TOGGLE * 12
LEDS
DATA 1,0,0,0,1,0,1,0,1,0,2,0,1,0,3,0 ' (SOME OF THE LEDS ARE
ACTIVE HI AND SOME
DATA 1,0,4,0,1,0,5,0,1,0,6,0,1,0,7,0 ' ARE ACTIVE LO - HAVING AN
ARRAY HELPS
DATA 1,0,8,0,0,1,12,1,0,1,13,1,0,1,15,1 ' TO REMOVE THE
CONFUSION.?.)



Post Reply