Home
JAQForum Ver 20.06
Log In or Join  
Active Topics
Local Time 20:44 15 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 : Using the Parallax PAM-7Q GPS receiver

Author Message
cdeagle
Senior Member

Joined: 22/06/2014
Location: United States
Posts: 261
Posted: 08:55am 01 Mar 2015
Copy link to clipboard 
Print this post

Here's a MMBasic program that reads GPS data from the Parallax PAM-7Q GPS receiver and displays the "time tag" of the data and other relevant information. It uses code from Geoff's GPS.BAS program and TZAdvantage's day-of-the-week subroutine. The software pauses for 5000 milliseconds after each valid data message.

Note that the receiver communicates at 9600 baud via TTL. It could be used for Geoff's GPS-controlled clock or perhaps a GPS tracker.



' pam7q.bas

' demonstrates interface with Parallax PAM-7Q GPS
' receiver (#28509) using MMBasic version 4.6B

' thanks to Geoff and TZAdvantage for their code

' March 1, 2015

'''''''''''''''''''''''''''''''''''''''
' typical $GPRMC data (comma delimited)
'''''''''''''''''''''''''''''''''''''''

' $GPRMC,081836,A,3751.65,S,14507.36,E,000.0,360.0,130998,011. 3,E*62

' contents and format of each data field

' 1 = UTC time (hhmmss.sss)
' 2 = data status (A = data valid, V = data not valid)
' 3 = latitude (ddmm.mmmm)
' 4 = N = north or S = south latitude
' 5 = longitude (ddd.mm.mmmm)
' 6 = E = east or W = west longitude
' 7 = speed over ground (knots)
' 8 = course over ground (degrees true)
' 9 = UTC date (ddmmyy)
' 10 = magnetic variation (degrees; east or west)
' 11 = mode indicator
' 12 = checksum

' 28-pin Micromite-to-GPS pin connections

' pin 21 to RXD, pin 22 to TXD

