Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of MODGPS by
GPS.h
00001 /* 00002 Copyright (c) 2010 Andy Kirkham 00003 00004 Permission is hereby granted, free of charge, to any person obtaining a copy 00005 of this software and associated documentation files (the "Software"), to deal 00006 in the Software without restriction, including without limitation the rights 00007 to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 00008 copies of the Software, and to permit persons to whom the Software is 00009 furnished to do so, subject to the following conditions: 00010 00011 The above copyright notice and this permission notice shall be included in 00012 all copies or substantial portions of the Software. 00013 00014 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00015 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00016 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00017 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00018 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 00019 OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 00020 THE SOFTWARE. 00021 */ 00022 00023 #ifndef GPS_H 00024 #define GPS_H 00025 00026 #include "mbed.h" 00027 #include "GPS_Time.h" 00028 #include "GPS_Geodetic.h" 00029 00030 #define GPS_RBR 0x00 00031 #define GPS_THR 0x00 00032 #define GPS_DLL 0x00 00033 #define GPS_IER 0x04 00034 #define GPS_DML 0x04 00035 #define GPS_IIR 0x08 00036 #define GPS_FCR 0x08 00037 #define GPS_LCR 0x0C 00038 #define GPS_LSR 0x14 00039 #define GPS_SCR 0x1C 00040 #define GPS_ACR 0x20 00041 #define GPS_ICR 0x24 00042 #define GPS_FDR 0x28 00043 #define GPS_TER 0x30 00044 00045 #define GPS_BUFFER_LEN 128 00046 #define GPS_TICKTOCK 10000 00047 00048 /** @defgroup API The MODGPS API */ 00049 00050 /** GPS module 00051 * @author Andy Kirkham 00052 * @see http://mbed.org/cookbook/MODGPS 00053 * @see example1.cpp 00054 * @see example2.cpp 00055 * @see API 00056 * 00057 * @image html /media/uploads/AjK/gps_interfaces.png "Wiring up the GPS module" 00058 * 00059 * Example: 00060 * @code 00061 * #include "mbed.h" 00062 * #include "GPS.h" 00063 * 00064 * DigitalOut led1(LED1); 00065 * Serial pc(USBTX, USBRX); 00066 * GPS gps(NC, p10); 00067 * 00068 * int main() { 00069 * GPS_Time t; 00070 * 00071 * // Wait for the GPS NMEA data to become valid. 00072 * while (!gps.isTimeValid()) { 00073 * led1 = !led1; 00074 * wait(1); 00075 * } 00076 * 00077 * gps.timeNow(&t); 00078 * 00079 * pc.printf("The time/date is %02d:%02d:%02d %02d/%02d/%04d\r\n", 00080 * t.hour, t.minute, t.second, t.day, t.month, t.year); 00081 * 00082 * // Wait until at least four satellites produce a position fix and a valid quality. 00083 * while (gps.numOfSats() < 4 && gps.getGPSquality != 0) { 00084 * led1 = !led1; 00085 * wait(1); 00086 * } 00087 * 00088 * pc.printf("Lat = %.4f Lon = %.4f Alt = %.1fkm\r\n", 00089 * gps.latitude(), gps.longitude, gps.altitude()); 00090 * 00091 * // Make the LED go steady to indicate we have finished. 00092 * led1 = 1; 00093 * 00094 * while(1) {} 00095 * } 00096 * @endcode 00097 */ 00098 00099 class GPS : Serial { 00100 public: 00101 00102 //! The PPS edge type to interrupt on. 00103 enum ppsEdgeType { 00104 ppsRise = 0, /*!< Use the rising edge (default). */ 00105 ppsFall /*!< Use the falling edge. */ 00106 }; 00107 00108 //! A copy of the Serial parity enum 00109 enum Parity { 00110 None = 0 00111 , Odd 00112 , Even 00113 , Forced1 00114 , Forced0 00115 }; 00116 00117 //! GPS constructor. 00118 /** 00119 * The GPS constructor is used to initialise the GPS object. 00120 * 00121 * @param tx Usually unused and set to NC 00122 * @param rx The RX pin the GPS is connected to, p10, p14( OR p25), p27. 00123 * @param name An option name for RPC usage. 00124 */ 00125 GPS(PinName tx, PinName rx, const char *name = NULL); 00126 00127 //! Is the time reported by the GPS valid. 00128 /** 00129 * Method used to check the validity of the time the GPS module is reporting. 00130 * 00131 * @code 00132 * // Assuming we have a GPS object previously created... 00133 * GPS gps(NC, p9); 00134 * 00135 * if (gps.isTimeValid()) { 00136 * // Time is valid :) 00137 * } 00138 * else { 00139 * // Doh, time is not valid :( 00140 * ) 00141 * 00142 * @endcode 00143 * 00144 * @ingroup API 00145 * @return bool true if valid, false otherwise 00146 */ 00147 bool isTimeValid(void) { return theTime.status == 'V' ? false : true; } 00148 00149 //! Is the positional fix reported by the GPS valid. 00150 /** 00151 * Method used to check the validity of the positional data. This method 00152 * returns the GGA field, 0 is "bad, 1 is "ok", etc. See the NMEA GGA 00153 * description for more details. 00154 * 00155 * @code 00156 * // Assuming we have a GPS object previously created... 00157 * GPS gps(NC, p9); 00158 * 00159 * if (gps.getGPSquality() == 0) { 00160 * // The location fix is no good/not accurate :( 00161 * } 00162 * else { 00163 * // All good, can use last fix data. 00164 * ) 00165 * 00166 * @endcode 00167 * 00168 * @ingroup API 00169 * @return int 0 on no fix, 1... (see NMEA GGA for more details). 00170 */ 00171 int getGPSquality(void) { return thePlace.getGPSquality(); } 00172 00173 //! How many satellites were used in the last fix. 00174 /** 00175 * Method returns the number of GPS satellites used on the last fix. 00176 * 00177 * @code 00178 * // Assuming we have a GPS object previously created... 00179 * GPS gps(NC, p9); 00180 * 00181 * int sats = gps.numOfSats(); 00182 * 00183 * @endcode 00184 * 00185 * @ingroup API 00186 * @return int The number of satellites. 00187 */ 00188 int numOfSats(void) { return thePlace.numOfSats(); } 00189 00190 //! What was the last reported latitude (in degrees) 00191 /** 00192 * Method returns a double in degrees, positive being North, negative being South. 00193 * 00194 * @code 00195 * // Assuming we have a GPS object previously created... 00196 * GPS gps(NC, p9); 00197 * 00198 * double latitude = gps.latitude(); 00199 * 00200 * @endcode 00201 * 00202 * @ingroup API 00203 * @return double Degrees 00204 */ 00205 double latitude(void); 00206 00207 //! What was the last reported longitude (in degrees) 00208 /** 00209 * Method returns a double in degrees, positive being East, negative being West. 00210 * 00211 * @code 00212 * // Assuming we have a GPS object previously created... 00213 * GPS gps(NC, p9); 00214 * 00215 * double logitude = gps.logitude(); 00216 * 00217 * @endcode 00218 * 00219 * @ingroup API 00220 * @return double Degrees 00221 */ 00222 double longitude(void); 00223 00224 //! What was the last reported altitude (in kilometers) 00225 /** 00226 * Method returns a double in kilometers. 00227 * 00228 * @code 00229 * // Assuming we have a GPS object previously created... 00230 * GPS gps(NC, p9); 00231 * 00232 * double altitude = gps.altitude(); 00233 * 00234 * @endcode 00235 * 00236 * @ingroup API 00237 * @return double Kilometers 00238 */ 00239 double altitude(void); 00240 00241 //! What was the last reported altitude/height (in kilometers) 00242 /** 00243 * @see altitude() 00244 * 00245 * @code 00246 * // Assuming we have a GPS object previously created... 00247 * GPS gps(NC, p9); 00248 * 00249 * double height = gps.height(); 00250 * 00251 * @endcode 00252 * 00253 * Note, this is identical to altitude() 00254 * @see altitude() 00255 * 00256 * @ingroup API 00257 * @return double Kilometers 00258 */ 00259 double height(void) { return altitude(); } 00260 00261 //! Get all three geodetic parameters together. 00262 /** 00263 * Pass a pointer to a GPS_Geodetic object and the current 00264 * GPS data will be copied into it. 00265 * 00266 * @code 00267 * // Assuming we have a GPS object previously created... 00268 * GPS gps(NC, p9); 00269 * 00270 * // Then get the data... 00271 * GPS_Geodetic p; 00272 * gps.geodetic(&p); 00273 * printf("Latitude = %.4f", p.lat); 00274 * printf("Longitude = %.4f", p.lon); 00275 * printf("Altitude = %.4f", p.alt); 00276 * 00277 * @endcode 00278 * 00279 * @ingroup API 00280 * @param g A GSP_Geodetic pointer to an existing GPS_Geodetic object. 00281 * @return GPS_Geodetic * The pointer passed in. 00282 */ 00283 GPS_Geodetic *geodetic(GPS_Geodetic *g); 00284 00285 //! Get all three geodetic parameters together. 00286 /** 00287 * Get all the geodetic data at once. For example:- 00288 * 00289 * @code 00290 * // Assuming we have a GPS object previously created... 00291 * GPS gps(NC, p9); 00292 * 00293 * // Then get the data... 00294 * GPS_Geodetic *p = gps.geodetic(); 00295 * printf("Latitude = %.4f", p->lat); 00296 * delete(p); // then remember to delete the object to prevent memory leaks. 00297 * 00298 * @endcode 00299 * 00300 * @ingroup API 00301 * @return GPS_Geodetic * A pointer to the data. 00302 */ 00303 GPS_Geodetic *geodetic(void) { return geodetic(NULL); } 00304 00305 //! Take a snap shot of the current time. 00306 /** 00307 * Pass a pointer to a GPS_Time object to get a copy of the current 00308 * time and date as reported by the GPS. 00309 * 00310 * @code 00311 * // Assuming we have a GPS object previously created... 00312 * GPS gps(NC, p9); 00313 * 00314 * // Then get the data... 00315 * GPS_Time t; 00316 * gps.timeNow(&t); 00317 * printf("Year = %d", t.year); 00318 * 00319 * @endcode 00320 * 00321 * @ingroup API 00322 * @param n A GPS_Time * pointer to an existing GPS_Time object. 00323 * @return GPS_Time * The pointer passed in. 00324 */ 00325 GPS_Time * timeNow(GPS_Time *n) { return theTime.timeNow(n); } 00326 00327 //! Take a snap shot of the current time. 00328 /** 00329 * Pass a pointer to a GPS_Time object to get a copy of the current 00330 * time and date as reported by the GPS. 00331 * 00332 * @code 00333 * // Assuming we have a GPS object previously created... 00334 * GPS gps(NC, p9); 00335 * 00336 * // Then get the data... 00337 * GPS_Time *t = gps.timeNow(); 00338 * printf("Year = %d", t->year); 00339 * delete(t); // Avoid memory leaks. 00340 * 00341 * @endcode 00342 * 00343 * @ingroup API 00344 * @return GPS_Time * The pointer passed in. 00345 */ 00346 GPS_Time * timeNow(void) { GPS_Time *n = new GPS_Time; return theTime.timeNow(n); } 00347 00348 //! Return the curent day. 00349 /** 00350 * @code 00351 * // Assuming we have a GPS object previously created... 00352 * GPS gps(NC, p9); 00353 * 00354 * // Then get the Julain Day Number. 00355 * double julianDayNumber = gps.julianDayNumber(); 00356 * 00357 * @endcode 00358 * 00359 * @ingroup API 00360 * @return double The Julian Date as a double. 00361 */ 00362 double julianDayNumber(void) { return theTime.julian_day_number(); } 00363 00364 //! Return the curent date/time as a Julian date 00365 /** 00366 * @code 00367 * // Assuming we have a GPS object previously created... 00368 * GPS gps(NC, p9); 00369 * 00370 * // Then get the Julian Date. 00371 * double julianDate = gps.julianDate(); 00372 * 00373 * @endcode 00374 * 00375 * @ingroup API 00376 * @return double The Julian Date as a double. 00377 */ 00378 double julianDate(void) { return theTime.julian_date(); } 00379 00380 //! Get the current sidereal degree angle. 00381 /** 00382 * @code 00383 * // Assuming we have a GPS object previously created... 00384 * GPS gps(NC, p9); 00385 * double sidereal = gps.siderealDegrees(); 00386 * 00387 * @endcode 00388 * 00389 * @ingroup API 00390 * @return double Sidereal degree angle.. 00391 */ 00392 double siderealDegrees(void) { return theTime.siderealDegrees(&theTime, longitude()); } 00393 00394 //! Get the current sidereal hour angle. 00395 /** 00396 * @code 00397 * // Assuming we have a GPS object previously created... 00398 * GPS gps(NC, p9); 00399 * double sidereal = gps.siderealHA(); 00400 * 00401 * @endcode 00402 * 00403 * @ingroup API 00404 * @return double Sidereal degree angle.. 00405 */ 00406 double siderealHA(void) { return theTime.siderealHA(&theTime, longitude()); } 00407 00408 //! Optionally, connect a 1PPS single to an Mbed pin. 00409 /** 00410 * Optional: If the GPS unit has a 1PPS output, use this to 00411 * connect that to our internal ISR. Using the 1PPS increases 00412 * the GPS_Time time accuracy from +/-0.25s to +/-0.001s 00413 * 00414 * @code 00415 * // Assuming we have a GPS object previously created... 00416 * GPS gps(NC, p9); 00417 * 00418 * gps.ppsAttach(p29); // default to GPS::ppsRise, rising edge. 00419 * 00420 * // Or... 00421 * gps.ppsAttach(p29, GPS::ppsRise); // The default. 00422 * 00423 * // Or... 00424 * gps.ppsAttach(p29, GPS::ppsFall); // If a falling edge. 00425 * 00426 * @endcode 00427 * 00428 * <b>Note</b>, before using this function you should attach an actual 00429 * callback function using attach_pps() 00430 * 00431 * @see attach_pps() 00432 * 00433 * @ingroup API 00434 * @param irq A PinName to attach 00435 * @param type The type of edge, MAX7456::ppsRise OR MAX7456::ppsFall 00436 */ 00437 void ppsAttach(PinName irq, ppsEdgeType type = ppsRise ); 00438 00439 //! Remove any 1PPS signal previously attached. 00440 void ppsUnattach(void); 00441 00442 //! GPS serial receive interrupt handler. 00443 void rx_irq(void); 00444 00445 //! GPS pps interrupt handler. 00446 void pps_irq(void); 00447 00448 //! A pointer to the UART peripheral base address being used. 00449 void *_base; 00450 00451 //! The RX serial buffer. 00452 char buffer[2][GPS_BUFFER_LEN]; 00453 00454 //! The current "active" buffer, i.e. the buffer the ISR is writing to. 00455 int active_buffer; 00456 00457 //! The active buffer "in" pointer. 00458 int rx_buffer_in; 00459 00460 //! Boolean flag set when the "passive" buffer is full and needs processing. 00461 bool process_required; 00462 00463 //! 10ms Ticker callback. 00464 void ticktock(void); 00465 00466 //! Attach a user object/method callback function to the PPS signal 00467 /** 00468 * Attach a user callback object/method to call when the 1PPS signal activates. 00469 * 00470 * @code 00471 * class FOO { 00472 * public: 00473 * void myCallback(void); 00474 * }; 00475 * 00476 * GPS gps(NC, p9); 00477 * Foo foo; 00478 * 00479 * gps.attach_pps(foo, &FOO::myCallback); 00480 * 00481 * @endcode 00482 * 00483 * @ingroup API 00484 * @param tptr pointer to the object to call the member function on 00485 * @param mptr pointer to the member function to be called 00486 */ 00487 template<typename T> 00488 void attach_pps(T* tptr, void (T::*mptr)(void)) { cb_pps.attach(tptr, mptr); } 00489 00490 //! Attach a user callback function to the PPS signal 00491 /** 00492 * Attach a user callback function pointer to call when the 1PPS signal activates. 00493 * 00494 * @code 00495 * void myCallback(void) { ... } 00496 * 00497 * GPS gps(NC, p9); 00498 * Foo foo; 00499 * 00500 * gps.attach_pps(&myCallback); 00501 * 00502 * @endcode 00503 * 00504 * @ingroup API 00505 * @param fptr Callback function pointer 00506 */ 00507 void attach_pps(void (*fptr)(void)) { cb_pps.attach(fptr); } 00508 00509 //! A callback object for the 1PPS user API. 00510 FunctionPointer cb_pps; 00511 00512 //! Attach a user callback function to the NMEA RMC message processed signal. 00513 /** 00514 * Attach a user callback object/method to call when an NMEA RMC packet has been processed. 00515 * 00516 * @code 00517 * class FOO { 00518 * public: 00519 * void myCallback(void); 00520 * }; 00521 * 00522 * GPS gps(NC, p9); 00523 * Foo foo; 00524 * 00525 * gps.attach_rmc(foo, &FOO::myCallback); 00526 * 00527 * @endcode 00528 * 00529 * @ingroup API 00530 * @param tptr pointer to the object to call the member function on 00531 * @param mptr pointer to the member function to be called 00532 */ 00533 template<typename T> 00534 void attach_rmc(T* tptr, void (T::*mptr)(void)) { cb_rmc.attach(tptr, mptr); } 00535 00536 //! Attach a user callback function to the NMEA RMC message processed signal. 00537 /** 00538 * Attach a user callback function pointer to call when an NMEA RMC packet has been processed. 00539 * 00540 * @code 00541 * void myCallback(void) { ... } 00542 * 00543 * GPS gps(NC, p9); 00544 * Foo foo; 00545 * 00546 * gps.attach_rmc(&myCallback); 00547 * 00548 * @endcode 00549 * 00550 * @ingroup API 00551 * @param fptr Callback function pointer. 00552 */ 00553 void attach_rmc(void (*fptr)(void)) { cb_rmc.attach(fptr); } 00554 00555 //! A callback object for the NMEA RMS message processed signal user API. 00556 FunctionPointer cb_rmc; 00557 00558 //! Attach a user callback function to the NMEA GGA message processed signal. 00559 /** 00560 * Attach a user callback object/method to call when an NMEA GGA packet has been processed. 00561 * 00562 * @code 00563 * class FOO { 00564 * public: 00565 * void myCallback(void); 00566 * }; 00567 * 00568 * GPS gps(NC, p9); 00569 * Foo foo; 00570 * 00571 * gps.attach_gga(foo, &FOO::myCallback); 00572 * 00573 * @endcode 00574 * 00575 * @ingroup API 00576 * @param tptr pointer to the object to call the member function on 00577 * @param mptr pointer to the member function to be called 00578 */ 00579 template<typename T> 00580 void attach_gga(T* tptr, void (T::*mptr)(void)) { cb_gga.attach(tptr, mptr); } 00581 00582 //! Attach a user callback function to the NMEA GGA message processed signal. 00583 /** 00584 * Attach a user callback function pointer to call when an NMEA GGA packet has been processed. 00585 * 00586 * @code 00587 * void myCallback(void) { ... } 00588 * 00589 * GPS gps(NC, p9); 00590 * Foo foo; 00591 * 00592 * gps.attach_gga(&myCallback); 00593 * 00594 * @endcode 00595 * 00596 * @ingroup API 00597 * @param fptr Callback function pointer. 00598 */ 00599 void attach_gga(void (*fptr)(void)) { cb_gga.attach(fptr); } 00600 00601 //! A callback object for the NMEA GGA message processed signal user API. 00602 FunctionPointer cb_gga; 00603 00604 //! Set the baud rate the GPS module is using. 00605 /** 00606 * Set the baud rate of the serial port 00607 * 00608 * @see http://mbed.org/projects/libraries/api/mbed/trunk/Serial#Serial.baud 00609 * 00610 * @ingroup API 00611 * @param baudrate The baudrate to set. 00612 */ 00613 void baud(int baudrate) { Serial::baud(baudrate); } 00614 00615 //! Set the serial port format the GPS module is using. 00616 /** 00617 * Set the transmission format used by the Serial port 00618 * 00619 * @see http://mbed.org/projects/libraries/api/mbed/trunk/Serial#Serial.format 00620 * 00621 * @ingroup API 00622 * @param bits - The number of bits in a word (5-8; default = 8) 00623 * @param parity - The parity used (GPS::None, GPS::Odd, GPS::Even, GPS::Forced1, GPS::Forced0; default = GPS::None) 00624 * @param stop_bits - The number of stop bits (1 or 2; default = 1) 00625 */ 00626 void format(int bits, Parity parity, int stop_bits) { Serial::format(bits, (Serial::Parity)parity, stop_bits); } 00627 00628 protected: 00629 00630 //! Flag set true when a GPS PPS has been attached to a pin. 00631 bool _ppsInUse; 00632 00633 //! An InterruptIn object to "trigger" on the PPS edge. 00634 InterruptIn *_pps; 00635 00636 //! A Ticker object called every 10ms. 00637 Ticker *_second100; 00638 00639 //! A GPS_Time object used to hold the last parsed time/date data. 00640 GPS_Time theTime; 00641 00642 //! A GPS_Geodetic object used to hold the last parsed positional data. 00643 GPS_Geodetic thePlace; 00644 }; 00645 00646 #endif 00647
Generated on Wed Jul 20 2022 12:15:06 by
1.7.2
