Code for autonomous ground vehicle, Data Bus, 3rd place winner in 2012 Sparkfun AVC.

Dependencies:   Watchdog mbed Schedule SimpleFilter LSM303DLM PinDetect DebounceIn Servo

Committer:
shimniok
Date:
Wed Jun 20 14:57:48 2012 +0000
Revision:
0:826c6171fc1b
Updated documentation

Who changed what in which revision?

UserRevisionLine numberNew contents of line
shimniok 0:826c6171fc1b 1 /*
shimniok 0:826c6171fc1b 2 TinyGPS - a small GPS library for Arduino providing basic NMEA parsing
shimniok 0:826c6171fc1b 3 Copyright (C) 2008-9 Mikal Hart
shimniok 0:826c6171fc1b 4 All rights reserved.
shimniok 0:826c6171fc1b 5
shimniok 0:826c6171fc1b 6 This library is free software; you can redistribute it and/or
shimniok 0:826c6171fc1b 7 modify it under the terms of the GNU Lesser General Public
shimniok 0:826c6171fc1b 8 License as published by the Free Software Foundation; either
shimniok 0:826c6171fc1b 9 version 2.1 of the License, or (at your option) any later version.
shimniok 0:826c6171fc1b 10
shimniok 0:826c6171fc1b 11 This library is distributed in the hope that it will be useful,
shimniok 0:826c6171fc1b 12 but WITHOUT ANY WARRANTY; without even the implied warranty of
shimniok 0:826c6171fc1b 13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
shimniok 0:826c6171fc1b 14 Lesser General Public License for more details.
shimniok 0:826c6171fc1b 15
shimniok 0:826c6171fc1b 16 You should have received a copy of the GNU Lesser General Public
shimniok 0:826c6171fc1b 17 License along with this library; if not, write to the Free Software
shimniok 0:826c6171fc1b 18 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
shimniok 0:826c6171fc1b 19
shimniok 0:826c6171fc1b 20 Ported to mbed by Michael Shimniok
shimniok 0:826c6171fc1b 21 */
shimniok 0:826c6171fc1b 22
shimniok 0:826c6171fc1b 23 #include "mbed.h"
shimniok 0:826c6171fc1b 24 #include "types.h"
shimniok 0:826c6171fc1b 25
shimniok 0:826c6171fc1b 26 #ifndef TinyGPS_h
shimniok 0:826c6171fc1b 27 #define TinyGPS_h
shimniok 0:826c6171fc1b 28
shimniok 0:826c6171fc1b 29 #define _GPS_VERSION 9 // software version of this library
shimniok 0:826c6171fc1b 30 #define _GPS_MPH_PER_KNOT 1.15077945
shimniok 0:826c6171fc1b 31 #define _GPS_MPS_PER_KNOT 0.51444444
shimniok 0:826c6171fc1b 32 #define _GPS_KMPH_PER_KNOT 1.852
shimniok 0:826c6171fc1b 33 #define _GPS_MILES_PER_METER 0.00062137112
shimniok 0:826c6171fc1b 34 #define _GPS_KM_PER_METER 0.001
shimniok 0:826c6171fc1b 35 //#define _GPS_NO_STATS
shimniok 0:826c6171fc1b 36
shimniok 0:826c6171fc1b 37 /** TinyGPS - a small GPS library for Arduino providing basic NMEA parsing Copyright (C) 2008-9 Mikal Hart
shimniok 0:826c6171fc1b 38 * All rights reserved. Modified by Michael Shimniok
shimniok 0:826c6171fc1b 39 */
shimniok 0:826c6171fc1b 40
shimniok 0:826c6171fc1b 41 class TinyGPS
shimniok 0:826c6171fc1b 42 {
shimniok 0:826c6171fc1b 43 public:
shimniok 0:826c6171fc1b 44
shimniok 0:826c6171fc1b 45 /** Create a new GPS parsing object for parsing NMEA sentences
shimniok 0:826c6171fc1b 46 */
shimniok 0:826c6171fc1b 47 TinyGPS();
shimniok 0:826c6171fc1b 48
shimniok 0:826c6171fc1b 49 /** Parse a single character received from GPS
shimniok 0:826c6171fc1b 50 *
shimniok 0:826c6171fc1b 51 * @param c is the character received from the GPS
shimniok 0:826c6171fc1b 52 * @returns true if processing ok
shimniok 0:826c6171fc1b 53 */
shimniok 0:826c6171fc1b 54 bool encode(char c);
shimniok 0:826c6171fc1b 55
shimniok 0:826c6171fc1b 56 /** Shorthand operator for encode()
shimniok 0:826c6171fc1b 57 */
shimniok 0:826c6171fc1b 58 TinyGPS &operator << (char c) {encode(c); return *this;}
shimniok 0:826c6171fc1b 59
shimniok 0:826c6171fc1b 60 /** Return lat/long in hundred thousandths of a degree and age of fix in milliseconds
shimniok 0:826c6171fc1b 61 * @returns latitude is the latitude of the most recent fix that was parsed
shimniok 0:826c6171fc1b 62 * @returns longitude is the longitude of the most recent fix that was parsed
shimniok 0:826c6171fc1b 63 * @returns fix_age is the age of the fix (if available from the NMEA sentences being parsed)
shimniok 0:826c6171fc1b 64 */
shimniok 0:826c6171fc1b 65 inline void get_position(long *latitude, long *longitude, unsigned long *fix_age = 0)
shimniok 0:826c6171fc1b 66 {
shimniok 0:826c6171fc1b 67 if (latitude) *latitude = _latitude;
shimniok 0:826c6171fc1b 68 if (longitude) *longitude = _longitude;
shimniok 0:826c6171fc1b 69 if (fix_age) *fix_age = _last_position_fix == GPS_INVALID_FIX_TIME ?
shimniok 0:826c6171fc1b 70 GPS_INVALID_AGE : millis() - _last_position_fix;
shimniok 0:826c6171fc1b 71 }
shimniok 0:826c6171fc1b 72
shimniok 0:826c6171fc1b 73 /** Return the date and time from the parsed NMEA sentences
shimniok 0:826c6171fc1b 74 *
shimniok 0:826c6171fc1b 75 * @returns date as an integer value
shimniok 0:826c6171fc1b 76 * @returns time as an integer value
shimniok 0:826c6171fc1b 77 * @returns fix_age in milliseconds if available
shimniok 0:826c6171fc1b 78 */
shimniok 0:826c6171fc1b 79 inline void get_datetime(unsigned long *date, unsigned long *time, unsigned long *fix_age = 0)
shimniok 0:826c6171fc1b 80 {
shimniok 0:826c6171fc1b 81 if (date) *date = _date;
shimniok 0:826c6171fc1b 82 if (time) *time = _time;
shimniok 0:826c6171fc1b 83 if (fix_age) *fix_age = _last_time_fix == GPS_INVALID_FIX_TIME ?
shimniok 0:826c6171fc1b 84 GPS_INVALID_AGE : millis() - _last_time_fix;
shimniok 0:826c6171fc1b 85 }
shimniok 0:826c6171fc1b 86
shimniok 0:826c6171fc1b 87 /** signed altitude in centimeters (from GPGGA sentence)
shimniok 0:826c6171fc1b 88 * @returns altitude in centimeters, integer
shimniok 0:826c6171fc1b 89 */
shimniok 0:826c6171fc1b 90 inline long altitude() { return _altitude; }
shimniok 0:826c6171fc1b 91
shimniok 0:826c6171fc1b 92 /** course in last full GPRMC sentence in 100th of a degree
shimniok 0:826c6171fc1b 93 * @returns course as an integer, 100ths of a degree
shimniok 0:826c6171fc1b 94 */
shimniok 0:826c6171fc1b 95 inline unsigned long course() { return _course; }
shimniok 0:826c6171fc1b 96
shimniok 0:826c6171fc1b 97 /** speed in last full GPRMC sentence in 100ths of a knot
shimniok 0:826c6171fc1b 98 * @returns speed in 100ths of a knot
shimniok 0:826c6171fc1b 99 */
shimniok 0:826c6171fc1b 100 unsigned long speed() { return _speed; }
shimniok 0:826c6171fc1b 101
shimniok 0:826c6171fc1b 102 /* horizontal dilution of position in last full GPGGA sentence in 100ths
shimniok 0:826c6171fc1b 103 * @returns hdop in 100ths
shimniok 0:826c6171fc1b 104 */
shimniok 0:826c6171fc1b 105 unsigned long hdop() { return _hdop; }
shimniok 0:826c6171fc1b 106
shimniok 0:826c6171fc1b 107 /** number of satellites tracked in last full GPGGA sentence
shimniok 0:826c6171fc1b 108 * @returns number of satellites tracked
shimniok 0:826c6171fc1b 109 */
shimniok 0:826c6171fc1b 110 unsigned long sat_count() { return _sat_count; }
shimniok 0:826c6171fc1b 111
shimniok 0:826c6171fc1b 112 #ifndef _GPS_NO_STATS
shimniok 0:826c6171fc1b 113 void stats(unsigned long *chars, unsigned short *good_sentences, unsigned short *failed_cs);
shimniok 0:826c6171fc1b 114 #endif
shimniok 0:826c6171fc1b 115
shimniok 0:826c6171fc1b 116 /** returns position as double precision
shimniok 0:826c6171fc1b 117 *
shimniok 0:826c6171fc1b 118 * @returns latitude as double precision
shimniok 0:826c6171fc1b 119 * @returns longitude as double precision
shimniok 0:826c6171fc1b 120 * @returns fix age in milliseconds if available
shimniok 0:826c6171fc1b 121 */
shimniok 0:826c6171fc1b 122 inline void f_get_position(double *latitude, double *longitude, unsigned long *fix_age = 0)
shimniok 0:826c6171fc1b 123 {
shimniok 0:826c6171fc1b 124 long lat, lon;
shimniok 0:826c6171fc1b 125 get_position(&lat, &lon, fix_age);
shimniok 0:826c6171fc1b 126 // mes 04/27/12 increased fractional precision to 7 digits, was 5
shimniok 0:826c6171fc1b 127 *latitude = lat / 10000000.0;
shimniok 0:826c6171fc1b 128 *longitude = lon / 10000000.0;
shimniok 0:826c6171fc1b 129 }
shimniok 0:826c6171fc1b 130
shimniok 0:826c6171fc1b 131 /** Convert date and time of last parsed sentence to integers
shimniok 0:826c6171fc1b 132 *
shimniok 0:826c6171fc1b 133 * @returns year
shimniok 0:826c6171fc1b 134 * @returns month
shimniok 0:826c6171fc1b 135 * @returns day of month
shimniok 0:826c6171fc1b 136 * @returns hour
shimniok 0:826c6171fc1b 137 * @returns minute
shimniok 0:826c6171fc1b 138 * @returns second
shimniok 0:826c6171fc1b 139 * @returns hundreths
shimniok 0:826c6171fc1b 140 * @returns fix_age in milliseconds if available
shimniok 0:826c6171fc1b 141 */
shimniok 0:826c6171fc1b 142 inline void crack_datetime(int *year, byte *month, byte *day,
shimniok 0:826c6171fc1b 143 byte *hour, byte *minute, byte *second, byte *hundredths = 0, unsigned long *fix_age = 0)
shimniok 0:826c6171fc1b 144 {
shimniok 0:826c6171fc1b 145 unsigned long date, time;
shimniok 0:826c6171fc1b 146 get_datetime(&date, &time, fix_age);
shimniok 0:826c6171fc1b 147 if (year)
shimniok 0:826c6171fc1b 148 {
shimniok 0:826c6171fc1b 149 *year = date % 100;
shimniok 0:826c6171fc1b 150 *year += *year > 80 ? 1900 : 2000;
shimniok 0:826c6171fc1b 151 }
shimniok 0:826c6171fc1b 152 if (month) *month = (date / 100) % 100;
shimniok 0:826c6171fc1b 153 if (day) *day = date / 10000;
shimniok 0:826c6171fc1b 154 if (hour) *hour = time / 1000000;
shimniok 0:826c6171fc1b 155 if (minute) *minute = (time / 10000) % 100;
shimniok 0:826c6171fc1b 156 if (second) *second = (time / 100) % 100;
shimniok 0:826c6171fc1b 157 if (hundredths) *hundredths = time % 100;
shimniok 0:826c6171fc1b 158 }
shimniok 0:826c6171fc1b 159
shimniok 0:826c6171fc1b 160 /** returns altitude as a float
shimniok 0:826c6171fc1b 161 */
shimniok 0:826c6171fc1b 162 inline double f_altitude() { return altitude() / 100.0; }
shimniok 0:826c6171fc1b 163
shimniok 0:826c6171fc1b 164 /** returns course as a float
shimniok 0:826c6171fc1b 165 */
shimniok 0:826c6171fc1b 166 inline double f_course() { return course() / 100.0; }
shimniok 0:826c6171fc1b 167
shimniok 0:826c6171fc1b 168 /** returns speed in knots as a float
shimniok 0:826c6171fc1b 169 */
shimniok 0:826c6171fc1b 170 inline double f_speed_knots() { return speed() / 100.0; }
shimniok 0:826c6171fc1b 171
shimniok 0:826c6171fc1b 172 /** returns speed in mph as a float
shimniok 0:826c6171fc1b 173 */
shimniok 0:826c6171fc1b 174 inline double f_speed_mph() { return _GPS_MPH_PER_KNOT * f_speed_knots(); }
shimniok 0:826c6171fc1b 175
shimniok 0:826c6171fc1b 176 /** returns speed in meters per second as a float
shimniok 0:826c6171fc1b 177 */
shimniok 0:826c6171fc1b 178 inline double f_speed_mps() { return _GPS_MPS_PER_KNOT * f_speed_knots(); }
shimniok 0:826c6171fc1b 179
shimniok 0:826c6171fc1b 180 /** returns speed in km per hour as a float
shimniok 0:826c6171fc1b 181 */
shimniok 0:826c6171fc1b 182 inline double f_speed_kmph() { return _GPS_KMPH_PER_KNOT * f_speed_knots(); }
shimniok 0:826c6171fc1b 183
shimniok 0:826c6171fc1b 184 /** returns hdop as a float
shimniok 0:826c6171fc1b 185 */
shimniok 0:826c6171fc1b 186 inline double f_hdop() { return hdop() / 100.0; }
shimniok 0:826c6171fc1b 187
shimniok 0:826c6171fc1b 188 /** @returns library version
shimniok 0:826c6171fc1b 189 */
shimniok 0:826c6171fc1b 190 static int library_version() { return _GPS_VERSION; }
shimniok 0:826c6171fc1b 191
shimniok 0:826c6171fc1b 192 /** determine if RMC sentence parsed since last reset_ready()
shimniok 0:826c6171fc1b 193 */
shimniok 0:826c6171fc1b 194 inline bool rmc_ready() { return _rmc_ready; }
shimniok 0:826c6171fc1b 195
shimniok 0:826c6171fc1b 196 /** determine if GGA sentence parsed since last reset_ready()
shimniok 0:826c6171fc1b 197 */
shimniok 0:826c6171fc1b 198 inline bool gga_ready() { return _gga_ready; }
shimniok 0:826c6171fc1b 199
shimniok 0:826c6171fc1b 200 /** determine if GSV sentence parsed since last reset_ready()
shimniok 0:826c6171fc1b 201 */
shimniok 0:826c6171fc1b 202 inline bool gsv_ready() { return _gsv_ready; }
shimniok 0:826c6171fc1b 203
shimniok 0:826c6171fc1b 204 /** Reset the ready flags for all the parsed sentences
shimniok 0:826c6171fc1b 205 */
shimniok 0:826c6171fc1b 206 inline void reset_ready() { _gsv_ready = _rmc_ready = _gga_ready = false; }
shimniok 0:826c6171fc1b 207
shimniok 0:826c6171fc1b 208 enum {GPS_INVALID_AGE = 0xFFFFFFFF, GPS_INVALID_ANGLE = 999999999, GPS_INVALID_ALTITUDE = 999999999, GPS_INVALID_DATE = 0,
shimniok 0:826c6171fc1b 209 GPS_INVALID_TIME = 0xFFFFFFFF, GPS_INVALID_SPEED = 999999999, GPS_INVALID_FIX_TIME = 0xFFFFFFFF};
shimniok 0:826c6171fc1b 210
shimniok 0:826c6171fc1b 211 private:
shimniok 0:826c6171fc1b 212 enum {_GPS_SENTENCE_GPGGA, _GPS_SENTENCE_GPRMC, _GPS_SENTENCE_GPGSV, _GPS_SENTENCE_OTHER};
shimniok 0:826c6171fc1b 213
shimniok 0:826c6171fc1b 214 // properties
shimniok 0:826c6171fc1b 215 unsigned long _time, _new_time;
shimniok 0:826c6171fc1b 216 unsigned long _date, _new_date;
shimniok 0:826c6171fc1b 217 long _latitude, _new_latitude;
shimniok 0:826c6171fc1b 218 long _longitude, _new_longitude;
shimniok 0:826c6171fc1b 219 long _altitude, _new_altitude;
shimniok 0:826c6171fc1b 220 unsigned long _speed, _new_speed;
shimniok 0:826c6171fc1b 221 unsigned long _course, _new_course;
shimniok 0:826c6171fc1b 222 unsigned long _hdop, _new_hdop;
shimniok 0:826c6171fc1b 223 unsigned int _sat_count, _new_sat_count;
shimniok 0:826c6171fc1b 224 unsigned long _last_time_fix, _new_time_fix;
shimniok 0:826c6171fc1b 225 unsigned long _last_position_fix, _new_position_fix;
shimniok 0:826c6171fc1b 226
shimniok 0:826c6171fc1b 227 // parsing state variables
shimniok 0:826c6171fc1b 228 byte _parity;
shimniok 0:826c6171fc1b 229 bool _is_checksum_term;
shimniok 0:826c6171fc1b 230 char _term[15];
shimniok 0:826c6171fc1b 231 byte _sentence_type;
shimniok 0:826c6171fc1b 232 byte _term_number;
shimniok 0:826c6171fc1b 233 byte _term_offset;
shimniok 0:826c6171fc1b 234 bool _gps_data_good;
shimniok 0:826c6171fc1b 235 bool _rmc_ready;
shimniok 0:826c6171fc1b 236 bool _gga_ready;
shimniok 0:826c6171fc1b 237 bool _gsv_ready;
shimniok 0:826c6171fc1b 238
shimniok 0:826c6171fc1b 239 #ifndef _GPS_NO_STATS
shimniok 0:826c6171fc1b 240 // statistics
shimniok 0:826c6171fc1b 241 unsigned long _encoded_characters;
shimniok 0:826c6171fc1b 242 unsigned short _good_sentences;
shimniok 0:826c6171fc1b 243 unsigned short _failed_checksum;
shimniok 0:826c6171fc1b 244 unsigned short _passed_checksum;
shimniok 0:826c6171fc1b 245 #endif
shimniok 0:826c6171fc1b 246
shimniok 0:826c6171fc1b 247 // internal utilities
shimniok 0:826c6171fc1b 248 int from_hex(char a);
shimniok 0:826c6171fc1b 249 int parse_int();
shimniok 0:826c6171fc1b 250 unsigned long parse_decimal();
shimniok 0:826c6171fc1b 251 unsigned long parse_degrees();
shimniok 0:826c6171fc1b 252 bool term_complete();
shimniok 0:826c6171fc1b 253 bool gpsisdigit(char c) { return c >= '0' && c <= '9'; }
shimniok 0:826c6171fc1b 254 long gpsatol(const char *str);
shimniok 0:826c6171fc1b 255 int gpsstrcmp(const char *str1, const char *str2);
shimniok 0:826c6171fc1b 256 };
shimniok 0:826c6171fc1b 257
shimniok 0:826c6171fc1b 258 // Arduino 0012 workaround
shimniok 0:826c6171fc1b 259 #undef int
shimniok 0:826c6171fc1b 260 #undef char
shimniok 0:826c6171fc1b 261 #undef long
shimniok 0:826c6171fc1b 262 #undef byte
shimniok 0:826c6171fc1b 263 #undef double
shimniok 0:826c6171fc1b 264 #undef abs
shimniok 0:826c6171fc1b 265 #undef round
shimniok 0:826c6171fc1b 266
shimniok 0:826c6171fc1b 267 #endif