'''''''''''''''''''''''''''''''''''

' array to hold the GPS data fields

DIM gps_data$(15)

' day-of-the-week and calendar month arrays

dim days$(6), month$(11)

' read day-of-the-week strings

For I = 0 To 6

Read days$(I)

Next I

Data "Sunday"
Data "Monday"
Data "Tuesday"
Data "Wednesday"
Data "Thursday"
Data "Friday"
Data "Saturday"

' read month-of-the-year strings

For I = 0 To 11

Read month$(I)

Next I

Data "January"
Data "February"
Data "March"
Data "April"
Data "May"
Data "June"
Data "July"
data "August"
data "September"
data "October"
data "November"
data "December"

' open com port for communication with GPS receiver

OPEN "COM1:9600" AS #1

DO

' get the next GPS data message

GetGPSData

IF (gps_data$(0) = "GPGSV") THEN

' extract number of satellites in view

nSats = val(gps_data$(3))

endif

IF (gps_data$(0) = "GPRMC") THEN

' $GPRMC is the data message we want

IF (gps_data$(2) = "A") THEN

' "A" means locked on to satellites

' extract and format latitude (data element #3, ddmm.mmmm)

lat_deg$ = LEFT$(gps_data$(3), 2)

lat_min$ = MID$(gps_data$(3), 3, 2)

lat_sec$ = str$(cint(val(mid$(gps_data$(3), 5, 9)) * 60.0))

' extract and format longitude (data element #5, dddmm.mmmm)

long_deg$ = LEFT$(gps_data$(5), 3)

if (left$(long_deg$, 1) = "0") then

long_deg$ = " " + right$(long_deg$, 2)

endif

long_min$ = MID$(gps_data$(5), 4, 2)

long_sec$ = str$(cint(val(mid$(gps_data$(5), 6, 10)) * 60.0))

' extract calendar date (ddmmyy)

wrk_year = val(RIGHT$(gps_data$(9), 2)) + 2000

wrk_month$ = month$(val(MID$(gps_data$(9), 3, 2)) - 1)

wrk_day$ = LEFT$(gps_data$(9), 2)

' extract time stamp

hour$ = LEFT$(gps_data$(1), 2)

min$ = MID$(gps_data$(1), 3, 2)

sec$ = MID$(gps_data$(1), 5, 2)

' format "working" calendar date and compute day-of-the-week

wrk_date$ = wrk_day$ + "-" + MID$(gps_data$(9), 3, 2) + "-" + str$(wrk_year)

DayOfWeek

if (left$(wrk_day$, 1) = "0") then

wrk_day$ = right$(wrk_day$, 1)

endif

' reformat date to mmddyyyy for display

usa_date$ = wrk_month$ + " " + wrk_day$ + "," + " " + str$(wrk_year)

' display results

print

print

print days$(dow), " ", usa_date$, " ", hour$ + ":" + min$ + ":" + sec$ + " UTC"

print

PRINT "Latitude "; lat_deg$ + " deg " + lat_min$ + " min " + lat_sec$ + " sec " + gps_data$(4)

print

PRINT "Longitude "; long_deg$ + " deg " + long_min$ + " min " + long_sec$ + " sec " + gps_data$(6)

print

if (nSats <> 0) then

print "number of satellites in view ", nSats

endif

' pause 5000 ms

pause 5000

ELSE

'PRINT "GPS searching..."

ENDIF

ENDIF

LOOP

end

''''''''''''''
''''''''''''''

SUB GetGPSData

' subroutine to load the GPS data fields
' into the string array gps_data$()

DO

DO WHILE (INPUT$(1, #1) <> "$")

' wait for a valid message (first character = "$")

LOOP

' extract thirteen data items for the message

FOR i = 0 TO 15

' clear current array element for data

gps_data$(i) = ""

' parse the individual data items

DO

' get the next character

x$ = INPUT$(1, #1)

IF (x$ = ",") THEN

' encountered data deliminter = ","

exit

endif

IF (x$ = "*") THEN

' encountered first part of checksum
' we have all the data so exit subroutine

exit sub

endif

' add this character or number to the current data field

gps_data$(i) = gps_data$(i) + x$

LOOP

NEXT i

LOOP

END SUB

'''''''
'''''''

Sub DayOfWeek

' calculate day of the week using
' TZAdvantage's algorithm

' assumed date format = dd-mm-yyy

a = Int((14-Val(Mid$(wrk_date$, 4, 2))) / 12)

m = Val(Mid$(wrk_date$, 4, 2)) + 12 * a - 2

y = Val(Mid$(wrk_date$, 7, 4)) - a

d = Val(Mid$(wrk_date$, 1, 2))

dow = (d + y + Int(y / 4) - Int(y / 100) + Int(y / 400) + Int(31 * m / 12)) Mod 7

End Sub

 
cdeagle
Senior Member

Joined: 22/06/2014
Location: United States
Posts: 261
Posted: 09:16am 01 Mar 2015
Copy link to clipboard 
Print this post

Here's an example of the output displayed by the program.

Sunday March 1, 2015 19:14:50 UTC

Latitude 28 deg 23 min 46 sec N

Longitude 80 deg 35 min 55 sec W

number of satellites in view 14
 
viscomjim
Guru

Joined: 08/01/2014
Location: United States
Posts: 925
Posted: 03:29pm 01 Mar 2015
Copy link to clipboard 
Print this post

Nice work cdeagle! will have to give it a try.

Also, welcome!!!!!
 
cdeagle
Senior Member

Joined: 22/06/2014
Location: United States
Posts: 261
Posted: 04:34am 15 Mar 2015
Copy link to clipboard 
Print this post

Here's a picture of a "portable" prototype using this GPS receiver.





This configuration uses Big Mick's MuP board (top left). The Micromite and LCD use 5 volts from a rechargeable battery. I'm using Ron Hackett's power supply board without the regulator (bottom right). The GPS (top center) and Micromite use 3.3 volts from the MuP on-board regulator. The component at the top right is a USB-to-TTL serial device used for programming the Micromite.

The 4-by-20 LCD displays UTC, day-of-the-week, and calendar date along with the latitude and longitude.

The software is basically the version posted earlier with output to the LCD.

 
viscomjim
Guru

Joined: 08/01/2014
Location: United States
Posts: 925
Posted: 04:43am 15 Mar 2015
Copy link to clipboard 
Print this post

Nice work. Its always cool when things come together and actually work they way you want them to. Keep it coming!!!
 
cdeagle
Senior Member

Joined: 22/06/2014
Location: United States
Posts: 261
Posted: 07:03am 19 May 2015
Copy link to clipboard 
Print this post


Here's a version of the software that logs GPS information to a microSD card using the Sparkfun OpenLog board. It writes the calendar date, UTC time, latitude and longitude and ground speed via COM2.

The latitude and longitude are in degrees with north latitudes positive, south latitude negative, east longitudes positive and west longitudes negative.

Additional data can be easily added to the stream.

option AUTORUN on

' lcd_pam7q.bas

' demonstrates interface with Parallax PAM-7Q GPS
' receiver (#28509) and data logging to OpenLog
' using MMBasic version 4.6B

' thanks to Geoff and TZAdvantage for their code

' May 19, 2015

'''''''''''''''''''''''''''''''''''''''
' typical $GPRMC data (comma delimited)
'''''''''''''''''''''''''''''''''''''''

' $GPRMC,081836,A,3751.65,S,14507.36,E,000.0,360.0,130998,011.3,E*62

' contents and format of each data field

' 1 = UTC time (hhmmss.sss)
' 2 = data status (A = data valid, V = data not valid)
' 3 = latitude (ddmm.mmmm)
' 4 = N = north or S = south latitude
' 5 = longitude (ddd.mm.mmmm)
' 6 = E = east or W = west longitude
' 7 = speed over ground (knots)
' 8 = course over ground (degrees true)
' 9 = UTC date (ddmmyy)
' 10 = magnetic variation (degrees; east or west)
' 11 = mode indicator
' 12 = checksum

' 28-pin Micromite-to-GPS pin connections (COM1)

' pin 21 to RXD, pin 22 to TXD

' 28-pin Miromite-to-OpenLog connections (COM2)

' pin 9 to RXI, pin 10 to TXO

' initialize LCD

lcd init 23, 24, 25, 26, 15, 16

'''''''''''''''''''''''''''''''''''

