Advertisement
Guest User

File from Parallax

a guest
Jun 10th, 2010
281
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. ' -----[ Title ]-----------------------------------------------------------
  2. '
  3. ' File...... Easy GPS V1.0.bsp
  4. ' Purpose... Easy GPS Interface
  5. ' Author.... Parallax, Inc.
  6. ' E-mail.... support@parallax.com
  7. ' Started... 02-26-2010
  8. ' Updated...
  9. '
  10. ' {$STAMP BS2p}
  11. ' {$PBASIC 2.5}
  12.  
  13.  
  14. ' -----[ Program Description ]---------------------------------------------
  15.  
  16. ' Connect the Yellow Wire from your Parallax GPS Receiver to P0. The Black
  17. ' wire goes to VSS and the Red wire goes to VDD. All others wires should
  18. ' not be connected (I plugged mine into empty isolated breadboard slots)
  19.  
  20. ' This code is compatible with the PMB-648 & PMB-688 only.
  21.  
  22. ' Reads NMEA data string from GPS receiver and parses data. GPS string is
  23. ' buffered into scratchpad RAM with SPSTR modifier. Once in SPRAM, data is
  24. ' parsed out based on its position.
  25. '
  26. ' $GPRMC,POS_UTC,POS_STAT,LAT,LAT_D,LON,LON_D,SPD,HDG,DATE,MAG_VAR,MAG_REF,*CC
  27. '
  28. ' POS_UTC - UTC of position. Hours, minutes and seconds. (hhmmss)
  29. ' POS_STAT - Position status. (A = Data valid, V = Data invalid)
  30. ' LAT - Latitude (ddmm.ffff)
  31. ' LAT_D - Latitude direction. (N = North, S = South)
  32. ' LON - Longitude (dddmm.ffff)
  33. ' LON_D - Longitude direction (E = East, W = West)
  34. ' SPD - Speed over ground. (knots) (0.0 - 999.9)
  35. ' HDG - Heading/track made good (degrees True) (x.x)
  36. ' DATE - Date (ddmmyy)
  37. ' MAG_VAR - Magnetic variation (degrees) (x.x)
  38. ' MAG_REF - Magnetic variation (E = East, W = West)
  39. ' *CC - Checksum
  40.  
  41. ' This program also reads the $GPGGA string and parses it for altitude.
  42.  
  43.  
  44. ' -----[ Revision History ]------------------------------------------------
  45.  
  46.  
  47.  
  48. ' -----[ I/O Definitions ]-------------------------------------------------
  49.  
  50. GPSpin PIN 0 ' GPS serial input
  51.  
  52.  
  53. ' -----[ Constants ]-------------------------------------------------------
  54.  
  55. T4800 CON 500 ' Baud rate for GPS (typical)
  56.  
  57. MoveTo CON 2 ' DEBUG positioning command
  58. ClrRt CON 11 ' Clear line right of cursor
  59.  
  60. EST CON -5 ' Eastern Standard Time
  61. CST CON -6 ' Central Standard Time
  62. MST CON -7 ' Mountain Standard Time
  63. PST CON -8 ' Pacific Standard Time
  64.  
  65. EDT CON -4 ' Eastern Daylight Time
  66. CDT CON -5 ' Central Daylight Time
  67. MDT CON -6 ' Mountain Daylight Time
  68. PDT CON -7 ' Pacific Daylight Time
  69.  
  70. UTCfix CON PDT ' For Rocklin, CA
  71. Comma CON "," ' Comma
  72. DegSym CON 176 ' Degrees symbol for report
  73. MinSym CON 39 ' Minutes symbol
  74. SecSym CON 34 ' Seconds symbol
  75.  
  76.  
  77. ' -----[ Variables ]-------------------------------------------------------
  78.  
  79. index VAR Byte ' Index into GPS data in SPRAM
  80. flags VAR Byte ' Holds bit values
  81. valid VAR Flags.BIT3 ' Is data valid?
  82. numSats VAR Byte ' Number of satellites
  83.  
  84. tmHrs VAR Byte ' Time fields
  85. tmMins VAR Byte
  86. tmSecs VAR Byte
  87.  
  88. latDeg VAR Byte ' Latitude
  89. latMin VAR Byte
  90. latSec VAR Word
  91. latNS VAR flags.BIT0 ' 0 = N
  92.  
  93. longDeg VAR Byte ' Longitude
  94. longMin VAR Byte
  95. longSec VAR Word
  96. longEW VAR flags.BIT1 ' 0 = E
  97.  
  98. speed VAR Word ' In tenths of mph***************
  99. altitude VAR Word ' In feet************************
  100.  
  101. day VAR Byte ' Day of month, 1 - 31
  102. month VAR flags.NIB1 ' Month, 1 - 12
  103. year VAR Byte ' Year, 00 - 99
  104.  
  105. char VAR Byte ' Byte pulled from SPRAM
  106. workVal VAR Word ' For numeric conversions
  107. eeAddr VAR workVal ' Pointer to EE data
  108.  
  109. field VAR Nib ' Field #
  110. fldWidth VAR field ' Width of field
  111.  
  112.  
  113. ' -----[ EEPROM Data ]-----------------------------------------------------
  114.  
  115. NotValid DATA "No", 0
  116. IsValid DATA "Yes", 0
  117. DaysInMon DATA 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31
  118. MonNames DATA "JAN",0,"FEB",0,"MAR",0,"APR",0,"MAY",0,"JUN",0
  119. DATA "JUL",0,"AUG",0,"SEP",0,"OCT",0,"NOV",0,"DEC",0
  120.  
  121.  
  122. ' -----[ Initialization ]--------------------------------------------------
  123.  
  124. Initialize:
  125. PAUSE 250 ' Let DEBUG open
  126. DEBUG CLS ' Clear the screen
  127. DEBUG "Easy GPS Interface V1.0", CR
  128. DEBUG "======================="
  129.  
  130. Draw_Ruler:
  131. FOR index = 0 TO 65
  132. IF (index = 0) THEN Print_Ones
  133. IF (index // 10) > 0 THEN Print_Ones
  134. DEBUG MoveTo, (7 + index), 3, DEC1 (index / 10)
  135. Print_Ones:
  136. DEBUG MoveTo, (7 + index), 4, DEC1 (index // 10)
  137. Print_Ticks:
  138. IF (index // 10) > 0 THEN Next_Digit
  139. DEBUG MoveTo, (7 + index), 5, "|"
  140. Next_Digit:
  141. NEXT
  142.  
  143. Draw_Data_Labels:
  144. DEBUG MoveTo, 0, 9, "Signal Valid: "
  145. DEBUG MoveTo, 0, 11, " Local Time: "
  146. DEBUG MoveTo, 0, 12, " Local Date: "
  147. DEBUG MoveTo, 0, 14, " Latitude: "
  148. DEBUG MoveTo, 0, 15, " Longitude: "
  149. DEBUG MoveTo, 0, 16, " Altitude: "
  150. DEBUG MoveTo, 0, 17, " Speed: "
  151.  
  152.  
  153. ' -----[ Program Code ]----------------------------------------------------
  154.  
  155. Main:
  156. ' Wait for $GPRMC string and store data in SPRAM
  157. SERIN GPSpin, T4800, 3000, No_GPS_Data, [WAIT("GPRMC,"), SPSTR 65]
  158. GOSUB Parse_GPS_Data ' Extract data from SPRAM
  159.  
  160. Show_GPMRC_String:
  161. DEBUG MoveTo, 0, 6, "$GPRMC," ' Print header
  162. index = 0 ' Start at position UTC
  163.  
  164. Print_GPRMC_Char: ' Print the $GPRMC data string
  165. GET index, char ' Get char from SPRAM
  166. DEBUG char ' Display it
  167. IF char = "*" THEN Print_Checksum ' Look for checksum indicator
  168. index = index + 1 ' Point to next char
  169. GOTO Print_GPRMC_Char
  170.  
  171. Print_Checksum:
  172. GET (index + 1), char ' Get first checksum char
  173. DEBUG char ' Display
  174. GET (index + 2), char ' Get second checksum char
  175. DEBUG char, ClrRt ' Display, clear to end of line
  176.  
  177. Show_Report:
  178. DEBUG MoveTo, 14, 9 ' Was the signal valid?
  179. LOOKUP valid, [NotValid, IsValid], eeAddr' Get answer from EE
  180. GOSUB Print_Z_String ' Print it
  181.  
  182. DEBUG " (", DEC numSats, " Satellites)"
  183.  
  184. DEBUG ClrRt ' Clear end of line
  185. IF (valid = 0) THEN Signal_Not_Valid
  186.  
  187. Get_Altitude:
  188. SERIN GPSpin, T4800, 2000, Signal_Is_Valid, [WAIT("GPGGA,"), SPSTR 75]
  189.  
  190. index = 45 ' Altitude
  191. GOSUB Mixed_To_Tenths ' Convert "xxx.x" To number
  192. altitude = workVal
  193.  
  194. index = 38 : fldWidth = 2 ' Number of sats
  195. GOSUB String_To_Value
  196. numSats = workVal
  197.  
  198. Show_GPGGA_String:
  199. DEBUG MoveTo, 0, 7, "$GPGGA," ' Print header
  200. index = 0 ' Start at position UTC
  201.  
  202. Print_GPGGA_Char: ' Print the $GPRMC data string
  203. GET index, char ' Get char from SPRAM
  204. DEBUG char ' Display it
  205. IF char = "*" THEN Print_Chexum ' Look for checksum indicator
  206. index = index + 1 ' Point to next char
  207. GOTO Print_GPGGA_Char
  208.  
  209. Print_Chexum:
  210. GET (index + 1), char ' Get first checksum char
  211. DEBUG char ' Display
  212. GET (index + 2), char ' Get second checksum char
  213. DEBUG char, ClrRt ' Display, clear to end of line
  214.  
  215. Signal_Is_Valid:
  216. DEBUG MoveTo, 14, 11, DEC2 tmHrs, ":", DEC2 tmMins, ":", DEC2 tmSecs
  217.  
  218. DEBUG MoveTo, 14, 12, DEC2 day, " "
  219. eeAddr = (month - 1) * 4 + MonNames ' get address of month name
  220. GOSUB Print_Z_String ' print it
  221. DEBUG " 20", DEC2 year
  222.  
  223. DEBUG MoveTo, 14, 14, " ", DEC2 latDeg, DegSym, " ", DEC2 latMin, MinSym, " "
  224. DEBUG DEC2 (latSec / 10), ".", DEC1 (latSec // 10), SecSym, " "
  225. DEBUG "N" + (latNS * 5)
  226.  
  227. DEBUG MoveTo, 14, 15, DEC3 longDeg, DegSym, " ", DEC2 longMin, MinSym, " "
  228. DEBUG DEC2 (longSec / 10), ".", DEC1 (longSec // 10), SecSym, " "
  229. DEBUG "E" + (longEW * 18)
  230.  
  231. DEBUG MoveTo, 14, 16, DEC (altitude / 10), ".", DEC1 (altitude //10), " Meters", ClrRt
  232. DEBUG MoveTo, 14, 17, DEC (speed / 10), ".", DEC1 (speed // 10), " MPH "
  233. GOTO Main
  234.  
  235. Signal_Not_Valid:
  236. DEBUG MoveTo, 14, 11, "?", ClrRt ' Clear all fields
  237. DEBUG MoveTo, 14, 12, "?", ClrRt
  238. DEBUG MoveTo, 14, 14, "?", ClrRt
  239. DEBUG MoveTo, 14, 15, "?", ClrRt
  240. DEBUG MoveTo, 14, 16, "?", ClrRt
  241. DEBUG MoveTo, 14, 17, "?", ClrRt
  242. GOTO Main
  243.  
  244.  
  245. ' -----[ Subroutines ]-----------------------------------------------------
  246.  
  247. No_GPS_Data:
  248. DEBUG CLS, "Error: No GPS data detected"
  249. PAUSE 2500
  250. GOTO Initialize ' Try again
  251.  
  252.  
  253. Parse_GPS_Data:
  254. index = 0 : fldWidth = 2 ' UTC hours
  255. GOSUB String_To_Value
  256. tmHrs = workVal
  257.  
  258. index = 2 : fldWidth = 2 ' UTC minutes
  259. GOSUB String_To_Value
  260. tmMins = workVal
  261.  
  262. index = 4 : fldWidth = 2 ' UTC seconds
  263. GOSUB String_To_Value
  264. tmSecs = workVal
  265.  
  266. index = 13 : fldWidth = 2 ' Latitude degrees
  267. GOSUB String_To_Value
  268. latDeg = workVal
  269.  
  270. index = 15 : fldWidth = 2 ' Latitude minutes
  271. GOSUB String_To_Value
  272. latMin = workVal
  273.  
  274. index = 18 : fldWidth = 4 ' Latitude fractional minutes
  275. GOSUB String_To_Value
  276. latSec = workVal ** $0F5C ' x 0.06 --> tenths of seconds
  277.  
  278. index = 25 : fldWidth = 3 ' Longitude degrees
  279. GOSUB String_To_Value
  280. longDeg = workVal
  281.  
  282. index = 28 : fldWidth = 2 ' Longitude minutes
  283. GOSUB String_To_Value
  284. longMin = workVal
  285.  
  286. index = 31 : fldWidth = 4 ' Longitude fractional minutes
  287. GOSUB String_To_Value
  288. longSec = workVal ** $0F5C ' x 0.06 --> tenths of seconds
  289.  
  290. ' Get non-numeric data
  291.  
  292. Get_Valid:
  293. GET 11, char
  294. valid = 1 ' Assume valid
  295. IF (char = "A") THEN Get_Lat_Dir ' It is, so skip
  296. valid = 0 ' Set to 0 if not valid
  297.  
  298. Get_Lat_Dir:
  299. latNS = 0 ' Assume North
  300. GET 19, char ' Check it
  301. IF (char = "N") THEN Get_Long_Dir ' Confirm
  302. latNS = 1 ' Set to 1 if South
  303.  
  304. Get_Long_Dir:
  305. longEW = 0 ' Assume East
  306. GET 33, char ' Check it
  307. IF (char = "E") THEN Get_Speed ' Confirm
  308. longEW = 1 ' Set to 1 if West
  309.  
  310. ' Get variable length data
  311.  
  312. Get_Speed:
  313. index = 38
  314. GOSUB Mixed_To_Tenths ' Convert "xxx.x" To number
  315. ' speed = workVal ' Speed in knots (tenths)
  316. speed = workVal + (workVal ** $2699) ' x 1.1507771555 for mph
  317.  
  318. ' Get date
  319. ' -- past variable data, so we need to use field search
  320.  
  321. Get_Date:
  322. field = 8 ' Set field to find
  323. GOSUB Move_To_Field ' Go get position
  324. PUT 125, index ' Save date position
  325.  
  326. fldWidth = 2
  327. GOSUB String_To_Value
  328. day = workVal ' UTC day, 1 - 31
  329.  
  330. GET 125, index ' Get stored position
  331. index = index + 2 : fldWidth = 2
  332. GOSUB String_To_Value
  333. month = workVal ' UTC month, 1 - 12
  334.  
  335. GET 125, index ' Get stored position
  336. index = index + 4 : fldWidth = 2
  337. GOSUB String_To_Value
  338. year = workVal ' UTC year, 0 - 99
  339.  
  340. ' Adjust date for local position
  341.  
  342. Correct_Local_Time_Date:
  343. workVal = tmHrs + UTCfix ' Add UTC offset
  344. IF (workVal < 24) THEN Adjust_Time ' Midnight crossed?
  345. workVal = UTCfix ' Yes, so adjust date
  346. BRANCH workVal.BIT15, [Location_Leads, Location_Lags]
  347.  
  348. Location_Leads: ' East of Greenwich
  349. day = day + 1 ' No, move to next day
  350. eeAddr = DaysInMon * (month - 1) ' Get days in month
  351. READ eeAddr, char
  352. IF (day <= char) THEN Adjust_Time ' In same month?
  353. month = month + 1 ' No, move to next month
  354. day = 1 ' First day
  355. IF (month < 13) THEN Adjust_Time ' In same year?
  356. month = 1 ' No, set to January
  357. year = year + 1 // 100 ' Add one to year
  358. GOTO Adjust_Time
  359.  
  360. Location_Lags: ' West of Greenwich
  361. day = day - 1 ' Adjust day
  362. IF (day > 0) THEN Adjust_Time ' Same month?
  363. month = month - 1
  364. IF (month > 0) THEN Adjust_Time ' Same year?
  365. month = 1 ' No, set to January
  366. eeAddr = DaysInMon * (month - 1)
  367. READ eeAddr, day ' Get new day
  368. year = year + 99 // 100 ' Set to previous year
  369.  
  370. Adjust_Time:
  371. tmHrs = tmHrs + (24 + UTCfix) // 24 ' Localize hours
  372. RETURN
  373.  
  374. ' *********************************************
  375. ' Convert string data (nnnn) to numeric value
  376. ' -- index - location of first digit in data
  377. ' -- fldWidth - width of data field (1 to 5)
  378. ' -- workVal - returns numeric value of field
  379. ' *********************************************
  380.  
  381. String_To_Value:
  382. workVal = 0
  383. IF (fldWidth = 0) OR (fldWidth > 5) THEN String_To_Value_Done
  384.  
  385. Get_Field_Digit:
  386. GET index, char ' Get digit from field
  387. workVal = workVal + (char - "0") ' Convert, add into value
  388. fldWidth = fldWidth - 1 ' Decrement field width
  389. IF (fldWidth = 0) THEN String_To_Value_Done
  390. workVal = workVal * 10 ' Shift result digits left
  391. index = index + 1 ' Point to next digit
  392. GOTO Get_Field_Digit
  393.  
  394. String_To_Value_Done:
  395. RETURN
  396.  
  397. ' *****************************************************
  398. ' Convert string data (nnn.n) to numeric value (tenths)
  399. ' -- index - location of first digit in data
  400. ' -- workVal - returns numeric value of field
  401. ' *****************************************************
  402.  
  403. Mixed_To_Tenths:
  404. workVal = 0
  405.  
  406. Get_Mixed_Digit:
  407. GET index, char ' Read digit from speed field
  408. IF (char = ".") THEN Get_Mixed_Last ' Skip decimal point
  409. workVal = (workVal + (char - "0")) * 10' Add digit, move data left
  410. index = index + 1 ' Point to next digit
  411. GOTO Get_Mixed_Digit
  412.  
  413. Get_Mixed_Last:
  414. GET (index + 1), char
  415. workVal = workVal + (char - "0") ' Speed in knots
  416. RETURN
  417.  
  418. ' ************************************************************
  419. ' Find field location after variable-length data (i.e., speed)
  420. ' -- field - field number
  421. ' -- index - returns position of first digit in field
  422. ' ************************************************************
  423.  
  424. Move_To_Field:
  425. index = 0
  426. IF (field = 0) THEN Move_To_Field_Done' If zero, we're there
  427.  
  428. Get_Char:
  429. GET index, char ' Get char from SPRAM
  430. IF (char = Comma) THEN Found_Comma ' Is it a comma?
  431. index = index + 1 ' No, move to next char
  432. GOTO Get_Char
  433.  
  434. Found_Comma:
  435. field = field - 1 ' Was comma, dec field coutner
  436. index = index + 1 ' Point to next char
  437. IF (field = 0) THEN Move_To_Field_Done' If field = 0, we're there
  438. GOTO Get_Char
  439.  
  440. Move_To_Field_Done:
  441. RETURN
  442.  
  443. ' *********************************************
  444. ' Print Zero-terminated string stored in EEPROM
  445. ' -- eeAddr - starting character of string
  446. ' *********************************************
  447.  
  448. Print_Z_String:
  449. READ eeAddr, char ' Get char from EE
  450. IF (char = 0) THEN Print_Z_String_Done' If zero, we're done
  451. DEBUG char ' Print the char
  452. eeAddr = eeAddr + 1 ' Point to the next one
  453. GOTO Print_Z_String
  454.  
  455. Print_Z_String_Done:
  456. RETURN
Advertisement
Advertisement
Advertisement
RAW Paste Data Copied
Advertisement