Home
JAQForum Ver 20.06
Log In or Join  
Active Topics
Local Time 01:18 03 May 2024 Privacy Policy
Jump to

Notice. New forum software under development. It's going to miss a few functions and look a bit ugly for a while, but I'm working on it full time now as the old forum was too unstable. Couple days, all good. If you notice any issues, please contact me.

Forum Index : Microcontroller and PC projects : GPS serial with circular line buffer

Author Message
robert.rozee
Guru

Joined: 31/12/2012
Location: New Zealand
Posts: 2290
Posted: 03:22am 18 Dec 2016
Copy link to clipboard 
Print this post

hi,
below is a small demo showing how to achieve the following:

1. configure a SiRF chipset to output a single NMEA sentence repeatedly
2. implement serial input using an interrupt, data saved in a circular line buffer
3. use VT100 codes to clear screen and position cursor
4. extract comma delimited data from a string

NMEA sentences from the GPS are terminated with CR+LF, and this pair is used to split up the data stream into individual lines. up 9 lines can be held in the circular line buffer before it overflows.

the SiRF chipset can be configured with static navigation on or off. when turned on, static navigation attempts to eliminate 'wandering' causing the appearance of false motion. in general, it does this poorly, and so by default the below code turns static navigation off. the SiRF3 default is for it to be turned on.


cheers,
rob :-)


' demonstration of SiRF GPS configuration and
' serial port input with circular line buffer
' (c) Robert Rozee 2016


' configure circular line buffer
' ******************************

Dim CB$(10)
head = 1
tail = 1
running = 0

A$ = ""
B$ = ""

Const clreol$ = Chr$(27)+"[K"

Open "COM1:9600,1024,isr,S2" As #1


' configure SiRF chipset
' **********************

SS1$ = "$PSRF100,0,9600,8,1,0*0C"+Chr$(13)+Chr$(10)
For I = 1 To 10: Read J: SS2$ = SS2$+Chr$(J): Next I ' disable static nav
For I = 1 To 10: Read J: SS3$ = SS3$+Chr$(J): Next I ' enable statis nav
For I = 1 To 32
Read J
If (I>=5) And (I<=28) Then K = K+J ' checksum accumulated in K
If I=29 Then J = K \ 256
If I=30 Then J = K Mod 256
SS4$ = SS4$+Chr$(J)
Next I

Print #1, SS1$; ' enter SiRF binary mode
Pause 100
Print #1, SS2$; ' disable static navigation
Pause 100
Print #1, SS4$; ' return to NMEA mode
Pause 100
running = 1
clrscr


' main loop
' *********

Do
If head<>tail Then ' collect NMEA sentence from buffer
B$ = CB$(tail)
tail = (tail Mod 10)+1
validate(B$) ' verify checksum
EndIf


If Instr(B$,"$GPRMC")=1 Then ' check if sentence is the one we want

Print at$(1,4); B$; clreol$
Print clreol$

For I = 1 To 16 ' extract parameters one at a time
J = Instr(B$,",")
If J=0 Then Exit For
B$ = Mid$(B$,J+1) '$GPxxx is first discarded (param 0)

If I=1 Then GPS.time = Val(B$)
If I=2 Then GPS.OK = (Left$(B$,1)="A")
If I=3 Then
K = Instr(B$,".")
IP% = Val(Left$(B$,K-1))
FP% = Val(Mid$(B$,K+1))
GPS.lat% = IP%*10000+FP% ' 1/10000th of a degree per count
EndIf
If (I=4) And (Left$(B$,1)="S") Then GPS.lat% = -GPS.lat%

If I=5 Then
K = Instr(B$,".")
IP% = Val(Left$(B$,K-1))
FP% = Val(Mid$(B$,K+1))
GPS.long% = IP%*10000+FP% ' 1/10000th of a degree per count
EndIf
If (I=6) And (Left$(B$,1)="W") Then GPS.long% = -GPS.long%

If I=7 Then GPS.sog = Val(B$)*1.852 ' convert knots to km/h
If I=8 Then GPS.cog = Val(B$)
If I=9 Then GPS.date = Val(B$)

Next I

time.H = GPS.time \ 10000
time.M = (GPS.time \ 100) Mod 100
time.S = GPS.time Mod 100