' array to hold the GPS data fields

DIM gps_data$(15)

' day-of-the-week and calendar month arrays

dim days$(6), month$(11)

' read day-of-the-week strings

For I = 0 To 6

Read days$(I)

Next I

Data "Sun"
Data "Mon"
Data "Tue"
Data "Wed"
Data "Thu"
Data "Fri"
Data "Sat"

' read month-of-the-year strings

For I = 0 To 11

Read month$(I)

Next I

Data "Jan"
Data "Feb"
Data "Mar"
Data "Apr"
Data "May"
Data "Jun"
Data "Jul"
data "Aug"
data "Sep"
data "Oct"
data "Nov"
data "Dec"

' open com port for communication with GPS receiver

OPEN "COM1:9600" AS #1

' open com port for communication with OpenLog

OPEN "COM2:9600" AS #5

DO

' get the next GPS data message

GetGPSData

IF (gps_data$(0) = "GPGSV") THEN

' extract number of satellites in view

nSats = val(gps_data$(3))

'print "number of satellites = ", nSats

endif

IF (gps_data$(0) = "GPRMC") THEN

' $GPRMC is the data message we want

IF (gps_data$(2) = "A") THEN

' "A" means locked on to satellites

' extract and format latitude (data element #3, ddmm.mmmm)

lat_deg$ = LEFT$(gps_data$(3), 2)

lat_min$ = MID$(gps_data$(3), 3, 2)

lat_sec$ = str$(cint(val(mid$(gps_data$(3), 5, 9)) * 60.0))

latitude = val(lat_deg$) + val(lat_min$) / 60.0 + val(lat_sec$) / 3600.0

if (gps_data$(4) = "S") then

latitude = -latitude

end if

