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.
Dependencies: mbed BufferedSerial Servo2 PCT2075 I2CEeprom FastPWM
Diff: gps_mod.cpp
- Revision:
- 3:43cb067ecd00
- Child:
- 4:28cc0cf01570
diff -r 8e7b51353f32 -r 43cb067ecd00 gps_mod.cpp
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/gps_mod.cpp Mon Jul 27 08:44:59 2020 +0000
@@ -0,0 +1,265 @@
+#include "mbed.h"
+
+#ifdef GPS_
+
+#include "mbed.h"
+#include "gps_mod.h"
+using namespace std;
+#if defined (TARGET_NUCLEO_L476RG) // Computer is low power ARM Cortex development system
+#include "BufferedSerial.h"
+ BufferedSerial gps_module (A0, A1);
+#endif
+#if defined (TARGET_DISCO_F746NG) // Computer is high-end ARM Cortex development system with touch lcd
+#include "BufferedSoftSerial.h"
+ BufferedSoftSerial gps_module (A4, A5);
+#endif
+#ifdef TARGET_NUCLEO_L432KC
+#include "BufferedSerial.h"
+ extern BufferedSerial gps_module;
+#endif
+gps_mod::gps_mod() // Constructor
+{
+//BufferedSoftSerial gps_module (_pinTx : A0, _pinRx : A1);
+ state = WAITING4DOLLAR;
+ destptr = dest;
+ strcpy (latstr, "Invalid\0");
+ strcpy (longstr, "Invalid\0");
+ strcpy (altistr, "Invalid\0");
+ strcpy (timestr, "??:??:??\0");
+ chcnt = 0;
+ inmsg = false;
+ newdata = false;
+ posfix[0] = 'x';
+ posfix[1] = 0;
+ return;
+}
+
+bool gps_mod::new_data() {
+ bool r;
+ r = newdata;
+ newdata = false;
+ return r;
+}
+
+bool gps_mod::fix_valid()
+{
+ if (posfix[0] < '1' || posfix[0] > '3') return false;
+ return true;
+}
+
+char * gps_mod::date () {
+ return datestr;
+}
+
+char * gps_mod::heading () {
+ return headingstr;
+}
+
+char * gps_mod::mph () {
+ return speed_mphourstr;
+}
+
+char * gps_mod::position_fix_indicator ()
+{
+ return posfix;
+}
+
+char * gps_mod::latitude()
+{
+ if (fix_valid()) return latstr;
+ return "No Fix ";
+}
+
+char * gps_mod::longitude()
+{
+ if (fix_valid()) return longstr;
+ return "No Fix ";
+}
+
+char * gps_mod::altitude()
+{
+ if (fix_valid()) return altistr;
+ return "No Fix ";
+}
+
+char * gps_mod::sat_count ()
+{
+ return numofsats;
+}
+
+char * gps_mod::message(int mess_num)
+{
+ if (mess_num < 0 || mess_num > 5)
+ return NULL;
+ return dest + mess_num * (MAXMSGLEN + 4);
+}
+
+char * gps_mod::time ()
+{
+// char * t = message(0);
+ return timestr;
+}
+
+double gps_mod::lat_merged ()
+{
+ double result = strtod (latstr, NULL);
+ return result + (strtod (latstr + 3, NULL) / 60.0);
+}
+
+double gps_mod::lon_merged ()
+{
+ double result = strtod (longstr, NULL);
+ return result + (strtod (longstr + 4, NULL) / 60.0);
+}
+
+int gps_mod::update()
+{
+ static const char month_tab[] = "---\0Jan\0Feb\0Mar\0Apr\0May\0Jun\0Jul\0Aug\0Sep\0Oct\0Nov\0Dec\0";
+ const int MAX_COMMAS_IN_MSG = 24;
+ int date, month;
+ while (gps_module.readable()) {
+ ch = gps_module.getc();
+ switch (state) {
+ case WAITING4DOLLAR:
+ i = 0;
+ if (ch == '$') state = GOTDOLLAR;
+ break;
+ case GOTDOLLAR: // accumulate 5 chars after '$'
+ hdracc[i++] = ch;
+ hdracc[i] = 0;
+ if (i > 4) {
+ i = -1;
+ state = GOTHDR;
+ }
+ break;
+ case GOTHDR: // have read "$GP???" to get here
+// if (ch != ',') pc.printf ("Oops, comma missing\r\n");
+ if (strncmp(hdracc,"GPGGA",5) == 0) i = 0;
+ else if (strncmp(hdracc,"GPGLL",5) == 0) i = 1;
+ else if (strncmp(hdracc,"GPGSA",5) == 0) i = 2;
+ else if (strncmp(hdracc,"GPGSV",5) == 0) i = 3;
+ else if (strncmp(hdracc,"GPRMC",5) == 0) i = 4;//161229.487,A,3723.24756, N,12158.34162,W, 0.13, 309.62, 120598,,*10
+ // time ? lat lon ground speed knots|heading|date
+ else if (strncmp(hdracc,"GPVTG",5) == 0) i = 5;
+ if (i < 0) state = WAITING4DOLLAR; // Found invalid header info
+ else { // Validated header info
+ destptr = message(i);
+ chcnt = 0;
+ state = WAITING4CR;
+ }
+ break;
+ case WAITING4CR:
+ if (ch == '\r') {
+ state = WAITING4LF; // process new string data here
+ int comma_count = 0, comma_positions[MAX_COMMAS_IN_MSG + 2];
+ for (int j = 0; j < strlen(destptr) && j < MAXMSGLEN && comma_count < MAX_COMMAS_IN_MSG; j++) {
+ if (destptr[j] == ',') {
+ comma_positions[comma_count++] = j;
+ comma_positions[comma_count] = 0;
+ }
+ }
+ switch (i) {
+ case 0: // GGA 183655.00,5110.25620,N,00320.09926,W,1,11,0.80,59.9,M,49.5,M,,*74
+ if (comma_positions[0] == 9) { // time data seems to exist
+ timestr[0] = dest[0];
+ timestr[1] = dest[1];
+ timestr[2] = ':';
+ timestr[3] = dest[2];
+ timestr[4] = dest[3];
+ timestr[5] = ':';
+ timestr[6] = dest[4];
+ timestr[7] = dest[5];
+ timestr[8] = 0;
+ } else {
+ strcpy (timestr, "Invalid");
+ }
+ posfix[0] = dest[comma_positions[4] + 1];
+ if (fix_valid()) {
+ int a = 0, b = comma_positions[5] + 1; // get numof sats
+ if (dest[b] == ',') {
+ numofsats[0] = '-';
+ numofsats[1] = '-';
+ }
+ else {
+ numofsats[0] = dest[b++];
+ numofsats[1] = dest[b++];
+ }
+ b = comma_positions[7] + 1; // get altitude
+ char c;
+ while ((c = dest[b++]) != ',' && a < 7)
+ altistr[a++] = c;
+ altistr[a] = 0;
+ }
+ numofsats[2] = 0;
+ break;
+ case 1: // GLL 5110.25606,N,00320.10001,W,183752.00,A,A*72
+ latstr[0] = destptr[0];
+ latstr[1] = destptr[1];
+ latstr[2] = '~';
+ latstr[3] = destptr[2];
+ latstr[4] = destptr[3];
+ latstr[5] = '.';
+ for (int k = 5; k < 10; k++)
+ latstr[k + 1] = destptr[k];
+ latstr[11] = ' ';
+ latstr[12] = destptr[11]; // N or S
+ latstr[13] = 0;
+ for (int k = 0; k < 3; k++)
+ longstr[k] = destptr[k + 13];
+ longstr[3] = '~';
+ longstr[4] = destptr[16];
+ longstr[5] = destptr[17];
+ longstr[6] = '.';
+ for (int k = 7; k < 12; k++)
+ longstr[k] = destptr[k + 12];
+ longstr[12] = ' ';
+ longstr[13] = destptr[25]; // E or W
+ longstr[14] = 0;
+ break;
+ case 2: // GSA A,3,11,22,01,03,17,23,19,14,09,,,,1.72,0.97,1.42*0E
+ break;
+ case 3: // GSV complex multiple
+ break; // 0 1 2 3 4 5 67
+ case 4: // RMC 184111.00, A,5110.25663, N,00320.10076,W, 0.223, , 090816,,,A*6B
+// // 161229.487,A,3723.24756, N,12158.34162,W, 0.13, 309.62, 120598,,*10
+// time ? lat lon ground speed knots|heading|date
+ if (comma_positions[6] + 1 == comma_positions[7]) // no heading data exists
+ strcpy (headingstr, "-/-");
+ else
+ sprintf(headingstr, "%.1f", strtod(destptr + comma_positions[6] + 1, NULL));
+// pc.printf("%s ^%s^", destptr, headingstr);
+ date = (destptr[comma_positions[7] + 1] - '0') * 10 + (destptr[comma_positions[7] + 2] - '0');
+ month = (destptr[comma_positions[7] + 3] - '0') * 10 + (destptr[comma_positions[7] + 4] - '0');
+ if (month > 12 || month < 1)
+ month = 0;
+ month *= 4;
+ sprintf (datestr, "%d %s 20%d", date, &month_tab[month], strtol(&destptr[comma_positions[7] + 5], NULL, 10));
+ break;
+ case 5: // VTG ,T , ,M,0.098,N,0.181,K,A*2A course over ground and ground speed
+//$ GPVTG 309.62,T , ,M,0.13, N,0.2, K*6E
+ sprintf (speed_mphourstr, "%.1fmph", km2miles * strtod(destptr + comma_positions[5] + 1, NULL));
+ newdata = true;
+ break; // course true|course magnetic|knots|km/hour
+ default:
+// pc.printf ("Naf i = %d\r\n", i);
+ break;
+ }
+ } else { // char is not CR
+ if (chcnt > MAXMSGLEN) chcnt = MAXMSGLEN;
+ destptr[chcnt++] = ch;
+ destptr[chcnt] = 0;
+ }
+ break;
+ case WAITING4LF:
+// if (ch != '\n')
+// pc.printf ("Oops, no LF\r\n");
+ state = WAITING4DOLLAR;
+ break;
+ default:
+ break;
+ }
+ }
+ return 0;
+} // end of int gps_mod::update()
+
+#endif