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

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers gps_mod.cpp Source File

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