Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
GPSINT.cpp
00001 /* GPSINT.cpp 00002 * Original program from 00003 * jbradshaw (20141101) 00004 * The program is modified for ublox NEO 6M. 00005 */ 00006 00007 #include "GPSINT.h" 00008 00009 GPSINT::GPSINT(PinName tx, PinName rx) : _gps(tx, rx) { 00010 _gps.baud(9600); 00011 GPSidx=0; // Index for GPS buffer 00012 GPSstate=0; // Used to wait for '$' in GPS interrupt 00013 _gps.attach(this,&GPSINT::GPSSerialRecvInterrupt, _gps.RxIrq); // Recv interrupt handler 00014 } 00015 00016 int GPSINT::nmea_validate(char *nmeastr){ 00017 char check[3]; 00018 char checkcalcstr[3]; 00019 int i; 00020 int calculated_check; 00021 00022 i=0; 00023 calculated_check=0; 00024 00025 // check to ensure that the string starts with a $ 00026 if(nmeastr[i] == '$') 00027 i++; 00028 else 00029 return 0; 00030 00031 //No NULL reached, 75 char largest possible NMEA message, no '*' reached 00032 while((nmeastr[i] != 0) && (nmeastr[i] != '*') && (i < 75)){ 00033 calculated_check ^= nmeastr[i];// calculate the checksum 00034 i++; 00035 } 00036 00037 if(i >= 75){ 00038 return 0;// the string was too long so return an error 00039 } 00040 00041 if (nmeastr[i] == '*'){ 00042 check[0] = nmeastr[i+1]; //put hex chars in check string 00043 check[1] = nmeastr[i+2]; 00044 check[2] = 0; 00045 } 00046 else 00047 return 0;// no checksum separator found therefor invalid 00048 00049 sprintf(checkcalcstr,"%02X",calculated_check); 00050 return((checkcalcstr[0] == check[0]) 00051 && (checkcalcstr[1] == check[1])) ? 1 : 0 ; 00052 } 00053 00054 void GPSINT::parseGPSString(char *GPSstrParse){ 00055 //check if $GPGGA string 00056 if(!strncmp(GPSstrParse, "$GPGGA", 6)){ 00057 if (sscanf(GPSstrParse, "$GPGGA,%f,%f,%c,%f,%c,%d,%d,%f,%f,%c", &utc_time, &nmea_latitude, &ns, &nmea_longitude, &ew, &lock, &satelites, &hdop, &msl_altitude, &msl_units) >= 1) { 00058 // printf("%s", GPSstrParse); 00059 return; 00060 } 00061 else{ 00062 // printf("BAD parse %s", GPSstrParse); 00063 } 00064 } 00065 // Check if $GPRMC string 00066 else if (!strncmp(GPSstrParse, "$GPRMC", 6)){ 00067 if(sscanf(GPSstrParse, "$GPRMC,%f,%c,%f,%c,%f,%c,%f,%f,%d", &utc_time, &status,&nmea_latitude, &ns, &nmea_longitude, &ew, &speed_k, &course_d, &date) >= 1) { 00068 // printf("%s", GPSstrParse); 00069 return; 00070 } 00071 else{ 00072 // printf("BAD parse %s", GPSstrParse); 00073 } 00074 } 00075 // GLL - Geographic Position-Lat/Lon 00076 else if (!strncmp(GPSstrParse, "$GPGLL", 6)){ 00077 if(sscanf(GPSstrParse, "$GPGLL,%f,%c,%f,%c,%f,%c", &nmea_latitude, &ns, &nmea_longitude, &ew, &utc_time, &gll_status) >= 1) { 00078 // printf("%s", GPSstrParse); 00079 return; 00080 } 00081 else{ 00082 // printf("BAD parse %s", GPSstrParse); 00083 } 00084 } 00085 // VTG-Course Over Ground and Ground Speed 00086 else if (!strncmp(GPSstrParse, "$GPVTG", 6)){ 00087 if(sscanf(GPSstrParse, "$GPVTG,%f,%c,%f,%c,%f,%c,%f,%c", &course_t, &course_t_unit, &course_m, &course_m_unit, &speed_k, &speed_k_unit, &speed_km, &speed_km_unit) >= 1) { 00088 // printf("%s", GPSstrParse); 00089 return; 00090 } 00091 else{ 00092 // printf("BAD parse %s", GPSstrParse); 00093 } 00094 } 00095 }//parseGPSstring() 00096 00097 void GPSINT::GPSSerialRecvInterrupt(void) 00098 { 00099 char c; 00100 c =_gps.getc(); // On receive interrupt, get the character. 00101 // pc.printf("%c", c); 00102 00103 switch(GPSstate){ 00104 case 0: 00105 if(c =='$'){ 00106 GPSidx=0; 00107 Temp_GPSbuf[GPSidx] = c; //load char in current idx of array 00108 GPSidx++; 00109 GPSstate = 1; 00110 } 00111 break; 00112 case 1: 00113 Temp_GPSbuf[GPSidx] = c; //load char in current idx of array 00114 GPSidx++; 00115 if(c == '\n'){ //if last char was a newline 00116 Temp_GPSbuf[GPSidx] = '\0'; //append a NULL 00117 strcpy(GPSbuf, Temp_GPSbuf); //copy temp buf into GPS buf 00118 GPSidx=0; //reset index 00119 GPSstate = 0; //reset GPS state 00120 if(nmea_validate(GPSbuf)){ 00121 parseGPSString(GPSbuf); 00122 } 00123 } 00124 break; 00125 00126 default: 00127 break; 00128 00129 }//switch state 00130 } 00131 00132 float GPSINT::nmea_to_dec(float deg_coord, char nsew) { 00133 int degree = (int)(deg_coord/100); 00134 float minutes = deg_coord - degree*100; 00135 float dec_deg = minutes / 60; 00136 float decimal = degree + dec_deg; 00137 if (nsew == 'S' || nsew == 'W') { // return negative 00138 decimal *= -1; 00139 } 00140 return decimal; 00141 } 00142 00143 // NAVIGATION FUNCTIONS //////////////////////////////////////////////////////////// 00144 float GPSINT::calc_course_to(float pointLat, float pontLong) { 00145 const double d2r = PI / 180.0; 00146 const double r2d = 180.0 / PI; 00147 double dlat = abs(pointLat - dec_latitude) * d2r; 00148 double dlong = abs(pontLong - dec_longitude) * d2r; 00149 double y = sin(dlong) * cos(pointLat * d2r); 00150 double x = cos(dec_latitude*d2r)*sin(pointLat*d2r) - sin(dec_latitude*d2r)*cos(pointLat*d2r)*cos(dlong); 00151 return atan2(y,x)*r2d; 00152 } 00153 00154 /* 00155 var y = Math.sin(dLon) * Math.cos(lat2); 00156 var x = Math.cos(lat1)*Math.sin(lat2) - 00157 Math.sin(lat1)*Math.cos(lat2)*Math.cos(dLon); 00158 var brng = Math.atan2(y, x).toDeg(); 00159 */ 00160 00161 /* 00162 The Haversine formula according to Dr. Math. 00163 http://mathforum.org/library/drmath/view/51879.html 00164 00165 dlon = lon2 - lon1 00166 dlat = lat2 - lat1 00167 a = (sin(dlat/2))^2 + cos(lat1) * cos(lat2) * (sin(dlon/2))^2 00168 c = 2 * atan2(sqrt(a), sqrt(1-a)) 00169 d = R * c 00170 00171 Where 00172 * dlon is the change in longitude 00173 * dlat is the change in latitude 00174 * c is the great circle distance in Radians. 00175 * R is the radius of a spherical Earth. 00176 * The locations of the two points in 00177 spherical coordinates (longitude and 00178 latitude) are lon1,lat1 and lon2, lat2. 00179 */ 00180 double GPSINT::calc_dist_to_mi(float pointLat, float pontLong) { 00181 const double d2r = PI / 180.0; 00182 double dlat = pointLat - dec_latitude; 00183 double dlong = pontLong - dec_longitude; 00184 double a = pow(sin(dlat/2.0),2.0) + cos(dec_latitude*d2r) * cos(pointLat*d2r) * pow(sin(dlong/2.0),2.0); 00185 double c = 2.0 * asin(sqrt(abs(a))); 00186 double d = 63.765 * c; 00187 00188 return d; 00189 } 00190 00191 double GPSINT::calc_dist_to_ft(float pointLat, float pontLong) { 00192 return calc_dist_to_mi(pointLat, pontLong)*5280.0; 00193 } 00194 00195 double GPSINT::calc_dist_to_km(float pointLat, float pontLong) { 00196 return calc_dist_to_mi(pointLat, pontLong)*1.609344; 00197 } 00198 00199 double GPSINT::calc_dist_to_m(float pointLat, float pontLong) { 00200 return calc_dist_to_mi(pointLat, pontLong)*1609.344; 00201 }
Generated on Sat Aug 13 2022 08:11:32 by
1.7.2