Allows for a GPS module to be connected to a serial port and exposes an easy to use API to get the GPS data. New feature, added Mbed/LPC17xx RTC synchronisation
Dependents: SatGPS AntiTheftGPS FLIGHT_CONTROL_AND_COMMUNICATIONS_SYSTEM GPS-Lora ... more
Revision 2:8aa059e7d8b1, committed 2011-04-15
- Comitter:
- AjK
- Date:
- Fri Apr 15 12:23:52 2011 +0000
- Parent:
- 1:6aec92e77ad2
- Child:
- 3:28a1b60b0f37
- Commit message:
- 1.12 See ChangeLog.c
Changed in this revision
--- a/ChangeLog.c Sat Nov 20 21:02:06 2010 +0000 +++ b/ChangeLog.c Fri Apr 15 12:23:52 2011 +0000 @@ -59,5 +59,10 @@ 1.11 - 17/11/2010 * Mbed's systems don't like @mainpage, rolling back - + +1.12 - 15/04/2011 + + * Added VTG sentence (vectors speed and direction) + See example3.cpp + */
--- a/GPS.cpp Sat Nov 20 21:02:06 2010 +0000 +++ b/GPS.cpp Fri Apr 15 12:23:52 2011 +0000 @@ -97,6 +97,22 @@ return q; } +GPS_VTG * +GPS::vtg(GPS_VTG *q) +{ + GPS_VTG a, b; + + if (q == NULL) q = new GPS_VTG; + + do { + memcpy(&a, &theVTG, sizeof(GPS_VTG)); + memcpy(&b, &theVTG, sizeof(GPS_VTG)); + } + while (memcmp(&a, &b, sizeof(GPS_VTG)) != 0); + + return q; +} + void GPS::ticktock(void) { @@ -115,6 +131,10 @@ thePlace.nmea_gga(s); cb_gga.call(); } + else if (!strncmp(s, "$GPVTG", 6)) { + theVTG.nmea_vtg(s); + cb_vtg.call(); + } process_required = false; } } @@ -126,7 +146,7 @@ theTime++; // Increment the time/date by one second. cb_pps.call(); } - + void GPS::rx_irq(void) { @@ -137,6 +157,7 @@ iir = (uint32_t)*((char *)_base + GPS_IIR); while((int)(*((char *)_base + GPS_LSR) & 0x1)) { c = (char)(*((char *)_base + GPS_RBR) & 0xFF); + // debugging LPC_UART0->RBR = c; buffer[active_buffer][rx_buffer_in++] = c; rx_buffer_in &= (GPS_BUFFER_LEN - 1); if (c == '\n') {
--- a/GPS.h Sat Nov 20 21:02:06 2010 +0000 +++ b/GPS.h Fri Apr 15 12:23:52 2011 +0000 @@ -24,6 +24,7 @@ #define GPS_H #include "mbed.h" +#include "GPS_VTG.h" #include "GPS_Time.h" #include "GPS_Geodetic.h" @@ -258,6 +259,54 @@ */ double height(void) { return altitude(); } + //! Get all vector parameters together. + /** + * Pass a pointer to a GPS_VTG object and the current + * GPS data will be copied into it. + * + * @code + * // Assuming we have a GPS object previously created... + * GPS gps(NC, p9); + * + * // Then get the data... + * GPS_VTG p; + * gps.vtg(&p); + * printf("Speed (knots) = %.4f", p.velocity_knots); + * printf("Speed (kps) = %.4f", p.velocity_kps); + * printf("Track (true) = %.4f", p.track_true); + * printf("Track (mag) = %.4f", p.track_mag); + * + * @endcode + * + * @ingroup API + * @param g A GSP_VTG pointer to an existing GPS_VTG object. + * @return GPS_VTG * The pointer passed in. + */ + GPS_VTG *vtg(GPS_VTG *g); + + //! Get all vector parameters together. + /** + * Get all the vector data at once. For example:- + * + * @code + * // Assuming we have a GPS object previously created... + * GPS gps(NC, p9); + * + * // Then get the data... + * GPS_VTG *p = gps.vtg(); + * printf("Speed (knots) = %.4f", p->velocity_knots); + * printf("Speed (kps) = %.4f", p->velocity_kps); + * printf("Track (true) = %.4f", p->track_true); + * printf("Track (mag) = %.4f", p->track_mag); + * delete(p); // then remember to delete the object to prevent memory leaks. + * + * @endcode + * + * @ingroup API + * @return GPS_Geodetic * A pointer to the data. + */ + GPS_VTG *vtg(void) { return vtg(NULL); } + //! Get all three geodetic parameters together. /** * Pass a pointer to a GPS_Geodetic object and the current @@ -601,6 +650,52 @@ //! A callback object for the NMEA GGA message processed signal user API. FunctionPointer cb_gga; + + //! Attach a user callback function to the NMEA VTG message processed signal. + /** + * Attach a user callback object/method to call when an NMEA VTG packet has been processed. + * + * @code + * class FOO { + * public: + * void myCallback(void); + * }; + * + * GPS gps(NC, p9); + * Foo foo; + * + * gps.attach_vtg(foo, &FOO::myCallback); + * + * @endcode + * + * @ingroup API + * @param tptr pointer to the object to call the member function on + * @param mptr pointer to the member function to be called + */ + template<typename T> + void attach_vtg(T* tptr, void (T::*mptr)(void)) { cb_vtg.attach(tptr, mptr); } + + //! Attach a user callback function to the NMEA VTG message processed signal. + /** + * Attach a user callback function pointer to call when an NMEA VTG packet has been processed. + * + * @code + * void myCallback(void) { ... } + * + * GPS gps(NC, p9); + * Foo foo; + * + * gps.attach_vtg(&myCallback); + * + * @endcode + * + * @ingroup API + * @param fptr Callback function pointer. + */ + void attach_vtg(void (*fptr)(void)) { cb_vtg.attach(fptr); } + + //! A callback object for the NMEA RMS message processed signal user API. + FunctionPointer cb_vtg; //! Set the baud rate the GPS module is using. /** * Set the baud rate of the serial port @@ -640,7 +735,10 @@ GPS_Time theTime; //! A GPS_Geodetic object used to hold the last parsed positional data. - GPS_Geodetic thePlace; + GPS_Geodetic thePlace; + + //! A GPS_VTG object used to hold vector data. + GPS_VTG theVTG; }; #endif
--- a/GPS_Time.cpp Sat Nov 20 21:02:06 2010 +0000 +++ b/GPS_Time.cpp Fri Apr 15 12:23:52 2011 +0000 @@ -33,6 +33,10 @@ tenths = 0; hundreths = 0; status = 'V'; + velocity = 0; + track = 0; + magvar_dir = 'W'; + magvar = 0; } GPS_Time * @@ -98,6 +102,7 @@ } } +// $GPRMC,112709.735,A,5611.5340,N,00302.0306,W,000.0,307.0,150411,,,A*70 void GPS_Time::nmea_rmc(char *s) { @@ -106,13 +111,21 @@ char *time = (char *)NULL; char *date = (char *)NULL; char *stat = (char *)NULL; - + char *vel = (char *)NULL; + char *trk = (char *)NULL; + char *magv = (char *)NULL; + char *magd = (char *)NULL; + token = strtok(s, ","); while (token) { switch (token_counter) { - case 9: date = token; break; - case 1: time = token; break; - case 2: stat = token; break; + case 9: date = token; break; + case 1: time = token; break; + case 2: stat = token; break; + case 7: vel = token; break; + case 8: trk = token; break; + case 10: magv = token; break; + case 11: magd = token; break; } token = strtok((char *)NULL, ","); token_counter++; @@ -126,7 +139,10 @@ month = (char)((date[2] - '0') * 10) + (date[3] - '0'); year = (int)((date[4] - '0') * 10) + (date[5] - '0') + 2000; status = stat[0]; - + velocity = atof(vel); + track = atof(trk); + magvar = atof(magv); + magvar_dir = magd[0]; } }
--- a/GPS_Time.h Sat Nov 20 21:02:06 2010 +0000 +++ b/GPS_Time.h Fri Apr 15 12:23:52 2011 +0000 @@ -48,6 +48,14 @@ int hundreths; //! Time status. char status; + //! The velocity (in knots) + double velocity; + //! The track (in decimal degrees true) + double track; + //! The magnetic variation direction + char magvar_dir; + //! The magnetic variation value + double magvar; GPS_Time(); void fractionalReset(void) { tenths = hundreths = 0; } @@ -56,6 +64,12 @@ GPS_Time * timeNow(GPS_Time *n); GPS_Time * timeNow(void) { return timeNow(NULL); } void nmea_rmc(char *s); + double velocity_knots(void) { return velocity; } + double velocity_kph(void) { return (velocity * 1.852); } + double velocity_mps(void) { return velocity_kph() / 3600.0; } + double velocity_mph(void) { return velocity_kph() / 0.621371192; } + double track_over_ground(void) { return track; } + double magnetic_variation(void) { return magvar_dir == 'W' ? (magvar * -1.0) : (magvar); } double julian_day_number(GPS_Time *t); double julian_date(GPS_Time *t); double julian_day_number(void) { return julian_day_number(this); }
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GPS_VTG.cpp Fri Apr 15 12:23:52 2011 +0000 @@ -0,0 +1,72 @@ +/* + Copyright (c) 2010 Andy Kirkham + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#include "GPS_VTG.h" + +GPS_VTG::GPS_VTG() +{ + _velocity_knots = 0; + _velocity_kph = 0; + _track_true = 0; + _track_mag = 0; +} + +GPS_VTG * +GPS_VTG::vtg(GPS_VTG *n) +{ + if (n == NULL) n = new GPS_VTG; + + do { + memcpy(n, this, sizeof(GPS_VTG)); + } + while (memcmp(n, this, sizeof(GPS_VTG))); + return n; +} + +void +GPS_VTG::nmea_vtg(char *s) +{ + char *token; + int token_counter = 0; + char *vel_knots = (char *)NULL; + char *vel_kph = (char *)NULL; + char *trk_t = (char *)NULL; + char *trk_m = (char *)NULL; + + token = strtok(s, ","); + while (token) { + switch (token_counter) { + case 5: vel_knots = token; break; + case 7: vel_kph = token; break; + case 1: trk_t = token; break; + case 3: trk_m = token; break; + } + token = strtok((char *)NULL, ","); + token_counter++; + } + + if (vel_knots) { _velocity_knots = atof(vel_knots); } + if (vel_kph) { _velocity_kph = atof(vel_kph); } + if (trk_t) { _track_true = atof(trk_t); } + if (trk_m) { _track_mag = atof(trk_m); } +} +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/GPS_VTG.h Fri Apr 15 12:23:52 2011 +0000 @@ -0,0 +1,54 @@ +/* + Copyright (c) 2010 Andy Kirkham + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#ifndef GPS_VTG_H +#define GPS_VTG_H + +#include "mbed.h" + +/** GPS_Time definition. + */ +class GPS_VTG { +public: + + //! The velocity (in knots) + double _velocity_knots; + //! The velocity (in kph) + double _velocity_kph; + //! The track (in decimal degrees true) + double _track_true; + //! The track (in decimal degrees magnetic) + double _track_mag; + + GPS_VTG(); + GPS_VTG * vtg(GPS_VTG *n); + void nmea_vtg(char *s); + + double velocity_knots(void) { return _velocity_knots; } + double velocity_kph(void) { return _velocity_kph; } + double track_true(void) { return _track_true; } + double track_mag(void) { return _track_mag; } + +}; + +#endif +
--- a/example1.cpp Sat Nov 20 21:02:06 2010 +0000 +++ b/example1.cpp Fri Apr 15 12:23:52 2011 +0000 @@ -1,4 +1,4 @@ -#ifdef COMPILE_EXAMPLE_CODE_MODGPS +#ifdef COMPILE_EXAMPLE1_CODE_MODGPS #include "mbed.h" #include "GPS.h"
--- a/example2.cpp Sat Nov 20 21:02:06 2010 +0000 +++ b/example2.cpp Fri Apr 15 12:23:52 2011 +0000 @@ -1,4 +1,4 @@ -#ifdef COMPILE_EXAMPLE_CODE_MODGPS +#ifdef COMPILE_EXAMPLE2_CODE_MODGPS #include "mbed.h" #include "GPS.h"
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/example3.cpp Fri Apr 15 12:23:52 2011 +0000 @@ -0,0 +1,113 @@ +#ifdef COMPILE_EXAMPLE3_CODE_MODGPS + +// See forum post http://mbed.org/forum/mbed/topic/2151/ + +#include "mbed.h" +#include "GPS.h" + +Serial pc(USBTX, USBRX); +DigitalOut led1(LED1); + +// SET THIS. +// Create an instance of the GPS object. You will need to +// set p25 to whichever Serial RX pin you have connected +// your GPS module to. +GPS gps(NC, GPSRX); + +// 0.05 second flash of LED2 +DigitalOut led2(LED2); +Timeout t2; +void t2out(void) { led2 = 0; } +void blip2(void) { led2 = 1; t2.attach(&t2out, 0.05); } + +// 0.05 second flash of LED3 +DigitalOut led3(LED3); +Timeout t3; +void t3out(void) { led3 = 0; } +void blip3(void) { led3 = 1; t3.attach(&t3out, 0.05); } + +// 0.05 second flash of LED4 +DigitalOut led4(LED4); + +Timeout t4; +void t4out(void) { led4 = 0; } +void blip4(void) { led4 = 1; t4.attach(&t4out, 0.05); } + +int main() { + GPS_Time q1; + GPS_VTG v1; + + // SET THIS. + // Ensure you set the baud rate to match your serial + // communications to your PC/Max/Linux host so you + // can read the messages. + pc.baud(PCBAUD); + + // SET THIS. + // Most GPS modules use 9600,8,n,1 so that's what + // we default to here. Ensure your GPS module matches + // this, otherwise set it to match. + gps.baud(GPSBUAD); + gps.format(8, GPS::None, 1); + + // OPTIONAL + // If you GPS has a 1 pulse per second output you can + // connect it to an Mbed pin. Here you specify what pin + // and on what "edge" teh signal is active. If your GPS + // module has a rising edge at the one second point then + // use GPS::ppsRise + #ifdef PPSPIN + gps.ppsAttach(PPSPIN, GPS::ppsFall); + #endif + + // Sample of a callback to a function when a NMEA GGA message is recieved. + // For this example, we flash LED2 for 0.05 second. + gps.attach_gga(&blip2); + + // Sample of a callback to a function when a NMEA RMC message is recieved. + // For this example, we flash LED3 for 0.05 second. + gps.attach_rmc(&blip3); + + // Sample of a callback to a function when a NMEA VTG message is recieved. + // For this example, we flash LED4 for 0.05 second. + gps.attach_vtg(&blip4); + + while(1) { + // Every 3 seconds, flip LED1 and print the basic GPS info. + wait(3); + led1 = 1; + + // Demonstrate how to find out the GPS location co-ords. + pc.printf("Method 1. Lat = %.4f ", gps.latitude()); + pc.printf("Lon = %.4f ", gps.longitude()); + pc.printf("Alt = %.4f ", gps.altitude()); + + // Grab a snapshot of the current time. + gps.timeNow(&q1); + pc.printf("%c %02d:%02d:%02d %02d/%02d/%04d\r\n", + q1.status, q1.hour, q1.minute, q1.second, q1.day, q1.month, q1.year); + + gps.vtg(&v1); + pc.printf("Method 1. Vector data, Speed (knots):%lf, Speed(kph):%lf, Track(true):%lf, Track(mag)%lf\r\n", + v1.velocity_knots(), v1.velocity_kph(), v1.track_true(), v1.track_mag()); + + // Alternative method that does the same thing. + pc.printf("Method 2. Lat = %.4f ", gps.latitude()); + pc.printf("Lon = %.4f ", gps.longitude()); + pc.printf("Alt = %.4f ", gps.altitude()); + + GPS_Time *q2 = gps.timeNow(); + pc.printf("%c %02d:%02d:%02d %02d/%02d/%04d\r\n", + q2->status, q2->hour, q2->minute, q2->second, q2->day, q2->month, q2->year); + delete(q2); + + GPS_VTG *v2 = gps.vtg(); + pc.printf("Method 2. Vector data, Speed (knots):%lf, Speed(kph):%lf, Track(true):%lf, Track(mag):%lf\r\n\n", + v2->velocity_knots(), v2->velocity_kph(), v2->track_true(), v2->track_mag()); + delete(v2); + + led1 = 0; + } +} + +#endif