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: BSP_DISCO_F746NG
GroveGPS.h
- Committer:
- c1728p9
- Date:
- 2019-06-06
- Revision:
- 3:037ec2b52d31
- Parent:
- 2:82fce70de15f
- Child:
- 4:0ee729b4a211
File content as of revision 3:037ec2b52d31:
#ifndef _GROVE_GPS_H_
#define _GROVE_GPS_H_
#include "mbed.h"
#include <stdlib.h>
#include <string>
class GroveGPS {
public:
GroveGPS(PinName tx=D1, PinName rx=D0) : _last_line(""), gps_serial(tx, rx, 9600) {}
void readCharacter(char newCharacter) {
if (newCharacter == '\n') {
parseLine();
_last_line = "";
} else {
_last_line += newCharacter;
}
if (_last_line.length() > max_line_length) {
error("GPS error - line too long");
_last_line = "";
}
}
struct GGA {
double utc_time; // Format: hhmmss.sss
double latitude; // Format: ddmm.mmmm
char ns_indicator; // Format: N=north or S=south
double longitude; // Format: dddmm.mmmm
char ew_indicator; // Format: E=east or W=west
int position_fix; // Options: [0=not available, 1=GPS SPS mode, 2=Differential GPS, 6=dead reckoning]
int sats_used; // Range: 0-12
double hdop; // Horizontal Dilution of Precision
double msl_altitude;
char msl_altitude_units;
double geoid_separation;
char geoid_separation_units;
long age_of_diff;
long diff_ref_station_id;
std::string checksum;
} gps_gga;
void getTimestamp(char* buffer) {
m.lock();
sprintf(buffer, "%f", gps_gga.utc_time);
m.unlock();
}
void getLatitude(char* buffer) {
m.lock();
double coordinate = convertGPSToDecimal(gps_gga.latitude);
if (gps_gga.position_fix==0)
sprintf(buffer, "N/A");
else
sprintf(buffer, "%c%f", (gps_gga.ns_indicator == 'N') ? '0' : '-', coordinate);
m.unlock();
}
void getLongitude(char* buffer) {
m.lock();
double coordinate = convertGPSToDecimal(gps_gga.longitude);
if (gps_gga.position_fix==0)
sprintf(buffer, "N/A");
else
sprintf(buffer, "%c%f", (gps_gga.ew_indicator == 'E') ? '0' : '-', coordinate);
m.unlock();
}
void start() {
serial_thread.start(callback(this, &GroveGPS::read_serial));
}
private:
static const size_t max_line_length = 1024;
std::string _last_line;
Thread serial_thread;
Serial gps_serial;
Mutex m;
void read_serial() {
while (true) {
if (gps_serial.readable()) {
readCharacter(gps_serial.getc());
}
}
}
double convertGPSToDecimal(double coordinate) {
int degrees = coordinate/100.0;
int minutes = ((int)coordinate) % 100;
double seconds = coordinate - ((int)coordinate);
return degrees + (minutes+seconds)/60;
}
void parseLine() {
if (_last_line.find("GPGGA") != std::string::npos) {
m.lock();
parseGGA();
m.unlock();
}
}
void parseGGA() {
char* pEnd;
for (int i=0; i<14; i++) {
std::string current_item = _last_line.substr(0,_last_line.find(","));
_last_line = _last_line.substr(_last_line.find(",")+1);
if (i==0) { // NMEA Tag
} else if (i==1) { // UTC time
gps_gga.utc_time = strtod(current_item.c_str(), &pEnd);
} else if (i==2) { // Latitude
gps_gga.latitude = strtod(current_item.c_str(), &pEnd);
} else if (i==3) { // Latitude North/South indicator
gps_gga.ns_indicator = current_item[0];
} else if (i==4) { // Longitude
gps_gga.longitude = strtod(current_item.c_str(), &pEnd);
} else if (i==5) { // Longitude indicator
gps_gga.ew_indicator = current_item[0];
} else if (i==6) {
gps_gga.position_fix = strtod(current_item.c_str(), &pEnd);
}
}
}
};
#endif