date.D = GPS.date \ 10000
date.M = (GPS.date \ 100) Mod 100
date.Y = GPS.date Mod 100

Print at$(1,8);
Print "time = ",
Print Str$(time.H,2,0," "); "h",
Print Str$(time.M,2,0,"0"); "m",
Print Str$(time.S,2,0,"0"); "s"

Print "date = ",
Print Str$(date.Y,2,0,"0"); "y",
Print Str$(date.M,0,0,"0"); "m",
Print Str$(date.D,0,0,"0"); "d"
Print
Print "lat = ", GPS.lat% \ 10000, ". "; Abs(GPS.lat% Mod 10000)
Print "long = ", GPS.long% \ 10000, ". "; Abs(GPS.long% Mod 10000)
Print
Print "sog = ", GPS.sog; " km/h"; clreol$
Print "cog = ", GPS.cog; " degrees"; clreol$
Print
If GPS.OK Then Print "FIX OK";
Print clreol$;

EndIf

B$ = ""

Loop
End ' end of program



Sub isr ' serial port handler
Local I, S$ length 80
S$ = Input$(72,#1) ' grab data into temporary buffer
If running Then
A$ = Right$(A$,255-Len(S$))+S$ ' add to end of linear buffer
I = Instr(A$,Chr$(13)+Chr$(10)) ' check for eol marker (CR+LF)
Do While I<>0
CB$(head) = Left$(A$,I-1) ' transfer into circular buffer
head = (head Mod 10)+1
If I<254 Then A$ = Mid$(A$,I+2) Else A$=""
I = Instr(A$,Chr$(13)+Chr$(10)) ' check for any more eol markers
Loop
EndIf
End Sub



Sub validate(B$) ' verify B$ is undamaged
Local header, footer, checksum, I
header = Instr(B$,"$") ' header marker, $
footer = Instr(B$,"*") ' footer marker, *
checksum = 0
If (header<>1) Or (footer<>(Len(B$)-2)) Then
B$ = ""
Else
For I = header+1 To footer-1 ' xor together everything in between
checksum = checksum Xor Asc(Mid$(B$,I,1))
Next I
If Hex$(checksum,2)<>Right$(B$,2) Then B$ = ""
EndIf
End Sub ' B$ is cleared if anything is wrong



Function at$(x,y) ' VT100 position cursor
at$ = Chr$(27)+"["+Str$(Y)+";"+Str$(X)+"H"
End Function



Sub clrscr ' VT100 clear screen and home cursor
Print Chr$(27)+"[2J"+Chr$(27)+"[H";
End Sub



' disable static navigation
Data &hA0, &hA2 ' count + header
Data &h00, &h02 ' payload length (2 bytes)
Data &h8F, &h00 ' command + SN flag
Data &h00, &h8F ' payload checksum
Data &hB0, &hB3 ' footer

' enable static navigation
Data &hA0, &hA2 ' count + header
Data &h00, &h02 ' payload length (2 bytes)
Data &h8F, &h01 ' command + SN flag
Data &h00, &h90 ' payload checksum
Data &hB0, &hB3 ' footer

' return to NMEA mode
Data &hA0, &hA2 ' count + header
Data &h00, &h18 ' payload length (24 bytes)
Data &h81, &h02 ' command + mode
Data &h00, &h01 ' GGA (1) (interval + CS flag)
Data &h00, &h01 ' GLL (interval + CS flag)
Data &h00, &h01 ' GSA (1) (interval + CS flag)
Data &h00, &h01 ' GSV (5) (interval + CS flag)
Data &h01, &h01 ' RMC (1) (interval + CS flag) ## 1 sec ##
Data &h00, &h01 ' VTG (1) (interval + CS flag)
Data &h00, &h01 ' MSS (interval + CS flag)
Data &h00, &h00 ' <unused>
Data &h00, &h01 ' ZDA (interval + CS flag)
Data &h00, &h00 ' <unused>
Data &h25, &h80 ' baud rate (9600)
Data &hFF, &hFF ' payload checksum (calculated at runtime)
Data &hB0, &hB3 ' footer







[updated to account for multiple <CR><LF> markers in a single read]Edited by robert.rozee 2016-12-28
 
Print this page


To reply to this topic, you need to log in.

© JAQ Software 2024