Code for 'Smart Regulator' featured in 'Model Engineer', November 2020 on. Contains all work to August 2020 including all code described. Top level algorithm development is quite spares, leaving some work for you! Any questions - jon@jons-workshop.com
Dependencies: mbed BufferedSerial Servo2 PCT2075 I2CEeprom FastPWM
gps_mod.cpp
00001 #include "mbed.h" 00002 00003 //#ifdef GPS_ 00004 00005 #include "mbed.h" 00006 #include "gps_mod.h" 00007 using namespace std; 00008 #if defined (TARGET_NUCLEO_L476RG) // Computer is low power ARM Cortex development system 00009 #include "BufferedSerial.h" 00010 BufferedSerial gps_module (A0, A1); 00011 #endif 00012 #if defined (TARGET_DISCO_F746NG) // Computer is high-end ARM Cortex development system with touch lcd 00013 #include "BufferedSoftSerial.h" 00014 BufferedSoftSerial gps_module (A4, A5); 00015 #endif 00016 #ifdef TARGET_NUCLEO_L432KC 00017 #include "BufferedSerial.h" 00018 extern BufferedSerial gps_module; 00019 #endif 00020 gps_mod::gps_mod() // Constructor 00021 { 00022 //BufferedSoftSerial gps_module (_pinTx : A0, _pinRx : A1); 00023 state = WAITING4DOLLAR; 00024 destptr = dest; 00025 strcpy (latstr, "Invalid\0"); 00026 strcpy (longstr, "Invalid\0"); 00027 strcpy (altistr, "Invalid\0"); 00028 strcpy (timestr, "??:??:??\0"); 00029 chcnt = 0; 00030 inmsg = false; 00031 newdata = false; 00032 posfix[0] = 'x'; 00033 posfix[1] = 0; 00034 return; 00035 } 00036 00037 bool gps_mod::new_data() { 00038 bool r; 00039 r = newdata; 00040 newdata = false; 00041 return r; 00042 } 00043 00044 bool gps_mod::fix_valid() 00045 { 00046 if (posfix[0] < '1' || posfix[0] > '3') return false; 00047 return true; 00048 } 00049 00050 char * gps_mod::date () { 00051 return datestr; 00052 } 00053 00054 char * gps_mod::heading () { 00055 return headingstr; 00056 } 00057 00058 char * gps_mod::mph () { 00059 return speed_mphourstr; 00060 } 00061 00062 char * gps_mod::position_fix_indicator () 00063 { 00064 return posfix; 00065 } 00066 00067 char * gps_mod::latitude() 00068 { 00069 if (fix_valid()) return latstr; 00070 return "No Fix "; 00071 } 00072 00073 char * gps_mod::longitude() 00074 { 00075 if (fix_valid()) return longstr; 00076 return "No Fix "; 00077 } 00078 00079 char * gps_mod::altitude() 00080 { 00081 if (fix_valid()) return altistr; 00082 return "No Fix "; 00083 } 00084 00085 char * gps_mod::sat_count () 00086 { 00087 return numofsats; 00088 } 00089 00090 char * gps_mod::message(int mess_num) 00091 { 00092 if (mess_num < 0 || mess_num > 5) 00093 return NULL; 00094 return dest + mess_num * (MAXMSGLEN + 4); 00095 } 00096 00097 char * gps_mod::time () 00098 { 00099 // char * t = message(0); 00100 return timestr; 00101 } 00102 00103 double gps_mod::lat_merged () 00104 { 00105 double result = strtod (latstr, NULL); 00106 return result + (strtod (latstr + 3, NULL) / 60.0); 00107 } 00108 00109 double gps_mod::lon_merged () 00110 { 00111 double result = strtod (longstr, NULL); 00112 return result + (strtod (longstr + 4, NULL) / 60.0); 00113 } 00114 00115 int gps_mod::update() 00116 { 00117 static const char month_tab[] = "---\0Jan\0Feb\0Mar\0Apr\0May\0Jun\0Jul\0Aug\0Sep\0Oct\0Nov\0Dec\0"; 00118 const int MAX_COMMAS_IN_MSG = 24; 00119 int date, month; 00120 while (gps_module.readable()) { 00121 ch = gps_module.getc(); 00122 switch (state) { 00123 case WAITING4DOLLAR: 00124 i = 0; 00125 if (ch == '$') state = GOTDOLLAR; 00126 break; 00127 case GOTDOLLAR: // accumulate 5 chars after '$' 00128 hdracc[i++] = ch; 00129 hdracc[i] = 0; 00130 if (i > 4) { 00131 i = -1; 00132 state = GOTHDR; 00133 } 00134 break; 00135 case GOTHDR: // have read "$GP???" to get here 00136 // if (ch != ',') pc.printf ("Oops, comma missing\r\n"); 00137 if (strncmp(hdracc,"GPGGA",5) == 0) i = 0; 00138 else if (strncmp(hdracc,"GPGLL",5) == 0) i = 1; 00139 else if (strncmp(hdracc,"GPGSA",5) == 0) i = 2; 00140 else if (strncmp(hdracc,"GPGSV",5) == 0) i = 3; 00141 else if (strncmp(hdracc,"GPRMC",5) == 0) i = 4;//161229.487,A,3723.24756, N,12158.34162,W, 0.13, 309.62, 120598,,*10 00142 // time ? lat lon ground speed knots|heading|date 00143 else if (strncmp(hdracc,"GPVTG",5) == 0) i = 5; 00144 if (i < 0) state = WAITING4DOLLAR; // Found invalid header info 00145 else { // Validated header info 00146 destptr = message(i); 00147 chcnt = 0; 00148 state = WAITING4CR; 00149 } 00150 break; 00151 case WAITING4CR: 00152 if (ch == '\r') { 00153 state = WAITING4LF; // process new string data here 00154 int comma_count = 0, comma_positions[MAX_COMMAS_IN_MSG + 2]; 00155 for (int j = 0; j < strlen(destptr) && j < MAXMSGLEN && comma_count < MAX_COMMAS_IN_MSG; j++) { 00156 if (destptr[j] == ',') { 00157 comma_positions[comma_count++] = j; 00158 comma_positions[comma_count] = 0; 00159 } 00160 } 00161 switch (i) { 00162 case 0: // GGA 183655.00,5110.25620,N,00320.09926,W,1,11,0.80,59.9,M,49.5,M,,*74 00163 if (comma_positions[0] == 9) { // time data seems to exist 00164 timestr[0] = dest[0]; 00165 timestr[1] = dest[1]; 00166 timestr[2] = ':'; 00167 timestr[3] = dest[2]; 00168 timestr[4] = dest[3]; 00169 timestr[5] = ':'; 00170 timestr[6] = dest[4]; 00171 timestr[7] = dest[5]; 00172 timestr[8] = 0; 00173 } else { 00174 strcpy (timestr, "Invalid"); 00175 } 00176 posfix[0] = dest[comma_positions[4] + 1]; 00177 if (fix_valid()) { 00178 int a = 0, b = comma_positions[5] + 1; // get numof sats 00179 if (dest[b] == ',') { 00180 numofsats[0] = '-'; 00181 numofsats[1] = '-'; 00182 } 00183 else { 00184 numofsats[0] = dest[b++]; 00185 numofsats[1] = dest[b++]; 00186 } 00187 b = comma_positions[7] + 1; // get altitude 00188 char c; 00189 while ((c = dest[b++]) != ',' && a < 7) 00190 altistr[a++] = c; 00191 altistr[a] = 0; 00192 } 00193 numofsats[2] = 0; 00194 break; 00195 case 1: // GLL 5110.25606,N,00320.10001,W,183752.00,A,A*72 00196 latstr[0] = destptr[0]; 00197 latstr[1] = destptr[1]; 00198 latstr[2] = '~'; 00199 latstr[3] = destptr[2]; 00200 latstr[4] = destptr[3]; 00201 latstr[5] = '.'; 00202 for (int k = 5; k < 10; k++) 00203 latstr[k + 1] = destptr[k]; 00204 latstr[11] = ' '; 00205 latstr[12] = destptr[11]; // N or S 00206 latstr[13] = 0; 00207 for (int k = 0; k < 3; k++) 00208 longstr[k] = destptr[k + 13]; 00209 longstr[3] = '~'; 00210 longstr[4] = destptr[16]; 00211 longstr[5] = destptr[17]; 00212 longstr[6] = '.'; 00213 for (int k = 7; k < 12; k++) 00214 longstr[k] = destptr[k + 12]; 00215 longstr[12] = ' '; 00216 longstr[13] = destptr[25]; // E or W 00217 longstr[14] = 0; 00218 break; 00219 case 2: // GSA A,3,11,22,01,03,17,23,19,14,09,,,,1.72,0.97,1.42*0E 00220 break; 00221 case 3: // GSV complex multiple 00222 break; // 0 1 2 3 4 5 67 00223 case 4: // RMC 184111.00, A,5110.25663, N,00320.10076,W, 0.223, , 090816,,,A*6B 00224 // // 161229.487,A,3723.24756, N,12158.34162,W, 0.13, 309.62, 120598,,*10 00225 // time ? lat lon ground speed knots|heading|date 00226 if (comma_positions[6] + 1 == comma_positions[7]) // no heading data exists 00227 strcpy (headingstr, "-/-"); 00228 else 00229 sprintf(headingstr, "%.1f", strtod(destptr + comma_positions[6] + 1, NULL)); 00230 // pc.printf("%s ^%s^", destptr, headingstr); 00231 date = (destptr[comma_positions[7] + 1] - '0') * 10 + (destptr[comma_positions[7] + 2] - '0'); 00232 month = (destptr[comma_positions[7] + 3] - '0') * 10 + (destptr[comma_positions[7] + 4] - '0'); 00233 if (month > 12 || month < 1) 00234 month = 0; 00235 month *= 4; 00236 sprintf (datestr, "%d %s 20%d", date, &month_tab[month], strtol(&destptr[comma_positions[7] + 5], NULL, 10)); 00237 break; 00238 case 5: // VTG ,T , ,M,0.098,N,0.181,K,A*2A course over ground and ground speed 00239 //Adafruit $GPVTG,165.48,T,,M,0.03,N,0.06,K,A*37 00240 //$ GPVTG 309.62,T , ,M,0.13, N,0.2, K*6E 00241 sprintf (speed_mphourstr, "%.1fmph", km2miles * strtod(destptr + comma_positions[5] + 1, NULL)); 00242 newdata = true; 00243 break; // course true|course magnetic|knots|km/hour 00244 default: 00245 // pc.printf ("Naf i = %d\r\n", i); 00246 break; 00247 } 00248 } else { // char is not CR 00249 if (chcnt > MAXMSGLEN) chcnt = MAXMSGLEN; 00250 destptr[chcnt++] = ch; 00251 destptr[chcnt] = 0; 00252 } 00253 break; 00254 case WAITING4LF: 00255 // if (ch != '\n') 00256 // pc.printf ("Oops, no LF\r\n"); 00257 state = WAITING4DOLLAR; 00258 break; 00259 default: 00260 break; 00261 } 00262 } 00263 return 0; 00264 } // end of int gps_mod::update() 00265 00266 //#endif
Generated on Fri Jul 22 2022 15:22:19 by
1.7.2