GPS NMEA sentence reader for Nucleo boards.

Dependencies:   mbed MODSERIAL

I had a lot of trouble getting other GPS examples to work. So I took Edoardo De Marchi's code from 2014 and hacked it until it was working on newer hardware.

Advice:

  • Start with confirming the module works in U-Center, and know the baud rate. Many older libraries assume 9600. Newer modules run at higher baud rates
  • Use a good terminal program and confirm you have human readable messages starting with "$GNGGA" or "$GPGSV" or similar.

Comments in code include links to NMEA sentence guides:

Most libraries do not include sentence filters for the types of sentences output by my M8N (and perhaps other modules as well)

Most older versions of the MODSERIAL library do not update properly to support STM32. I have found and included a version of the lib which will compile without errors. However, when using it in my code, the NMEA sentence gets corrupted somehow (for example showing some HUGE [6 digit] Satellite count, etc.

Committer:
epremeaux
Date:
Thu Jul 04 04:12:41 2019 +0000
Revision:
2:c16325a7d225
Parent:
1:acd907fbcbae
U-Blox-M8N GPS example for Nucleo-F401RE. Decodes additional NMEA sentences

Who changed what in which revision?

UserRevisionLine numberNew contents of line
edodm85 0:ea14ad6794af 1 /*
edodm85 0:ea14ad6794af 2 * Author: Edoardo De Marchi
edodm85 1:acd907fbcbae 3 * Date: 22-08-14
edodm85 0:ea14ad6794af 4 * Notes: Firmware for GPS U-Blox NEO-6M
epremeaux 2:c16325a7d225 5 *
epremeaux 2:c16325a7d225 6 * Modified: Emery Premeaux
epremeaux 2:c16325a7d225 7 * Date: July 2019
epremeaux 2:c16325a7d225 8 * Written for: Nucleo F401RE & NEO-M8N
epremeaux 2:c16325a7d225 9 *
epremeaux 2:c16325a7d225 10 * Updated MODSERIAL library now compiles without errors but data seems corrupted.
epremeaux 2:c16325a7d225 11 *
epremeaux 2:c16325a7d225 12 * NMEA sentences: https://www.gpsinformation.org/dale/nmea.htm#nmea
epremeaux 2:c16325a7d225 13 *
edodm85 0:ea14ad6794af 14 */
edodm85 0:ea14ad6794af 15
epremeaux 2:c16325a7d225 16 #include "mbed.h"
epremeaux 2:c16325a7d225 17 //#include "MODSERIAL.h"
epremeaux 2:c16325a7d225 18
epremeaux 2:c16325a7d225 19 //MODSERIAL pc(USBTX,USBRX);
epremeaux 2:c16325a7d225 20 //MODSERIAL gps(D8, D2);
epremeaux 2:c16325a7d225 21
epremeaux 2:c16325a7d225 22 Serial pc(USBTX,USBRX);
epremeaux 2:c16325a7d225 23 Serial gps(D8, D2);
epremeaux 2:c16325a7d225 24
epremeaux 2:c16325a7d225 25 char cDataBuffer[500];
epremeaux 2:c16325a7d225 26 int i = 0;
epremeaux 2:c16325a7d225 27 int h_time,m_time,s_time;
epremeaux 2:c16325a7d225 28
epremeaux 2:c16325a7d225 29 void Init();
epremeaux 2:c16325a7d225 30 void parse(char *cmd, int n);
epremeaux 2:c16325a7d225 31 void parseTime (float timeval);
edodm85 0:ea14ad6794af 32
edodm85 0:ea14ad6794af 33
edodm85 0:ea14ad6794af 34 void Init()
edodm85 0:ea14ad6794af 35 {
epremeaux 2:c16325a7d225 36 gps.baud(115200);
epremeaux 2:c16325a7d225 37 pc.baud(115200);
edodm85 0:ea14ad6794af 38 pc.printf("Init OK\n");
edodm85 0:ea14ad6794af 39 }
edodm85 0:ea14ad6794af 40
edodm85 0:ea14ad6794af 41
edodm85 0:ea14ad6794af 42
edodm85 0:ea14ad6794af 43 int main()
edodm85 0:ea14ad6794af 44 {
edodm85 0:ea14ad6794af 45 Init();
edodm85 0:ea14ad6794af 46 char c;
edodm85 0:ea14ad6794af 47
edodm85 0:ea14ad6794af 48 while(true)
edodm85 0:ea14ad6794af 49 {
edodm85 0:ea14ad6794af 50 if(gps.readable())
edodm85 0:ea14ad6794af 51 {
edodm85 0:ea14ad6794af 52 if(gps.getc() == '$'); // wait a $
edodm85 0:ea14ad6794af 53 {
edodm85 0:ea14ad6794af 54 for(int i=0; i<sizeof(cDataBuffer); i++)
edodm85 0:ea14ad6794af 55 {
edodm85 0:ea14ad6794af 56 c = gps.getc();
edodm85 0:ea14ad6794af 57 if( c == '\r' )
edodm85 0:ea14ad6794af 58 {
edodm85 0:ea14ad6794af 59 //pc.printf("%s\n", cDataBuffer);
edodm85 0:ea14ad6794af 60 parse(cDataBuffer, i);
edodm85 0:ea14ad6794af 61 i = sizeof(cDataBuffer);
edodm85 0:ea14ad6794af 62 }
edodm85 0:ea14ad6794af 63 else
edodm85 0:ea14ad6794af 64 {
edodm85 0:ea14ad6794af 65 cDataBuffer[i] = c;
edodm85 0:ea14ad6794af 66 }
edodm85 0:ea14ad6794af 67 }
edodm85 0:ea14ad6794af 68 }
edodm85 0:ea14ad6794af 69 }
edodm85 0:ea14ad6794af 70 }
edodm85 0:ea14ad6794af 71 }
edodm85 0:ea14ad6794af 72
epremeaux 2:c16325a7d225 73 /*
epremeaux 2:c16325a7d225 74 * NMEA sentences: https://www.gpsinformation.org/dale/nmea.htm#nmea
epremeaux 2:c16325a7d225 75 * http://navspark.mybigcommerce.com/content/NMEA_Format_v0.1.pdf
epremeaux 2:c16325a7d225 76 */
edodm85 0:ea14ad6794af 77 void parse(char *cmd, int n)
epremeaux 2:c16325a7d225 78 {
edodm85 0:ea14ad6794af 79 char ns, ew, tf, status;
edodm85 0:ea14ad6794af 80 int fq, nst, fix, date; // fix quality, Number of satellites being tracked, 3D fix
edodm85 0:ea14ad6794af 81 float latitude, longitude, timefix, speed, altitude;
edodm85 0:ea14ad6794af 82
edodm85 0:ea14ad6794af 83 // Global Positioning System Fix Data
edodm85 0:ea14ad6794af 84 if(strncmp(cmd,"$GPGGA", 6) == 0)
edodm85 0:ea14ad6794af 85 {
edodm85 0:ea14ad6794af 86 sscanf(cmd, "$GPGGA,%f,%f,%c,%f,%c,%d,%d,%*f,%f", &timefix, &latitude, &ns, &longitude, &ew, &fq, &nst, &altitude);
edodm85 0:ea14ad6794af 87 pc.printf("GPGGA Fix taken at: %f, Latitude: %f %c, Longitude: %f %c, Fix quality: %d, Number of sat: %d, Altitude: %f M\n", timefix, latitude, ns, longitude, ew, fq, nst, altitude);
edodm85 0:ea14ad6794af 88 }
edodm85 0:ea14ad6794af 89
edodm85 0:ea14ad6794af 90 // Satellite status
epremeaux 2:c16325a7d225 91 else if(strncmp(cmd,"$GPGSA", 6) == 0)
edodm85 0:ea14ad6794af 92 {
edodm85 0:ea14ad6794af 93 sscanf(cmd, "$GPGSA,%c,%d,%d", &tf, &fix, &nst);
edodm85 0:ea14ad6794af 94 pc.printf("GPGSA Type fix: %c, 3D fix: %d, number of sat: %d\r\n", tf, fix, nst);
edodm85 0:ea14ad6794af 95 }
edodm85 0:ea14ad6794af 96
edodm85 0:ea14ad6794af 97 // Geographic position, Latitude and Longitude
epremeaux 2:c16325a7d225 98 else if(strncmp(cmd,"$GPGLL", 6) == 0)
edodm85 0:ea14ad6794af 99 {
edodm85 0:ea14ad6794af 100 sscanf(cmd, "$GPGLL,%f,%c,%f,%c,%f", &latitude, &ns, &longitude, &ew, &timefix);
edodm85 0:ea14ad6794af 101 pc.printf("GPGLL Latitude: %f %c, Longitude: %f %c, Fix taken at: %f\n", latitude, ns, longitude, ew, timefix);
edodm85 0:ea14ad6794af 102 }
edodm85 0:ea14ad6794af 103
edodm85 0:ea14ad6794af 104 // Geographic position, Latitude and Longitude
epremeaux 2:c16325a7d225 105 else if(strncmp(cmd,"$GPRMC", 6) == 0)
edodm85 0:ea14ad6794af 106 {
edodm85 0:ea14ad6794af 107 sscanf(cmd, "$GPRMC,%f,%c,%f,%c,%f,%c,%f,,%d", &timefix, &status, &latitude, &ns, &longitude, &ew, &speed, &date);
edodm85 0:ea14ad6794af 108 pc.printf("GPRMC Fix taken at: %f, Status: %c, Latitude: %f %c, Longitude: %f %c, Speed: %f, Date: %d\n", timefix, status, latitude, ns, longitude, ew, speed, date);
edodm85 0:ea14ad6794af 109 }
epremeaux 2:c16325a7d225 110
epremeaux 2:c16325a7d225 111 //
epremeaux 2:c16325a7d225 112 else if(strncmp(cmd,"$GNVTG", 6) == 0)
epremeaux 2:c16325a7d225 113 {
epremeaux 2:c16325a7d225 114 // pc.printf("its a Vector Track message.\n");
epremeaux 2:c16325a7d225 115 }
epremeaux 2:c16325a7d225 116
epremeaux 2:c16325a7d225 117 else if(strncmp(cmd,"$GNGGA", 6) == 0)
epremeaux 2:c16325a7d225 118 {
epremeaux 2:c16325a7d225 119 sscanf(cmd, "$GNGGA,%f,%f,%c,%f,%c,%d,%d,%*f,%f", &timefix, &latitude, &ns, &longitude, &ew, &fq, &nst, &altitude);
epremeaux 2:c16325a7d225 120 pc.printf("GNGGA Fix taken at: %f, Latitude: %f %c, Longitude: %f %c, Fix quality: %d, Number of sat: %d, Altitude: %f M\n", timefix, latitude, ns, longitude, ew, fq, nst, altitude);
epremeaux 2:c16325a7d225 121 parseTime(timefix);
epremeaux 2:c16325a7d225 122 pc.printf("Time: %d:%d:%d\n", h_time, m_time, s_time);
epremeaux 2:c16325a7d225 123 }
epremeaux 2:c16325a7d225 124
epremeaux 2:c16325a7d225 125 else if(strncmp(cmd,"$GNGSA", 6) == 0)
epremeaux 2:c16325a7d225 126 {
epremeaux 2:c16325a7d225 127 sscanf(cmd, "$GNGSA,%c,%d,%d", &tf, &fix, &nst);
epremeaux 2:c16325a7d225 128 pc.printf("GNGSA Type fix: %c, 3D fix: %d, number of sat: %d\r\n", tf, fix, nst);
epremeaux 2:c16325a7d225 129 }
epremeaux 2:c16325a7d225 130
epremeaux 2:c16325a7d225 131 else if(strncmp(cmd,"$GPGSV", 6) == 0)
epremeaux 2:c16325a7d225 132 {
epremeaux 2:c16325a7d225 133 // pc.printf("its a Satellite details message.\n");
epremeaux 2:c16325a7d225 134 }
epremeaux 2:c16325a7d225 135
epremeaux 2:c16325a7d225 136 else if(strncmp(cmd,"$GNGLL", 6) == 0)
epremeaux 2:c16325a7d225 137 {
epremeaux 2:c16325a7d225 138 sscanf(cmd, "$GNGLL,%f,%c,%f,%c,%f", &latitude, &ns, &longitude, &ew, &timefix);
epremeaux 2:c16325a7d225 139 pc.printf("GNGLL Latitude: %f %c, Longitude: %f %c, Fix taken at: %f\n", latitude, ns, longitude, ew, timefix);
epremeaux 2:c16325a7d225 140 }
epremeaux 2:c16325a7d225 141
epremeaux 2:c16325a7d225 142 else
epremeaux 2:c16325a7d225 143 {
epremeaux 2:c16325a7d225 144 // pc.printf("Unknown message type\n");
epremeaux 2:c16325a7d225 145 }
epremeaux 2:c16325a7d225 146 }
epremeaux 2:c16325a7d225 147
epremeaux 2:c16325a7d225 148 void parseTime (float timeval)
epremeaux 2:c16325a7d225 149 {
epremeaux 2:c16325a7d225 150 //format utc time to beijing time,add 8 time zone
epremeaux 2:c16325a7d225 151 float time = timeval + 80000.00f;
epremeaux 2:c16325a7d225 152 h_time = int(time) / 10000;
epremeaux 2:c16325a7d225 153 m_time = (int(time) % 10000) / 100;
epremeaux 2:c16325a7d225 154 s_time = int(time) % 100;
edodm85 0:ea14ad6794af 155 }
edodm85 0:ea14ad6794af 156
edodm85 0:ea14ad6794af 157
edodm85 0:ea14ad6794af 158