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 3:28a1b60b0f37, committed 2011-04-16
- Comitter:
- AjK
- Date:
- Sat Apr 16 09:37:33 2011 +0000
- Parent:
- 2:8aa059e7d8b1
- Child:
- 4:1e3a53f150aa
- Commit message:
- 1.13 See ChangeLog.c
Changed in this revision
--- a/ChangeLog.c Fri Apr 15 12:23:52 2011 +0000 +++ b/ChangeLog.c Sat Apr 16 09:37:33 2011 +0000 @@ -64,5 +64,11 @@ * Added VTG sentence (vectors speed and direction) See example3.cpp - + +1.13 - 16/04/2011 + + * Found that concat commas in NMEA sentences (indicating an empty field) + caused strtok() to return pointers in incorrect positions. + * Found copying geodetic and vtg data structs to temp buffers actually + didn't work properly. */
--- a/GPS.cpp Fri Apr 15 12:23:52 2011 +0000 +++ b/GPS.cpp Sat Apr 16 09:37:33 2011 +0000 @@ -24,6 +24,10 @@ GPS::GPS(PinName tx, PinName rx, const char *name) : Serial(tx, rx, name) { + _nmeaOnUart0 = false; + + _lastByte = 0; + switch(_uidx) { case 1: _base = LPC_UART1; break; case 2: _base = LPC_UART2; break; @@ -84,15 +88,15 @@ GPS_Geodetic * GPS::geodetic(GPS_Geodetic *q) { - GPS_Geodetic a, b; + GPS_Geodetic a; if (q == NULL) q = new GPS_Geodetic; do { memcpy(&a, &thePlace, sizeof(GPS_Geodetic)); - memcpy(&b, &thePlace, sizeof(GPS_Geodetic)); + memcpy(q, &thePlace, sizeof(GPS_Geodetic)); } - while (memcmp(&a, &b, sizeof(GPS_Geodetic)) != 0); + while (memcmp(&a, q, sizeof(GPS_Geodetic)) != 0); return q; } @@ -100,15 +104,15 @@ GPS_VTG * GPS::vtg(GPS_VTG *q) { - GPS_VTG a, b; + GPS_VTG a; if (q == NULL) q = new GPS_VTG; do { memcpy(&a, &theVTG, sizeof(GPS_VTG)); - memcpy(&b, &theVTG, sizeof(GPS_VTG)); + memcpy(q, &theVTG, sizeof(GPS_VTG)); } - while (memcmp(&a, &b, sizeof(GPS_VTG)) != 0); + while (memcmp(&a, q, sizeof(GPS_VTG)) != 0); return q; } @@ -156,15 +160,34 @@ if (_base) { 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); + c = (char)(*((char *)_base + GPS_RBR) & 0xFF); + + // strtok workaround. + // Found that ,, together (which some NMEA sentences + // contain for a null/empty field) confuses strtok() + // function. Solution:- Push a "zero" into the string + // for missing/empty fields. + if (c == ',' && _lastByte == ',') { + buffer[active_buffer][rx_buffer_in] = '0'; + if (++rx_buffer_in >= GPS_BUFFER_LEN) rx_buffer_in = 0; + } + + // Debugging/dumping data. + if (_nmeaOnUart0) LPC_UART0->RBR = c; + + // Put the byte into the string. + buffer[active_buffer][rx_buffer_in] = c; + if (++rx_buffer_in >= GPS_BUFFER_LEN) rx_buffer_in = 0; + + // Save for next time an irq occurs. See strtok() above. + _lastByte = c; + + // If end of NMEA sentence flag for processing. if (c == '\n') { active_buffer = active_buffer == 0 ? 1 : 0; process_required = true; rx_buffer_in = 0; - } + } } } }
--- a/GPS.h Fri Apr 15 12:23:52 2011 +0000 +++ b/GPS.h Sat Apr 16 09:37:33 2011 +0000 @@ -696,6 +696,7 @@ //! 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 @@ -707,7 +708,7 @@ */ void baud(int baudrate) { Serial::baud(baudrate); } - //! Set the serial port format the GPS module is using. + //! Set the serial port format the GPS module is using. /** * Set the transmission format used by the Serial port * @@ -720,6 +721,24 @@ */ void format(int bits, Parity parity, int stop_bits) { Serial::format(bits, (Serial::Parity)parity, stop_bits); } + //! Send incoming GPS bytes to Uart0 + /** + * Send incoming GPS bytes to Uart0 + * + * This can be useful for printing out the bytes from the GPS onto + * a the common debug port Uart0. Note, Uart0 should have been setup + * and initialised before switching this on. Also, realistically, + * you should ensure Uart0 has a higher baud rate than that being + * used by the GPS. Sending of bytes to Uart0 is "raw" and should + * only be used to initially gather data and should NOT be used as + * part of the application design. If you need to forward on the + * data you should come up with a proper strategy. + * + * @ingroup API + * @param b - True to send to Uart0, false otherwise + */ + void NmeaOnUart0(bool b) { _nmeaOnUart0 = b; } + protected: //! Flag set true when a GPS PPS has been attached to a pin. @@ -738,7 +757,13 @@ GPS_Geodetic thePlace; //! A GPS_VTG object used to hold vector data. - GPS_VTG theVTG; + GPS_VTG theVTG; + + //! Used to record the previous byte received. + char _lastByte; + + //! Used for debugging. + bool _nmeaOnUart0; }; #endif
--- a/GPS_VTG.cpp Fri Apr 15 12:23:52 2011 +0000 +++ b/GPS_VTG.cpp Sat Apr 16 09:37:33 2011 +0000 @@ -21,6 +21,7 @@ */ #include "GPS_VTG.h" +#include <math.h> GPS_VTG::GPS_VTG() { @@ -35,10 +36,11 @@ { if (n == NULL) n = new GPS_VTG; - do { - memcpy(n, this, sizeof(GPS_VTG)); - } - while (memcmp(n, this, sizeof(GPS_VTG))); + n->_velocity_knots = _velocity_knots; + n->_velocity_kph = _velocity_kph; + n->_track_true = _track_true; + n->_track_mag = _track_mag; + return n; } @@ -64,9 +66,9 @@ token_counter++; } + if (trk_t) { _track_true = atof(trk_t); } + if (trk_m) { _track_mag = atof(trk_m); } 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); } + if (vel_kph) { _velocity_kph = atof(vel_kph); } }
--- a/GPS_VTG.h Fri Apr 15 12:23:52 2011 +0000 +++ b/GPS_VTG.h Sat Apr 16 09:37:33 2011 +0000 @@ -24,6 +24,7 @@ #define GPS_VTG_H #include "mbed.h" +#include "iomacros.h" /** GPS_Time definition. */
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/info.h Sat Apr 16 09:37:33 2011 +0000 @@ -0,0 +1,13 @@ +/* + +Typical NMEA sentences from my GPS module. + +$GPGGA,075851.891,5611.5305,N,00302.0369,W,0,00,4.8,44.0,M,52.0,M,,0000*77 +$GPGSA,A,1,,,,,,,,,,,,,4.8,4.8,0.7*37 +$GPGSV,3,1,12,20,82,116,,01,79,246,,32,54,077,,17,48,254,*70 +$GPGSV,3,2,12,23,46,168,,24,40,128,,04,25,295,,11,24,143,*73 +$GPGSV,3,3,12,31,22,065,,13,15,190,,12,11,343,,25,00,019,*7D +$GPRMC,075851.891,V,5611.5305,N,00302.0369,W,002.2,252.9,160411,,,N*68 +$GPVTG,252.9,T,,M,002.2,N,004.1,K,N*0B + +*/ \ No newline at end of file