Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- ' -----[ Title ]-----------------------------------------------------------
- '
- ' File...... Easy GPS V1.0.bsp
- ' Purpose... Easy GPS Interface
- ' Author.... Parallax, Inc.
- ' E-mail.... support@parallax.com
- ' Started... 02-26-2010
- ' Updated...
- '
- ' {$STAMP BS2p}
- ' {$PBASIC 2.5}
- ' -----[ Program Description ]---------------------------------------------
- ' Connect the Yellow Wire from your Parallax GPS Receiver to P0. The Black
- ' wire goes to VSS and the Red wire goes to VDD. All others wires should
- ' not be connected (I plugged mine into empty isolated breadboard slots)
- ' This code is compatible with the PMB-648 & PMB-688 only.
- ' Reads NMEA data string from GPS receiver and parses data. GPS string is
- ' buffered into scratchpad RAM with SPSTR modifier. Once in SPRAM, data is
- ' parsed out based on its position.
- '
- ' $GPRMC,POS_UTC,POS_STAT,LAT,LAT_D,LON,LON_D,SPD,HDG,DATE,MAG_VAR,MAG_REF,*CC
- '
- ' POS_UTC - UTC of position. Hours, minutes and seconds. (hhmmss)
- ' POS_STAT - Position status. (A = Data valid, V = Data invalid)
- ' LAT - Latitude (ddmm.ffff)
- ' LAT_D - Latitude direction. (N = North, S = South)
- ' LON - Longitude (dddmm.ffff)
- ' LON_D - Longitude direction (E = East, W = West)
- ' SPD - Speed over ground. (knots) (0.0 - 999.9)
- ' HDG - Heading/track made good (degrees True) (x.x)
- ' DATE - Date (ddmmyy)
- ' MAG_VAR - Magnetic variation (degrees) (x.x)
- ' MAG_REF - Magnetic variation (E = East, W = West)
- ' *CC - Checksum
- ' This program also reads the $GPGGA string and parses it for altitude.
- ' -----[ Revision History ]------------------------------------------------
- ' -----[ I/O Definitions ]-------------------------------------------------
- GPSpin PIN 0 ' GPS serial input
- ' -----[ Constants ]-------------------------------------------------------
- T4800 CON 500 ' Baud rate for GPS (typical)
- MoveTo CON 2 ' DEBUG positioning command
- ClrRt CON 11 ' Clear line right of cursor
- EST CON -5 ' Eastern Standard Time
- CST CON -6 ' Central Standard Time
- MST CON -7 ' Mountain Standard Time
- PST CON -8 ' Pacific Standard Time
- EDT CON -4 ' Eastern Daylight Time
- CDT CON -5 ' Central Daylight Time
- MDT CON -6 ' Mountain Daylight Time
- PDT CON -7 ' Pacific Daylight Time
- UTCfix CON PDT ' For Rocklin, CA
- Comma CON "," ' Comma
- DegSym CON 176 ' Degrees symbol for report
- MinSym CON 39 ' Minutes symbol
- SecSym CON 34 ' Seconds symbol
- ' -----[ Variables ]-------------------------------------------------------
- index VAR Byte ' Index into GPS data in SPRAM
- flags VAR Byte ' Holds bit values
- valid VAR Flags.BIT3 ' Is data valid?
- numSats VAR Byte ' Number of satellites
- tmHrs VAR Byte ' Time fields
- tmMins VAR Byte
- tmSecs VAR Byte
- latDeg VAR Byte ' Latitude
- latMin VAR Byte
- latSec VAR Word
- latNS VAR flags.BIT0 ' 0 = N
- longDeg VAR Byte ' Longitude
- longMin VAR Byte
- longSec VAR Word
- longEW VAR flags.BIT1 ' 0 = E
- speed VAR Word ' In tenths of mph***************
- altitude VAR Word ' In feet************************
- day VAR Byte ' Day of month, 1 - 31
- month VAR flags.NIB1 ' Month, 1 - 12
- year VAR Byte ' Year, 00 - 99
- char VAR Byte ' Byte pulled from SPRAM
- workVal VAR Word ' For numeric conversions
- eeAddr VAR workVal ' Pointer to EE data
- field VAR Nib ' Field #
- fldWidth VAR field ' Width of field
- ' -----[ EEPROM Data ]-----------------------------------------------------
- NotValid DATA "No", 0
- IsValid DATA "Yes", 0
- DaysInMon DATA 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
- MonNames DATA "JAN",0,"FEB",0,"MAR",0,"APR",0,"MAY",0,"JUN",0
- DATA "JUL",0,"AUG",0,"SEP",0,"OCT",0,"NOV",0,"DEC",0
- ' -----[ Initialization ]--------------------------------------------------
- Initialize:
- PAUSE 250 ' Let DEBUG open
- DEBUG CLS ' Clear the screen
- DEBUG "Easy GPS Interface V1.0", CR
- DEBUG "======================="
- Draw_Ruler:
- FOR index = 0 TO 65
- IF (index = 0) THEN Print_Ones
- IF (index // 10) > 0 THEN Print_Ones
- DEBUG MoveTo, (7 + index), 3, DEC1 (index / 10)
- Print_Ones:
- DEBUG MoveTo, (7 + index), 4, DEC1 (index // 10)
- Print_Ticks:
- IF (index // 10) > 0 THEN Next_Digit
- DEBUG MoveTo, (7 + index), 5, "|"
- Next_Digit:
- NEXT
- Draw_Data_Labels:
- DEBUG MoveTo, 0, 9, "Signal Valid: "
- DEBUG MoveTo, 0, 11, " Local Time: "
- DEBUG MoveTo, 0, 12, " Local Date: "
- DEBUG MoveTo, 0, 14, " Latitude: "
- DEBUG MoveTo, 0, 15, " Longitude: "
- DEBUG MoveTo, 0, 16, " Altitude: "
- DEBUG MoveTo, 0, 17, " Speed: "
- ' -----[ Program Code ]----------------------------------------------------
- Main:
- ' Wait for $GPRMC string and store data in SPRAM
- SERIN GPSpin, T4800, 3000, No_GPS_Data, [WAIT("GPRMC,"), SPSTR 65]
- GOSUB Parse_GPS_Data ' Extract data from SPRAM
- Show_GPMRC_String:
- DEBUG MoveTo, 0, 6, "$GPRMC," ' Print header
- index = 0 ' Start at position UTC
- Print_GPRMC_Char: ' Print the $GPRMC data string
- GET index, char ' Get char from SPRAM
- DEBUG char ' Display it
- IF char = "*" THEN Print_Checksum ' Look for checksum indicator
- index = index + 1 ' Point to next char
- GOTO Print_GPRMC_Char
- Print_Checksum:
- GET (index + 1), char ' Get first checksum char
- DEBUG char ' Display
- GET (index + 2), char ' Get second checksum char
- DEBUG char, ClrRt ' Display, clear to end of line
- Show_Report:
- DEBUG MoveTo, 14, 9 ' Was the signal valid?
- LOOKUP valid, [NotValid, IsValid], eeAddr' Get answer from EE
- GOSUB Print_Z_String ' Print it
- DEBUG " (", DEC numSats, " Satellites)"
- DEBUG ClrRt ' Clear end of line
- IF (valid = 0) THEN Signal_Not_Valid
- Get_Altitude:
- SERIN GPSpin, T4800, 2000, Signal_Is_Valid, [WAIT("GPGGA,"), SPSTR 75]
- index = 45 ' Altitude
- GOSUB Mixed_To_Tenths ' Convert "xxx.x" To number
- altitude = workVal
- index = 38 : fldWidth = 2 ' Number of sats
- GOSUB String_To_Value
- numSats = workVal
- Show_GPGGA_String:
- DEBUG MoveTo, 0, 7, "$GPGGA," ' Print header
- index = 0 ' Start at position UTC
- Print_GPGGA_Char: ' Print the $GPRMC data string
- GET index, char ' Get char from SPRAM
- DEBUG char ' Display it
- IF char = "*" THEN Print_Chexum ' Look for checksum indicator
- index = index + 1 ' Point to next char
- GOTO Print_GPGGA_Char
- Print_Chexum:
- GET (index + 1), char ' Get first checksum char
- DEBUG char ' Display
- GET (index + 2), char ' Get second checksum char
- DEBUG char, ClrRt ' Display, clear to end of line
- Signal_Is_Valid:
- DEBUG MoveTo, 14, 11, DEC2 tmHrs, ":", DEC2 tmMins, ":", DEC2 tmSecs
- DEBUG MoveTo, 14, 12, DEC2 day, " "
- eeAddr = (month - 1) * 4 + MonNames ' get address of month name
- GOSUB Print_Z_String ' print it
- DEBUG " 20", DEC2 year
- DEBUG MoveTo, 14, 14, " ", DEC2 latDeg, DegSym, " ", DEC2 latMin, MinSym, " "
- DEBUG DEC2 (latSec / 10), ".", DEC1 (latSec // 10), SecSym, " "
- DEBUG "N" + (latNS * 5)
- DEBUG MoveTo, 14, 15, DEC3 longDeg, DegSym, " ", DEC2 longMin, MinSym, " "
- DEBUG DEC2 (longSec / 10), ".", DEC1 (longSec // 10), SecSym, " "
- DEBUG "E" + (longEW * 18)
- DEBUG MoveTo, 14, 16, DEC (altitude / 10), ".", DEC1 (altitude //10), " Meters", ClrRt
- DEBUG MoveTo, 14, 17, DEC (speed / 10), ".", DEC1 (speed // 10), " MPH "
- GOTO Main
- Signal_Not_Valid:
- DEBUG MoveTo, 14, 11, "?", ClrRt ' Clear all fields
- DEBUG MoveTo, 14, 12, "?", ClrRt
- DEBUG MoveTo, 14, 14, "?", ClrRt
- DEBUG MoveTo, 14, 15, "?", ClrRt
- DEBUG MoveTo, 14, 16, "?", ClrRt
- DEBUG MoveTo, 14, 17, "?", ClrRt
- GOTO Main
- ' -----[ Subroutines ]-----------------------------------------------------
- No_GPS_Data:
- DEBUG CLS, "Error: No GPS data detected"
- PAUSE 2500
- GOTO Initialize ' Try again
- Parse_GPS_Data:
- index = 0 : fldWidth = 2 ' UTC hours
- GOSUB String_To_Value
- tmHrs = workVal
- index = 2 : fldWidth = 2 ' UTC minutes
- GOSUB String_To_Value
- tmMins = workVal
- index = 4 : fldWidth = 2 ' UTC seconds
- GOSUB String_To_Value
- tmSecs = workVal
- index = 13 : fldWidth = 2 ' Latitude degrees
- GOSUB String_To_Value
- latDeg = workVal
- index = 15 : fldWidth = 2 ' Latitude minutes
- GOSUB String_To_Value
- latMin = workVal
- index = 18 : fldWidth = 4 ' Latitude fractional minutes
- GOSUB String_To_Value
- latSec = workVal ** $0F5C ' x 0.06 --> tenths of seconds
- index = 25 : fldWidth = 3 ' Longitude degrees
- GOSUB String_To_Value
- longDeg = workVal
- index = 28 : fldWidth = 2 ' Longitude minutes
- GOSUB String_To_Value
- longMin = workVal
- index = 31 : fldWidth = 4 ' Longitude fractional minutes
- GOSUB String_To_Value
- longSec = workVal ** $0F5C ' x 0.06 --> tenths of seconds
- ' Get non-numeric data
- Get_Valid:
- GET 11, char
- valid = 1 ' Assume valid
- IF (char = "A") THEN Get_Lat_Dir ' It is, so skip
- valid = 0 ' Set to 0 if not valid
- Get_Lat_Dir:
- latNS = 0 ' Assume North
- GET 19, char ' Check it
- IF (char = "N") THEN Get_Long_Dir ' Confirm
- latNS = 1 ' Set to 1 if South
- Get_Long_Dir:
- longEW = 0 ' Assume East
- GET 33, char ' Check it
- IF (char = "E") THEN Get_Speed ' Confirm
- longEW = 1 ' Set to 1 if West
- ' Get variable length data
- Get_Speed:
- index = 38
- GOSUB Mixed_To_Tenths ' Convert "xxx.x" To number
- ' speed = workVal ' Speed in knots (tenths)
- speed = workVal + (workVal ** $2699) ' x 1.1507771555 for mph
- ' Get date
- ' -- past variable data, so we need to use field search
- Get_Date:
- field = 8 ' Set field to find
- GOSUB Move_To_Field ' Go get position
- PUT 125, index ' Save date position
- fldWidth = 2
- GOSUB String_To_Value
- day = workVal ' UTC day, 1 - 31
- GET 125, index ' Get stored position
- index = index + 2 : fldWidth = 2
- GOSUB String_To_Value
- month = workVal ' UTC month, 1 - 12
- GET 125, index ' Get stored position
- index = index + 4 : fldWidth = 2
- GOSUB String_To_Value
- year = workVal ' UTC year, 0 - 99
- ' Adjust date for local position
- Correct_Local_Time_Date:
- workVal = tmHrs + UTCfix ' Add UTC offset
- IF (workVal < 24) THEN Adjust_Time ' Midnight crossed?
- workVal = UTCfix ' Yes, so adjust date
- BRANCH workVal.BIT15, [Location_Leads, Location_Lags]
- Location_Leads: ' East of Greenwich
- day = day + 1 ' No, move to next day
- eeAddr = DaysInMon * (month - 1) ' Get days in month
- READ eeAddr, char
- IF (day <= char) THEN Adjust_Time ' In same month?
- month = month + 1 ' No, move to next month
- day = 1 ' First day
- IF (month < 13) THEN Adjust_Time ' In same year?
- month = 1 ' No, set to January
- year = year + 1 // 100 ' Add one to year
- GOTO Adjust_Time
- Location_Lags: ' West of Greenwich
- day = day - 1 ' Adjust day
- IF (day > 0) THEN Adjust_Time ' Same month?
- month = month - 1
- IF (month > 0) THEN Adjust_Time ' Same year?
- month = 1 ' No, set to January
- eeAddr = DaysInMon * (month - 1)
- READ eeAddr, day ' Get new day
- year = year + 99 // 100 ' Set to previous year
- Adjust_Time:
- tmHrs = tmHrs + (24 + UTCfix) // 24 ' Localize hours
- RETURN
- ' *********************************************
- ' Convert string data (nnnn) to numeric value
- ' -- index - location of first digit in data
- ' -- fldWidth - width of data field (1 to 5)
- ' -- workVal - returns numeric value of field
- ' *********************************************
- String_To_Value:
- workVal = 0
- IF (fldWidth = 0) OR (fldWidth > 5) THEN String_To_Value_Done
- Get_Field_Digit:
- GET index, char ' Get digit from field
- workVal = workVal + (char - "0") ' Convert, add into value
- fldWidth = fldWidth - 1 ' Decrement field width
- IF (fldWidth = 0) THEN String_To_Value_Done
- workVal = workVal * 10 ' Shift result digits left
- index = index + 1 ' Point to next digit
- GOTO Get_Field_Digit
- String_To_Value_Done:
- RETURN
- ' *****************************************************
- ' Convert string data (nnn.n) to numeric value (tenths)
- ' -- index - location of first digit in data
- ' -- workVal - returns numeric value of field
- ' *****************************************************
- Mixed_To_Tenths:
- workVal = 0
- Get_Mixed_Digit:
- GET index, char ' Read digit from speed field
- IF (char = ".") THEN Get_Mixed_Last ' Skip decimal point
- workVal = (workVal + (char - "0")) * 10' Add digit, move data left
- index = index + 1 ' Point to next digit
- GOTO Get_Mixed_Digit
- Get_Mixed_Last:
- GET (index + 1), char
- workVal = workVal + (char - "0") ' Speed in knots
- RETURN
- ' ************************************************************
- ' Find field location after variable-length data (i.e., speed)
- ' -- field - field number
- ' -- index - returns position of first digit in field
- ' ************************************************************
- Move_To_Field:
- index = 0
- IF (field = 0) THEN Move_To_Field_Done' If zero, we're there
- Get_Char:
- GET index, char ' Get char from SPRAM
- IF (char = Comma) THEN Found_Comma ' Is it a comma?
- index = index + 1 ' No, move to next char
- GOTO Get_Char
- Found_Comma:
- field = field - 1 ' Was comma, dec field coutner
- index = index + 1 ' Point to next char
- IF (field = 0) THEN Move_To_Field_Done' If field = 0, we're there
- GOTO Get_Char
- Move_To_Field_Done:
- RETURN
- ' *********************************************
- ' Print Zero-terminated string stored in EEPROM
- ' -- eeAddr - starting character of string
- ' *********************************************
- Print_Z_String:
- READ eeAddr, char ' Get char from EE
- IF (char = 0) THEN Print_Z_String_Done' If zero, we're done
- DEBUG char ' Print the char
- eeAddr = eeAddr + 1 ' Point to the next one
- GOTO Print_Z_String
- Print_Z_String_Done:
- RETURN
Advertisement
Advertisement
Advertisement
RAW Paste Data
Copied
Advertisement