' extract and format longitude (data element #5, dddmm.mmmm)

long_deg$ = LEFT$(gps_data$(5), 3)

if (left$(long_deg$, 1) = "0") then

long_deg$ = " " + right$(long_deg$, 2)

endif

long_min$ = MID$(gps_data$(5), 4, 2)

long_sec$ = str$(cint(val(mid$(gps_data$(5), 6, 10)) * 60.0))

longitude = val(long_deg$) + val(long_min$) / 60.0 + val(long_sec$) / 3600.0

if (gps_data$(6) = "W") then

longitude = -longitude

end if

' extract calendar date (data element #9; ddmmyy)

wrk_year = val(RIGHT$(gps_data$(9), 2)) + 2000

cal_month = val(MID$(gps_data$(9), 3, 2))

wrk_month$ = month$(cal_month - 1)

wrk_day$ = LEFT$(gps_data$(9), 2)

' extract time stamp

hour$ = LEFT$(gps_data$(1), 2)

min$ = MID$(gps_data$(1), 3, 2)

sec$ = MID$(gps_data$(1), 5, 2)

' format "working" calendar date and compute day-of-the-week

wrk_date$ = wrk_day$ + "-" + MID$(gps_data$(9), 3, 2) + "-" + str$(wrk_year)

DayOfWeek

if (left$(wrk_day$, 1) = "0") then

wrk_day$ = right$(wrk_day$, 1)

endif

' reformat date to mmddyyyy for display

usa_date$ = wrk_month$ + " " + wrk_day$ + "," + " " + str$(wrk_year)

' display results on lcd

wrkstr1$ = " " + days$(dow) + " " + usa_date$

lcd 2,1, wrkstr1$

wrkstr2$ = " " + hour$ + ":" + min$ + ":" + sec$ + " UTC"

lcd 1,1, wrkstr2$

wrkstr3$ = " Lat " + lat_deg$ + "d " + lat_min$ + "m " + lat_sec$ + "s " + gps_data$(4)

lcd 3, 1, wrkstr3$

wrkstr4$ = " Lon " + long_deg$ + "d " + long_min$ + "m " + long_sec$ + "s " + gps_data$(6)

lcd 4, 1, wrkstr4$

print #5, str$(cal_month);"-";wrk_day$;"-";str$(wrk_year);",";hour$ + ":" + min$ + ":" + sec$; ",";latitude;",";longitude;","; gps_data$(7)

' pause 30 seconds between updates

pause 30000

ELSE

'lcd 1, 1, "GPS searching..."

ENDIF

ENDIF

LOOP

close #5

end

''''''''''''
''''''''''''

SUB GetGPSData

' subroutine to load the GPS data fields
' into the string array gps_data$()

DO

DO WHILE (INPUT$(1, #1) <> "$")

' wait for a valid message (first character = "$")

LOOP

' extract thirteen data items for the message

FOR i = 0 TO 15

' clear current array element for data

gps_data$(i) = ""

' parse the individual data items

DO

' get the next character

x$ = INPUT$(1, #1)

IF (x$ = ",") THEN

' encountered data deliminter = ","

exit

endif

IF (x$ = "*") THEN

' encountered first part of checksum
' we have all the data so exit subroutine

exit sub

endif

' add this character or number to the current data field

gps_data$(i) = gps_data$(i) + x$

LOOP

NEXT i

LOOP

END SUB

'''''''''''
'''''''''''

Sub DayOfWeek

' calculate day of the week using
' TZAdvantage's algorithm

' assumed date format = dd-mm-yyy

a = Int((14-Val(Mid$(wrk_date$, 4, 2))) / 12)

m = Val(Mid$(wrk_date$, 4, 2)) + 12 * a - 2

y = Val(Mid$(wrk_date$, 7, 4)) - a

d = Val(Mid$(wrk_date$, 1, 2))

dow = (d + y + Int(y / 4) - Int(y / 100) + Int(y / 400) + Int(31 * m / 12)) Mod 7

End Sub

 
Print this page


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

© JAQ Software 2024