Updated version with new commands and sleep mode
Fork of GPS by
Revision 7:7aac669b0075, committed 2015-04-07
- Comitter:
- Spilly
- Date:
- Tue Apr 07 03:49:28 2015 +0000
- Parent:
- 6:af055728e564
- Child:
- 8:2476bea153a1
- Commit message:
- Added additional documentation/comments
Changed in this revision
GPS.cpp | Show annotated file Show diff for this revision Revisions of this file |
GPS.h | Show annotated file Show diff for this revision Revisions of this file |
--- a/GPS.cpp Sun Apr 05 01:41:34 2015 +0000 +++ b/GPS.cpp Tue Apr 07 03:49:28 2015 +0000 @@ -2,10 +2,15 @@ // This is a modified version of mbed /users/SamClarke/code/GPS/ for MTK3339 GPS module // // Changes made by Ryan Spillman: +// +// Last updated: 4/6/2015 +// // added commands to the initialization function to set baud rate, set update rate, enabled DGPS WAAS, and set minimum navigation speed // added a function to put the unit into sleep mode // added several zeros after the decimal places to fix weird rounding errors // added information about checksums +// Modified parse data function to get all of the NMEA sentences at once. Previously it only grabbed one sentence each time the function was called +// Changed latitude and longitude calculation variables to doubles to decrease math errors // // IMPORTANT: // Any changes made to commands sent to GPS unit require corresponding changes to the @@ -14,6 +19,8 @@ // http://siliconsparrow.com/demos/nmeachecksum.php **************************************************************************************************************************************************************/ +//GDOP = delta(output location) / delta(measured data) + #include "GPS.h" GPS::GPS(PinName tx, PinName rx) : _UltimateGps(tx, rx) { @@ -21,86 +28,188 @@ _UltimateGps.baud(38400); //Changed firmware of MTK3339 to 38400 baud with update rate of 5Hz (GlobalTopFlashTool to change firmware) } +void GPS::coldStart() +{ + _UltimateGps.printf("$PMTK103*30\r\n"); +} +int GPS::getGPGGA() +{ + if(sscanf(NEMA, "GPGGA, %*f, %*f, %*c, %*f, %*c, %d, %d, %*f, %f", &fixtype, &satellites, &altitude) >=1) + { + //if(fixtype == 0) return 0; + return 1; + } + return 0; +} +int GPS::getGPGSA() +{ + if(satellites == 4) + { + if(sscanf(NEMA, "GPGSA, %c, %d, %*c, %*c, %*c, %*c,,,,,,,,,%f, %f, %f", &mode, &status, &PDOP, &HDOP, &VDOP) >=1) return 1; + } + else if(satellites == 5) + { + if(sscanf(NEMA, "GPGSA, %c, %d, %*d, %*d, %*d, %*d, %*d,,,,,,,, %f, %f, %f", &mode, &status, &PDOP, &HDOP, &VDOP) >=1) return 1; + } + else if(satellites == 6) + { + if(sscanf(NEMA, "GPGSA, %c, %d, %*d, %*d, %*d, %*d, %*d, %*d,,,,,,, %f, %f, %f", &mode, &status, &PDOP, &HDOP, &VDOP) >=1) return 1; + } + else if(satellites == 7) + { + if(sscanf(NEMA, "GPGSA, %c, %d, %*d, %*d, %*d, %*d, %*d, %*d, %*d,,,,,, %f, %f, %f", &mode, &status, &PDOP, &HDOP, &VDOP) >=1) return 1; + } + else if(satellites == 8) + { + if(sscanf(NEMA, "GPGSA, %c, %d, %*d, %*d, %*d, %*d, %*d, %*d, %*d, %*d,,,,, %f, %f, %f", &mode, &status, &PDOP, &HDOP, &VDOP) >=1) return 1; + } + else if(satellites == 9) + { + if(sscanf(NEMA, "GPGSA, %c, %d, %*d, %*d, %*d, %*d, %*d, %*d, %*d, %*d, %*d,,,, %f, %f, %f", &mode, &status, &PDOP, &HDOP, &VDOP) >=1) return 1; + } + else if(satellites == 10) + { + if(sscanf(NEMA, "GPGSA, %c, %d, %*d, %*d, %*d, %*d, %*d, %*d, %*d, %*d, %*d, %*d,,, %f, %f, %f", &mode, &status, &PDOP, &HDOP, &VDOP) >=1) return 1; + } + else if(satellites == 11) + { + if(sscanf(NEMA, "GPGSA, %c, %d, %*d, %*d, %*d, %*d, %*d, %*d, %*d, %*d, %*d, %*d, %*d,, %f, %f, %f", &mode, &status, &PDOP, &HDOP, &VDOP) >=1) return 1; + } + else + { + if(sscanf(NEMA, "GPGSA, %c, %d, %*d, %*d, %*d, %*d, %*d, %*d, %*d, %*d, %*d, %*d, %*d, %*d, %f, %f, %f", &mode, &status, &PDOP, &HDOP, &VDOP) >=1) return 1; + } + return 0; +} +int GPS::getGPRMC() +{ + + if(sscanf(NEMA, "GPRMC, %2d%2d%f, %c, %f, %c, %f, %c, %f, %f, %2d%2d%2d", &hours, &minutes, &seconds, &validity, &latitude, &ns, &longitude, &ew, &speed, &heading, &day, &month, &year) >=1) + { + year += 2000; + if(ns =='S') { + latitude *= -1.00000000000000000f; + } + if(ew =='W') { + longitude *= -1.00000000000000000f; + } + double degrees = trunc(latitude / 100.0000000000000000f); + double minutes = latitude - (degrees * 100.00000000000000000f); + degLat = degrees + minutes / 60.00000000000000000f; + degrees = trunc(longitude / 100.0000000000000000f); + minutes = longitude - (degrees * 100.00000000000000000f); + degLon = degrees + minutes / 60.00000000000000000f; + if(fixtype == 1) { + fix = "Positive"; + } + if(fixtype == 2) { + fix = "Differential"; + } + if(heading > 0.00f && heading < 45.00f) { + cardinal = "NNE"; + } + if(heading == 45.00f) { + cardinal = "NE"; + } + if(heading > 45.00f && heading < 90.00f) { + cardinal = "ENE"; + } + if(heading == 90.00f) { + cardinal = "E"; + } + if(heading > 90.00f && heading < 135.00f) { + cardinal = "ESE"; + } + if(heading == 135.00f) { + cardinal = "SE"; + } + if(heading > 135.00f && heading < 180.00f) { + cardinal = "SSE"; + } + if(heading == 180.00f) { + cardinal = "S"; + } + if(heading > 180.00f && heading < 225.00f) { + cardinal = "SSW"; + } + if(heading == 225.00f) { + cardinal = "SW"; + } + if(heading > 225.00f && heading < 270.00f) { + cardinal = "WSW"; + } + if(heading == 270.00f) { + cardinal = "W"; + } + if(heading > 270.00f && heading < 315.00f) { + cardinal = "WNW"; + } + if(heading == 315.00f) { + cardinal = "NW"; + } + if(heading > 315.00f && heading < 360.00f) { + cardinal = "NNW"; + } + if(heading == 360.00f || heading == 0.00f) { + cardinal = "N"; + } + kph = speed*1.852f; + return 1; + } + return 0; +} int GPS::parseData() { - while(1) { + getData(); + if(getGPGGA()) + { getData(); - if(sscanf(NEMA, "GPGGA, %*f, %*f, %*c, %*f, %*c, %d, %d, %*f, %f", &fixtype, &satellites, &altitude) >=1); - if(sscanf(NEMA, "GPRMC, %2d%2d%f, %c, %f, %c, %f, %c, %f, %f, %2d%2d%2d", &hours, &minutes, &seconds, &validity, &latitude, &ns, &longitude, &ew, &speed, &heading, &day, &month, &year) >=1) { - if(fixtype == 0) { - return 0; - } - year += 2000; - if(ns =='S') { - latitude *= -1.00000000000000000f; - } - if(ew =='W') { - longitude *= -1.00000000000000000f; - } - float degrees = trunc(latitude / 100.0000000000000000f); - float minutes = latitude - (degrees * 100.00000000000000000f); - latitude = degrees + minutes / 60.00000000000000000f; - degrees = trunc(longitude / 100.0000000000000000f); - minutes = longitude - (degrees * 100.00000000000000000f); - longitude = degrees + minutes / 60.00000000000000000f; - if(fixtype == 1) { - fix = "Positive"; - } - if(fixtype == 2) { - fix = "Differential"; - } - if(heading > 0.00f && heading < 45.00f) { - cardinal = "NNE"; - } - if(heading == 45.00f) { - cardinal = "NE"; - } - if(heading > 45.00f && heading < 90.00f) { - cardinal = "ENE"; - } - if(heading == 90.00f) { - cardinal = "E"; - } - if(heading > 90.00f && heading < 135.00f) { - cardinal = "ESE"; - } - if(heading == 135.00f) { - cardinal = "SE"; - } - if(heading > 135.00f && heading < 180.00f) { - cardinal = "SSE"; - } - if(heading == 180.00f) { - cardinal = "S"; - } - if(heading > 180.00f && heading < 225.00f) { - cardinal = "SSW"; - } - if(heading == 225.00f) { - cardinal = "SW"; - } - if(heading > 225.00f && heading < 270.00f) { - cardinal = "WSW"; - } - if(heading == 270.00f) { - cardinal = "W"; - } - if(heading > 270.00f && heading < 315.00f) { - cardinal = "WNW"; - } - if(heading == 315.00f) { - cardinal = "NW"; - } - if(heading > 315.00f && heading < 360.00f) { - cardinal = "NNW"; - } - if(heading == 360.00f || heading == 0.00f) { - cardinal = "N"; - } - kph = speed*1.852f; + if(getGPGSA()) + { + getData(); + getGPRMC(); + return 1; + } + else + { + getData(); + getGPGSA(); return 1; } } + else if(getGPGSA()) + { + getData(); + if(getGPGGA()) + { + getData(); + getGPRMC(); + return 1; + } + else + { + getData(); + getGPGGA(); + return 1; + } + } + else + { + getData(); + if(getGPGGA()) + { + getData(); + getGPGSA(); + return 1; + } + else if(getGPGSA()) + { + getData(); + getGPGGA(); + return 1; + } + } + return 0; } @@ -131,13 +240,24 @@ void GPS::Init() { - _UltimateGps.printf("$PMTK251,38400*27\r\n"); //set baud (any higher and the serial buffer overflows) - //_UltimateGps.printf("$PMTK220,100*2F\r\n"); //10 Hz update - _UltimateGps.printf("$PMTK220,200*2C\r\n"); //5 Hz udpate - _UltimateGps.printf("$PMTK225,0*2bt\r\n"); //disable always locate (datasheet indicates that this negatively affects accuracy) - _UltimateGps.printf("$PMTK301,2*2et\r\n"); //set DGPS to use WAAS - _UltimateGps.printf("$PMTK386,0.8*35\r\n"); //set Nav Speed threshold to 0.8 m/s - _UltimateGps.printf("$PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*28\r\n"); + //don't need to send baud rate command because it is already set to 38400 in firmware + //_UltimateGps.printf("$PMTK251,38400*27\r\n"); //set baud (any higher and the serial buffer overflows) + + //Note: SBAS can only be enabled when update rate is less than or equal to 5Hz. + //_UltimateGps.printf("$PMTK220,100*2F\r\n"); //10 Hz update + _UltimateGps.printf("$PMTK220,200*2C\r\n"); //5 Hz udpate + //_UltimateGps.printf("$PMTK220,1000*1f\r\n"); //1 Hz udpate + + _UltimateGps.printf("$PMTK225,0*2bt\r\n"); //disable always locate (datasheet indicates that this negatively affects accuracy) + _UltimateGps.printf("$PMTK301,2*2et\r\n"); //set DGPS to use WAAS + + //_UltimateGps.printf("$PMTK386,0.8*35\r\n"); //set Nav Speed threshold to 0.8 m/s + //_UltimateGps.printf("$PMTK386,0.2*3f\r\n"); //set Nav Speed threshold to 0.2 m/s + _UltimateGps.printf("$PMTK386,0*23\r\n"); //disable Nav Speed threshold + + //_UltimateGps.printf("$PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*28\r\n"); //GPRMC and GPGGA + //_UltimateGps.printf("$PMTK314,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0*28\r\n"); //GPRMC and GPGSA + _UltimateGps.printf("$PMTK314,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29\r\n"); //GPRMC, GPGGA, and GPGSA } void GPS::Sleep(int sleep) @@ -148,8 +268,24 @@ } else { - _UltimateGps.printf("$$PMTK161,1*28\r\n"); //wake up - _UltimateGps.printf("$PMTK220,200*2C\r\n"); //5 Hz udpate - _UltimateGps.printf("$PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*28\r\n"); + _UltimateGps.printf("$$PMTK161,1*28\r\n"); //wake up + + /*unit goes back to default config when put to sleep*/ + + //Note: SBAS can only be enabled when update rate is less than or equal to 5Hz. + //_UltimateGps.printf("$PMTK220,100*2F\r\n"); //10 Hz update + _UltimateGps.printf("$PMTK220,200*2C\r\n"); //5 Hz udpate + //_UltimateGps.printf("$PMTK220,1000*1f\r\n"); //1 Hz udpate + + _UltimateGps.printf("$PMTK225,0*2bt\r\n"); //disable always locate (datasheet indicates that this negatively affects accuracy) + _UltimateGps.printf("$PMTK301,2*2et\r\n"); //set DGPS to use WAAS + + //_UltimateGps.printf("$PMTK386,0.8*35\r\n"); //set Nav Speed threshold to 0.8 m/s + //_UltimateGps.printf("$PMTK386,0.2*3f\r\n"); //set Nav Speed threshold to 0.2 m/s + _UltimateGps.printf("$PMTK386,0*23\r\n"); //disable Nav Speed threshold + + //_UltimateGps.printf("$PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*28\r\n"); //GPRMC and GPGGA + //_UltimateGps.printf("$PMTK314,0,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0*28\r\n"); //GPRMC and GPGSA + _UltimateGps.printf("$PMTK314,0,1,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29\r\n"); //GPRMC, GPGGA, and GPGSA } }
--- a/GPS.h Sun Apr 05 01:41:34 2015 +0000 +++ b/GPS.h Tue Apr 07 03:49:28 2015 +0000 @@ -34,8 +34,6 @@ public: GPS(PinName tx, PinName rx); - void Init(); - void Sleep(int sleep); int parseData(); float time; // UTC time int hours; @@ -56,7 +54,21 @@ string fix; string cardinal; float kph; - + + //added by Ryan + int getGPRMC(); + int getGPGSA(); + int getGPGGA(); + void Init(); + void Sleep(int sleep); + void coldStart(); + char mode; //manual or automatic + int status; //same as fixtype + float PDOP; //Position Dilution of Precision + float HDOP; //Horizontal Dilution of Precision + float VDOP; //Vertical Dilution of Precision + double degLat; //degrees latitude + double degLon; //degrees longitude private: float trunc ( float v);