Quick & dirty port of the Adafruit library for their GPS Featherwing board. It is designed to be used with the MAX32630FTHR board.

Committer:
danjulio
Date:
Sun Jun 11 04:06:22 2017 +0000
Revision:
0:8fc18502886a
Initial commit of ported gps library for mbed

Who changed what in which revision?

UserRevisionLine numberNew contents of line
danjulio 0:8fc18502886a 1 /***********************************
danjulio 0:8fc18502886a 2 This is our GPS library
danjulio 0:8fc18502886a 3
danjulio 0:8fc18502886a 4 Adafruit invests time and resources providing this open source code,
danjulio 0:8fc18502886a 5 please support Adafruit and open-source hardware by purchasing
danjulio 0:8fc18502886a 6 products from Adafruit!
danjulio 0:8fc18502886a 7
danjulio 0:8fc18502886a 8 Written by Limor Fried/Ladyada for Adafruit Industries.
danjulio 0:8fc18502886a 9 BSD license, check license.txt for more information
danjulio 0:8fc18502886a 10 All text above must be included in any redistribution
danjulio 0:8fc18502886a 11 ****************************************/
danjulio 0:8fc18502886a 12 //
danjulio 0:8fc18502886a 13 // Ported to mbed by Dan Julio - 5/2017
danjulio 0:8fc18502886a 14
danjulio 0:8fc18502886a 15 #include <gps.h>
danjulio 0:8fc18502886a 16
danjulio 0:8fc18502886a 17 // how long are max NMEA lines to parse?
danjulio 0:8fc18502886a 18 #define MAXLINELENGTH 120
danjulio 0:8fc18502886a 19
danjulio 0:8fc18502886a 20 // we double buffer: read one line in and leave one for the main program
danjulio 0:8fc18502886a 21 volatile char line1[MAXLINELENGTH];
danjulio 0:8fc18502886a 22 volatile char line2[MAXLINELENGTH];
danjulio 0:8fc18502886a 23 // our index into filling the current line
danjulio 0:8fc18502886a 24 volatile uint8_t lineidx=0;
danjulio 0:8fc18502886a 25 // pointers to the double buffers
danjulio 0:8fc18502886a 26 volatile char *currentline;
danjulio 0:8fc18502886a 27 volatile char *lastline;
danjulio 0:8fc18502886a 28 volatile bool recvdflag;
danjulio 0:8fc18502886a 29 volatile bool inStandbyMode;
danjulio 0:8fc18502886a 30
danjulio 0:8fc18502886a 31
danjulio 0:8fc18502886a 32 bool Adafruit_GPS::parse(char *nmea) {
danjulio 0:8fc18502886a 33 // do checksum check
danjulio 0:8fc18502886a 34
danjulio 0:8fc18502886a 35 // first look if we even have one
danjulio 0:8fc18502886a 36 if (nmea[strlen(nmea)-4] == '*') {
danjulio 0:8fc18502886a 37 uint16_t sum = parseHex(nmea[strlen(nmea)-3]) * 16;
danjulio 0:8fc18502886a 38 sum += parseHex(nmea[strlen(nmea)-2]);
danjulio 0:8fc18502886a 39
danjulio 0:8fc18502886a 40 // check checksum
danjulio 0:8fc18502886a 41 for (uint8_t i=2; i < (strlen(nmea)-4); i++) {
danjulio 0:8fc18502886a 42 sum ^= nmea[i];
danjulio 0:8fc18502886a 43 }
danjulio 0:8fc18502886a 44 if (sum != 0) {
danjulio 0:8fc18502886a 45 // bad checksum :(
danjulio 0:8fc18502886a 46 //printf("bad checksum\n");
danjulio 0:8fc18502886a 47 return false;
danjulio 0:8fc18502886a 48 }
danjulio 0:8fc18502886a 49 }
danjulio 0:8fc18502886a 50 int32_t degree;
danjulio 0:8fc18502886a 51 long minutes;
danjulio 0:8fc18502886a 52 char degreebuff[10];
danjulio 0:8fc18502886a 53 // look for a few common sentences
danjulio 0:8fc18502886a 54 if (strstr(nmea, "$GPGGA")) {
danjulio 0:8fc18502886a 55 // found GGA
danjulio 0:8fc18502886a 56 char *p = nmea;
danjulio 0:8fc18502886a 57 // get time
danjulio 0:8fc18502886a 58 p = strchr(p, ',')+1;
danjulio 0:8fc18502886a 59 float timef = atof(p);
danjulio 0:8fc18502886a 60 uint32_t time = timef;
danjulio 0:8fc18502886a 61 hour = time / 10000;
danjulio 0:8fc18502886a 62 minute = (time % 10000) / 100;
danjulio 0:8fc18502886a 63 seconds = (time % 100);
danjulio 0:8fc18502886a 64
danjulio 0:8fc18502886a 65 milliseconds = fmod(timef, 1.0f) * 1000;
danjulio 0:8fc18502886a 66
danjulio 0:8fc18502886a 67 // parse out latitude
danjulio 0:8fc18502886a 68 p = strchr(p, ',')+1;
danjulio 0:8fc18502886a 69 if (',' != *p)
danjulio 0:8fc18502886a 70 {
danjulio 0:8fc18502886a 71 strncpy(degreebuff, p, 2);
danjulio 0:8fc18502886a 72 p += 2;
danjulio 0:8fc18502886a 73 degreebuff[2] = '\0';
danjulio 0:8fc18502886a 74 degree = atol(degreebuff) * 10000000;
danjulio 0:8fc18502886a 75 strncpy(degreebuff, p, 2); // minutes
danjulio 0:8fc18502886a 76 p += 3; // skip decimal point
danjulio 0:8fc18502886a 77 strncpy(degreebuff + 2, p, 4);
danjulio 0:8fc18502886a 78 degreebuff[6] = '\0';
danjulio 0:8fc18502886a 79 minutes = 50 * atol(degreebuff) / 3;
danjulio 0:8fc18502886a 80 latitude_fixed = degree + minutes;
danjulio 0:8fc18502886a 81 latitude = degree / 100000 + minutes * 0.000006f;
danjulio 0:8fc18502886a 82 latitudeDegrees = (latitude-100*int(latitude/100))/60.0f;
danjulio 0:8fc18502886a 83 latitudeDegrees += int(latitude/100);
danjulio 0:8fc18502886a 84 }
danjulio 0:8fc18502886a 85
danjulio 0:8fc18502886a 86 p = strchr(p, ',')+1;
danjulio 0:8fc18502886a 87 if (',' != *p)
danjulio 0:8fc18502886a 88 {
danjulio 0:8fc18502886a 89 if (p[0] == 'S') latitudeDegrees *= -1.0f;
danjulio 0:8fc18502886a 90 if (p[0] == 'N') lat = 'N';
danjulio 0:8fc18502886a 91 else if (p[0] == 'S') lat = 'S';
danjulio 0:8fc18502886a 92 else if (p[0] == ',') lat = 0;
danjulio 0:8fc18502886a 93 else return false;
danjulio 0:8fc18502886a 94 }
danjulio 0:8fc18502886a 95
danjulio 0:8fc18502886a 96 // parse out longitude
danjulio 0:8fc18502886a 97 p = strchr(p, ',')+1;
danjulio 0:8fc18502886a 98 if (',' != *p)
danjulio 0:8fc18502886a 99 {
danjulio 0:8fc18502886a 100 strncpy(degreebuff, p, 3);
danjulio 0:8fc18502886a 101 p += 3;
danjulio 0:8fc18502886a 102 degreebuff[3] = '\0';
danjulio 0:8fc18502886a 103 degree = atol(degreebuff) * 10000000;
danjulio 0:8fc18502886a 104 strncpy(degreebuff, p, 2); // minutes
danjulio 0:8fc18502886a 105 p += 3; // skip decimal point
danjulio 0:8fc18502886a 106 strncpy(degreebuff + 2, p, 4);
danjulio 0:8fc18502886a 107 degreebuff[6] = '\0';
danjulio 0:8fc18502886a 108 minutes = 50 * atol(degreebuff) / 3;
danjulio 0:8fc18502886a 109 longitude_fixed = degree + minutes;
danjulio 0:8fc18502886a 110 longitude = degree / 100000 + minutes * 0.000006f;
danjulio 0:8fc18502886a 111 longitudeDegrees = (longitude-100*int(longitude/100))/60.0f;
danjulio 0:8fc18502886a 112 longitudeDegrees += int(longitude/100);
danjulio 0:8fc18502886a 113 }
danjulio 0:8fc18502886a 114
danjulio 0:8fc18502886a 115 p = strchr(p, ',')+1;
danjulio 0:8fc18502886a 116 if (',' != *p)
danjulio 0:8fc18502886a 117 {
danjulio 0:8fc18502886a 118 if (p[0] == 'W') longitudeDegrees *= -1.0f;
danjulio 0:8fc18502886a 119 if (p[0] == 'W') lon = 'W';
danjulio 0:8fc18502886a 120 else if (p[0] == 'E') lon = 'E';
danjulio 0:8fc18502886a 121 else if (p[0] == ',') lon = 0;
danjulio 0:8fc18502886a 122 else {
danjulio 0:8fc18502886a 123 //printf("unknown lon\n");
danjulio 0:8fc18502886a 124 return false;
danjulio 0:8fc18502886a 125 }
danjulio 0:8fc18502886a 126 }
danjulio 0:8fc18502886a 127
danjulio 0:8fc18502886a 128 p = strchr(p, ',')+1;
danjulio 0:8fc18502886a 129 if (',' != *p)
danjulio 0:8fc18502886a 130 {
danjulio 0:8fc18502886a 131 fixquality = atoi(p);
danjulio 0:8fc18502886a 132 fix = (fixquality != 0); // Added by Dan Julio
danjulio 0:8fc18502886a 133 }
danjulio 0:8fc18502886a 134
danjulio 0:8fc18502886a 135 p = strchr(p, ',')+1;
danjulio 0:8fc18502886a 136 if (',' != *p)
danjulio 0:8fc18502886a 137 {
danjulio 0:8fc18502886a 138 satellites = atoi(p);
danjulio 0:8fc18502886a 139 }
danjulio 0:8fc18502886a 140
danjulio 0:8fc18502886a 141 p = strchr(p, ',')+1;
danjulio 0:8fc18502886a 142 if (',' != *p)
danjulio 0:8fc18502886a 143 {
danjulio 0:8fc18502886a 144 HDOP = atof(p);
danjulio 0:8fc18502886a 145 }
danjulio 0:8fc18502886a 146
danjulio 0:8fc18502886a 147 p = strchr(p, ',')+1;
danjulio 0:8fc18502886a 148 if (',' != *p)
danjulio 0:8fc18502886a 149 {
danjulio 0:8fc18502886a 150 altitude = atof(p);
danjulio 0:8fc18502886a 151 }
danjulio 0:8fc18502886a 152
danjulio 0:8fc18502886a 153 p = strchr(p, ',')+1;
danjulio 0:8fc18502886a 154 p = strchr(p, ',')+1;
danjulio 0:8fc18502886a 155 if (',' != *p)
danjulio 0:8fc18502886a 156 {
danjulio 0:8fc18502886a 157 geoidheight = atof(p);
danjulio 0:8fc18502886a 158 }
danjulio 0:8fc18502886a 159 return true;
danjulio 0:8fc18502886a 160 }
danjulio 0:8fc18502886a 161 if (strstr(nmea, "$GPRMC")) {
danjulio 0:8fc18502886a 162 // found RMC
danjulio 0:8fc18502886a 163 char *p = nmea;
danjulio 0:8fc18502886a 164
danjulio 0:8fc18502886a 165 // get time
danjulio 0:8fc18502886a 166 p = strchr(p, ',')+1;
danjulio 0:8fc18502886a 167 float timef = atof(p);
danjulio 0:8fc18502886a 168 uint32_t time = timef;
danjulio 0:8fc18502886a 169 hour = time / 10000;
danjulio 0:8fc18502886a 170 minute = (time % 10000) / 100;
danjulio 0:8fc18502886a 171 seconds = (time % 100);
danjulio 0:8fc18502886a 172
danjulio 0:8fc18502886a 173 milliseconds = fmod(timef, 1.0f) * 1000;
danjulio 0:8fc18502886a 174
danjulio 0:8fc18502886a 175 p = strchr(p, ',')+1;
danjulio 0:8fc18502886a 176 // Serial.println(p);
danjulio 0:8fc18502886a 177 if (p[0] == 'A')
danjulio 0:8fc18502886a 178 fix = true;
danjulio 0:8fc18502886a 179 else if (p[0] == 'V')
danjulio 0:8fc18502886a 180 fix = false;
danjulio 0:8fc18502886a 181 else {
danjulio 0:8fc18502886a 182 //printf("unknown fix\n");
danjulio 0:8fc18502886a 183 return false;
danjulio 0:8fc18502886a 184 }
danjulio 0:8fc18502886a 185
danjulio 0:8fc18502886a 186 // parse out latitude
danjulio 0:8fc18502886a 187 p = strchr(p, ',')+1;
danjulio 0:8fc18502886a 188 if (',' != *p)
danjulio 0:8fc18502886a 189 {
danjulio 0:8fc18502886a 190 strncpy(degreebuff, p, 2);
danjulio 0:8fc18502886a 191 p += 2;
danjulio 0:8fc18502886a 192 degreebuff[2] = '\0';
danjulio 0:8fc18502886a 193 long degree = atol(degreebuff) * 10000000;
danjulio 0:8fc18502886a 194 strncpy(degreebuff, p, 2); // minutes
danjulio 0:8fc18502886a 195 p += 3; // skip decimal point
danjulio 0:8fc18502886a 196 strncpy(degreebuff + 2, p, 4);
danjulio 0:8fc18502886a 197 degreebuff[6] = '\0';
danjulio 0:8fc18502886a 198 long minutes = 50 * atol(degreebuff) / 3;
danjulio 0:8fc18502886a 199 latitude_fixed = degree + minutes;
danjulio 0:8fc18502886a 200 latitude = degree / 100000 + minutes * 0.000006f;
danjulio 0:8fc18502886a 201 latitudeDegrees = (latitude-100*int(latitude/100))/60.0f;
danjulio 0:8fc18502886a 202 latitudeDegrees += int(latitude/100);
danjulio 0:8fc18502886a 203 }
danjulio 0:8fc18502886a 204
danjulio 0:8fc18502886a 205 p = strchr(p, ',')+1;
danjulio 0:8fc18502886a 206 if (',' != *p)
danjulio 0:8fc18502886a 207 {
danjulio 0:8fc18502886a 208 if (p[0] == 'S') latitudeDegrees *= -1.0;
danjulio 0:8fc18502886a 209 if (p[0] == 'N') lat = 'N';
danjulio 0:8fc18502886a 210 else if (p[0] == 'S') lat = 'S';
danjulio 0:8fc18502886a 211 else if (p[0] == ',') lat = 0;
danjulio 0:8fc18502886a 212 else {
danjulio 0:8fc18502886a 213 //printf("unknown lat\n");
danjulio 0:8fc18502886a 214 return false;
danjulio 0:8fc18502886a 215 }
danjulio 0:8fc18502886a 216 }
danjulio 0:8fc18502886a 217
danjulio 0:8fc18502886a 218 // parse out longitude
danjulio 0:8fc18502886a 219 p = strchr(p, ',')+1;
danjulio 0:8fc18502886a 220 if (',' != *p)
danjulio 0:8fc18502886a 221 {
danjulio 0:8fc18502886a 222 strncpy(degreebuff, p, 3);
danjulio 0:8fc18502886a 223 p += 3;
danjulio 0:8fc18502886a 224 degreebuff[3] = '\0';
danjulio 0:8fc18502886a 225 degree = atol(degreebuff) * 10000000;
danjulio 0:8fc18502886a 226 strncpy(degreebuff, p, 2); // minutes
danjulio 0:8fc18502886a 227 p += 3; // skip decimal point
danjulio 0:8fc18502886a 228 strncpy(degreebuff + 2, p, 4);
danjulio 0:8fc18502886a 229 degreebuff[6] = '\0';
danjulio 0:8fc18502886a 230 minutes = 50 * atol(degreebuff) / 3;
danjulio 0:8fc18502886a 231 longitude_fixed = degree + minutes;
danjulio 0:8fc18502886a 232 longitude = degree / 100000 + minutes * 0.000006f;
danjulio 0:8fc18502886a 233 longitudeDegrees = (longitude-100*int(longitude/100))/60.0f;
danjulio 0:8fc18502886a 234 longitudeDegrees += int(longitude/100);
danjulio 0:8fc18502886a 235 }
danjulio 0:8fc18502886a 236
danjulio 0:8fc18502886a 237 p = strchr(p, ',')+1;
danjulio 0:8fc18502886a 238 if (',' != *p)
danjulio 0:8fc18502886a 239 {
danjulio 0:8fc18502886a 240 if (p[0] == 'W') longitudeDegrees *= -1.0f;
danjulio 0:8fc18502886a 241 if (p[0] == 'W') lon = 'W';
danjulio 0:8fc18502886a 242 else if (p[0] == 'E') lon = 'E';
danjulio 0:8fc18502886a 243 else if (p[0] == ',') lon = 0;
danjulio 0:8fc18502886a 244 else {
danjulio 0:8fc18502886a 245 //printf("unknown lon (2)\n");
danjulio 0:8fc18502886a 246 return false;
danjulio 0:8fc18502886a 247 }
danjulio 0:8fc18502886a 248 }
danjulio 0:8fc18502886a 249
danjulio 0:8fc18502886a 250 // speed
danjulio 0:8fc18502886a 251 p = strchr(p, ',')+1;
danjulio 0:8fc18502886a 252 if (',' != *p)
danjulio 0:8fc18502886a 253 {
danjulio 0:8fc18502886a 254 speed = atof(p);
danjulio 0:8fc18502886a 255 }
danjulio 0:8fc18502886a 256
danjulio 0:8fc18502886a 257 // angle
danjulio 0:8fc18502886a 258 p = strchr(p, ',')+1;
danjulio 0:8fc18502886a 259 if (',' != *p)
danjulio 0:8fc18502886a 260 {
danjulio 0:8fc18502886a 261 angle = atof(p);
danjulio 0:8fc18502886a 262 }
danjulio 0:8fc18502886a 263
danjulio 0:8fc18502886a 264 p = strchr(p, ',')+1;
danjulio 0:8fc18502886a 265 if (',' != *p)
danjulio 0:8fc18502886a 266 {
danjulio 0:8fc18502886a 267 uint32_t fulldate = atof(p);
danjulio 0:8fc18502886a 268 day = fulldate / 10000;
danjulio 0:8fc18502886a 269 month = (fulldate % 10000) / 100;
danjulio 0:8fc18502886a 270 year = (fulldate % 100);
danjulio 0:8fc18502886a 271 }
danjulio 0:8fc18502886a 272
danjulio 0:8fc18502886a 273 // we dont parse the remaining, yet!
danjulio 0:8fc18502886a 274 return true;
danjulio 0:8fc18502886a 275 }
danjulio 0:8fc18502886a 276 //printf("unknown sentence\n");
danjulio 0:8fc18502886a 277 return false;
danjulio 0:8fc18502886a 278 }
danjulio 0:8fc18502886a 279
danjulio 0:8fc18502886a 280 char Adafruit_GPS::read(void) {
danjulio 0:8fc18502886a 281 char c = 0;
danjulio 0:8fc18502886a 282
danjulio 0:8fc18502886a 283 if (paused) return c;
danjulio 0:8fc18502886a 284
danjulio 0:8fc18502886a 285 if(!gpsHwSerial->readable()) return c;
danjulio 0:8fc18502886a 286
danjulio 0:8fc18502886a 287 c = gpsHwSerial->getc();
danjulio 0:8fc18502886a 288
danjulio 0:8fc18502886a 289 printf("%c", c);
danjulio 0:8fc18502886a 290
danjulio 0:8fc18502886a 291 // if (c == '$') { //please don't eat the dollar sign - rdl 9/15/14
danjulio 0:8fc18502886a 292 // currentline[lineidx] = 0;
danjulio 0:8fc18502886a 293 // lineidx = 0;
danjulio 0:8fc18502886a 294 // }
danjulio 0:8fc18502886a 295 if (c == '\n') {
danjulio 0:8fc18502886a 296 currentline[lineidx] = 0;
danjulio 0:8fc18502886a 297
danjulio 0:8fc18502886a 298 if (currentline == line1) {
danjulio 0:8fc18502886a 299 currentline = line2;
danjulio 0:8fc18502886a 300 lastline = line1;
danjulio 0:8fc18502886a 301 } else {
danjulio 0:8fc18502886a 302 currentline = line1;
danjulio 0:8fc18502886a 303 lastline = line2;
danjulio 0:8fc18502886a 304 }
danjulio 0:8fc18502886a 305
danjulio 0:8fc18502886a 306 //printf("----\n");
danjulio 0:8fc18502886a 307 //printf((char *)lastline);
danjulio 0:8fc18502886a 308 //printf("\n----\n");
danjulio 0:8fc18502886a 309 lineidx = 0;
danjulio 0:8fc18502886a 310 recvdflag = true;
danjulio 0:8fc18502886a 311 }
danjulio 0:8fc18502886a 312
danjulio 0:8fc18502886a 313 if (c != '\r') {
danjulio 0:8fc18502886a 314 currentline[lineidx++] = c;
danjulio 0:8fc18502886a 315 if (lineidx >= MAXLINELENGTH)
danjulio 0:8fc18502886a 316 lineidx = MAXLINELENGTH-1;
danjulio 0:8fc18502886a 317 }
danjulio 0:8fc18502886a 318
danjulio 0:8fc18502886a 319 return c;
danjulio 0:8fc18502886a 320 }
danjulio 0:8fc18502886a 321
danjulio 0:8fc18502886a 322 void Adafruit_GPS::readNMEA(void) {
danjulio 0:8fc18502886a 323 char c;
danjulio 0:8fc18502886a 324
danjulio 0:8fc18502886a 325 recvdflag = false;
danjulio 0:8fc18502886a 326
danjulio 0:8fc18502886a 327 while (!recvdflag) {
danjulio 0:8fc18502886a 328 if (!gpsHwSerial->readable()) {
danjulio 0:8fc18502886a 329 // No data yet
danjulio 0:8fc18502886a 330 Thread::yield();
danjulio 0:8fc18502886a 331 } else {
danjulio 0:8fc18502886a 332 c = gpsHwSerial->getc();
danjulio 0:8fc18502886a 333 //printf("%c", c);
danjulio 0:8fc18502886a 334 if (c == '\n') {
danjulio 0:8fc18502886a 335 // End-of-line
danjulio 0:8fc18502886a 336 currentline[lineidx] = 0;
danjulio 0:8fc18502886a 337 if (currentline == line1) {
danjulio 0:8fc18502886a 338 currentline = line2;
danjulio 0:8fc18502886a 339 lastline = line1;
danjulio 0:8fc18502886a 340 } else {
danjulio 0:8fc18502886a 341 currentline = line1;
danjulio 0:8fc18502886a 342 lastline = line2;
danjulio 0:8fc18502886a 343 }
danjulio 0:8fc18502886a 344 lineidx = 0;
danjulio 0:8fc18502886a 345 recvdflag = true;
danjulio 0:8fc18502886a 346 } else if (c != '\r') {
danjulio 0:8fc18502886a 347 // Data character
danjulio 0:8fc18502886a 348 currentline[lineidx++] = c;
danjulio 0:8fc18502886a 349 if (lineidx >= MAXLINELENGTH) {
danjulio 0:8fc18502886a 350 lineidx = MAXLINELENGTH-1;
danjulio 0:8fc18502886a 351 }
danjulio 0:8fc18502886a 352 }
danjulio 0:8fc18502886a 353 }
danjulio 0:8fc18502886a 354 }
danjulio 0:8fc18502886a 355 }
danjulio 0:8fc18502886a 356
danjulio 0:8fc18502886a 357 // Constructor when using Built-in Serial Hardware
danjulio 0:8fc18502886a 358 Adafruit_GPS::Adafruit_GPS(Serial *ser) {
danjulio 0:8fc18502886a 359 common_init(); // Set everything to common state, then...
danjulio 0:8fc18502886a 360 gpsHwSerial = ser; // ...override gpsHwSerial with value passed.
danjulio 0:8fc18502886a 361 }
danjulio 0:8fc18502886a 362
danjulio 0:8fc18502886a 363 // Initialization code used by all constructor types
danjulio 0:8fc18502886a 364 void Adafruit_GPS::common_init(void) {
danjulio 0:8fc18502886a 365 gpsHwSerial = NULL; // port pointer in corresponding constructor
danjulio 0:8fc18502886a 366 recvdflag = false;
danjulio 0:8fc18502886a 367 paused = false;
danjulio 0:8fc18502886a 368 lineidx = 0;
danjulio 0:8fc18502886a 369 currentline = line1;
danjulio 0:8fc18502886a 370 lastline = line2;
danjulio 0:8fc18502886a 371
danjulio 0:8fc18502886a 372 hour = minute = seconds = year = month = day =
danjulio 0:8fc18502886a 373 fixquality = satellites = 0; // uint8_t
danjulio 0:8fc18502886a 374 lat = lon = mag = 0; // char
danjulio 0:8fc18502886a 375 fix = false; // bool
danjulio 0:8fc18502886a 376 milliseconds = 0; // uint16_t
danjulio 0:8fc18502886a 377 latitude = longitude = geoidheight = altitude =
danjulio 0:8fc18502886a 378 speed = angle = magvariation = HDOP = 0.0; // float
danjulio 0:8fc18502886a 379 }
danjulio 0:8fc18502886a 380
danjulio 0:8fc18502886a 381 void Adafruit_GPS::begin(uint32_t baud)
danjulio 0:8fc18502886a 382 {
danjulio 0:8fc18502886a 383 gpsHwSerial->baud(baud);
danjulio 0:8fc18502886a 384 }
danjulio 0:8fc18502886a 385
danjulio 0:8fc18502886a 386 void Adafruit_GPS::sendCommand(const char *str) {
danjulio 0:8fc18502886a 387 gpsHwSerial->printf("%s\n", str);
danjulio 0:8fc18502886a 388 }
danjulio 0:8fc18502886a 389
danjulio 0:8fc18502886a 390 bool Adafruit_GPS::newNMEAreceived(void) {
danjulio 0:8fc18502886a 391 return recvdflag;
danjulio 0:8fc18502886a 392 }
danjulio 0:8fc18502886a 393
danjulio 0:8fc18502886a 394 void Adafruit_GPS::pause(bool p) {
danjulio 0:8fc18502886a 395 paused = p;
danjulio 0:8fc18502886a 396 }
danjulio 0:8fc18502886a 397
danjulio 0:8fc18502886a 398 char *Adafruit_GPS::lastNMEA(void) {
danjulio 0:8fc18502886a 399 recvdflag = false;
danjulio 0:8fc18502886a 400 return (char *)lastline;
danjulio 0:8fc18502886a 401 }
danjulio 0:8fc18502886a 402
danjulio 0:8fc18502886a 403 // read a Hex value and return the decimal equivalent
danjulio 0:8fc18502886a 404 uint8_t Adafruit_GPS::parseHex(char c) {
danjulio 0:8fc18502886a 405 if (c < '0')
danjulio 0:8fc18502886a 406 return 0;
danjulio 0:8fc18502886a 407 if (c <= '9')
danjulio 0:8fc18502886a 408 return c - '0';
danjulio 0:8fc18502886a 409 if (c < 'A')
danjulio 0:8fc18502886a 410 return 0;
danjulio 0:8fc18502886a 411 if (c <= 'F')
danjulio 0:8fc18502886a 412 return (c - 'A')+10;
danjulio 0:8fc18502886a 413 // if (c > 'F')
danjulio 0:8fc18502886a 414 return 0;
danjulio 0:8fc18502886a 415 }
danjulio 0:8fc18502886a 416
danjulio 0:8fc18502886a 417 bool Adafruit_GPS::waitForSentence(const char *wait4me, uint8_t max) {
danjulio 0:8fc18502886a 418 char str[20];
danjulio 0:8fc18502886a 419
danjulio 0:8fc18502886a 420 uint8_t i=0;
danjulio 0:8fc18502886a 421 while (i < max) {
danjulio 0:8fc18502886a 422 if (newNMEAreceived()) {
danjulio 0:8fc18502886a 423 char *nmea = lastNMEA();
danjulio 0:8fc18502886a 424 strncpy(str, nmea, 20);
danjulio 0:8fc18502886a 425 str[19] = 0;
danjulio 0:8fc18502886a 426 i++;
danjulio 0:8fc18502886a 427
danjulio 0:8fc18502886a 428 if (strstr(str, wait4me))
danjulio 0:8fc18502886a 429 return true;
danjulio 0:8fc18502886a 430 }
danjulio 0:8fc18502886a 431 }
danjulio 0:8fc18502886a 432
danjulio 0:8fc18502886a 433 return false;
danjulio 0:8fc18502886a 434 }
danjulio 0:8fc18502886a 435
danjulio 0:8fc18502886a 436 bool Adafruit_GPS::LOCUS_StartLogger(void) {
danjulio 0:8fc18502886a 437 sendCommand(PMTK_LOCUS_STARTLOG);
danjulio 0:8fc18502886a 438 recvdflag = false;
danjulio 0:8fc18502886a 439 return waitForSentence(PMTK_LOCUS_STARTSTOPACK);
danjulio 0:8fc18502886a 440 }
danjulio 0:8fc18502886a 441
danjulio 0:8fc18502886a 442 bool Adafruit_GPS::LOCUS_StopLogger(void) {
danjulio 0:8fc18502886a 443 sendCommand(PMTK_LOCUS_STOPLOG);
danjulio 0:8fc18502886a 444 recvdflag = false;
danjulio 0:8fc18502886a 445 return waitForSentence(PMTK_LOCUS_STARTSTOPACK);
danjulio 0:8fc18502886a 446 }
danjulio 0:8fc18502886a 447
danjulio 0:8fc18502886a 448 bool Adafruit_GPS::LOCUS_ReadStatus(void) {
danjulio 0:8fc18502886a 449 sendCommand(PMTK_LOCUS_QUERY_STATUS);
danjulio 0:8fc18502886a 450
danjulio 0:8fc18502886a 451 if (! waitForSentence("$PMTKLOG"))
danjulio 0:8fc18502886a 452 return false;
danjulio 0:8fc18502886a 453
danjulio 0:8fc18502886a 454 char *response = lastNMEA();
danjulio 0:8fc18502886a 455 uint16_t parsed[10];
danjulio 0:8fc18502886a 456 uint8_t i;
danjulio 0:8fc18502886a 457
danjulio 0:8fc18502886a 458 for (i=0; i<10; i++) parsed[i] = 65535;
danjulio 0:8fc18502886a 459
danjulio 0:8fc18502886a 460 response = strchr(response, ',');
danjulio 0:8fc18502886a 461 for (i=0; i<10; i++) {
danjulio 0:8fc18502886a 462 if (!response || (response[0] == 0) || (response[0] == '*'))
danjulio 0:8fc18502886a 463 break;
danjulio 0:8fc18502886a 464 response++;
danjulio 0:8fc18502886a 465 parsed[i]=0;
danjulio 0:8fc18502886a 466 while ((response[0] != ',') &&
danjulio 0:8fc18502886a 467 (response[0] != '*') && (response[0] != 0)) {
danjulio 0:8fc18502886a 468 parsed[i] *= 10;
danjulio 0:8fc18502886a 469 char c = response[0];
danjulio 0:8fc18502886a 470 if ((c <= '9') && (c >= '0'))
danjulio 0:8fc18502886a 471 parsed[i] += c - '0';
danjulio 0:8fc18502886a 472 else
danjulio 0:8fc18502886a 473 parsed[i] = c;
danjulio 0:8fc18502886a 474 response++;
danjulio 0:8fc18502886a 475 }
danjulio 0:8fc18502886a 476 }
danjulio 0:8fc18502886a 477 LOCUS_serial = parsed[0];
danjulio 0:8fc18502886a 478 LOCUS_type = parsed[1];
danjulio 0:8fc18502886a 479 if ((parsed[2] <= 'z') && (parsed[2] >= 'a')) {
danjulio 0:8fc18502886a 480 parsed[2] = parsed[2] - 'a' + 10;
danjulio 0:8fc18502886a 481 }
danjulio 0:8fc18502886a 482 LOCUS_mode = parsed[2];
danjulio 0:8fc18502886a 483 LOCUS_config = parsed[3];
danjulio 0:8fc18502886a 484 LOCUS_interval = parsed[4];
danjulio 0:8fc18502886a 485 LOCUS_distance = parsed[5];
danjulio 0:8fc18502886a 486 LOCUS_speed = parsed[6];
danjulio 0:8fc18502886a 487 LOCUS_status = !parsed[7];
danjulio 0:8fc18502886a 488 LOCUS_records = parsed[8];
danjulio 0:8fc18502886a 489 LOCUS_percent = parsed[9];
danjulio 0:8fc18502886a 490
danjulio 0:8fc18502886a 491 return true;
danjulio 0:8fc18502886a 492 }
danjulio 0:8fc18502886a 493
danjulio 0:8fc18502886a 494 // Standby Mode Switches
danjulio 0:8fc18502886a 495 bool Adafruit_GPS::standby(void) {
danjulio 0:8fc18502886a 496 if (inStandbyMode) {
danjulio 0:8fc18502886a 497 return false; // Returns false if already in standby mode, so that you do not wake it up by sending commands to GPS
danjulio 0:8fc18502886a 498 }
danjulio 0:8fc18502886a 499 else {
danjulio 0:8fc18502886a 500 inStandbyMode = true;
danjulio 0:8fc18502886a 501 sendCommand(PMTK_STANDBY);
danjulio 0:8fc18502886a 502 //return waitForSentence(PMTK_STANDBY_SUCCESS); // don't seem to be fast enough to catch the message, or something else just is not working
danjulio 0:8fc18502886a 503 return true;
danjulio 0:8fc18502886a 504 }
danjulio 0:8fc18502886a 505 }
danjulio 0:8fc18502886a 506
danjulio 0:8fc18502886a 507 bool Adafruit_GPS::wakeup(void) {
danjulio 0:8fc18502886a 508 if (inStandbyMode) {
danjulio 0:8fc18502886a 509 inStandbyMode = false;
danjulio 0:8fc18502886a 510 sendCommand(""); // send byte to wake it up
danjulio 0:8fc18502886a 511 return waitForSentence(PMTK_AWAKE);
danjulio 0:8fc18502886a 512 }
danjulio 0:8fc18502886a 513 else {
danjulio 0:8fc18502886a 514 return false; // Returns false if not in standby mode, nothing to wakeup
danjulio 0:8fc18502886a 515 }
danjulio 0:8fc18502886a 516 }