Mbed library for Quectel L80 GPS module
Revision 0:a5ea5d8302ef, committed 2019-04-12
- Comitter:
- biagiomkr
- Date:
- Fri Apr 12 17:00:42 2019 +0000
- Commit message:
- First release of Mbed library for Quectel L80
Changed in this revision
| Quectel_L80_GPS.cpp | Show annotated file Show diff for this revision Revisions of this file |
| Quectel_L80_GPS.h | Show annotated file Show diff for this revision Revisions of this file |
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Quectel_L80_GPS.cpp Fri Apr 12 17:00:42 2019 +0000
@@ -0,0 +1,652 @@
+/***********************************************************************
+This is the Quectel L80 GPS library.
+It is based on the Adafruit GPS library and has been adapted in order to
+work with Mbed OS.
+
+Initially written by Limor Fried/Ladyada for Adafruit Industries.
+Modified by Biagio Montaruli <biagio.hkr@gmail.com>
+BSD license, check license.txt for more information
+All text above must be included in any redistribution
+************************************************************************/
+
+/* Includes ------------------------------------------------------------------*/
+#include "mbed.h"
+#include <ctype.h>
+#include "Quectel_L80_GPS.h"
+
+/* Constructor */
+Quectel_L80_GPS::Quectel_L80_GPS(Serial *ser)
+{
+ gpsHwSerial = ser;
+
+ recvdflag = false;
+ paused = false;
+ lineidx = 0;
+ currentline = line1;
+ lastline = line2;
+ inFullOnMode = true;
+ inStandbyMode = false;
+ inAlwaysLocateMode = false;
+
+ hours = minutes = seconds = milliseconds = 0;
+ year = month = day = 0;
+ fixQuality = satellites = 0;
+ lat = lon = mag = 0;
+ fix = false;
+ latitude = longitude = altitude = 0.0;
+ geoidheight = speed = angle = magvariation = HDOP = 0.0;
+
+ LOCUS_serial = LOCUS_records = 0;
+ LOCUS_type = LOCUS_mode = LOCUS_config = LOCUS_interval = 0;
+ LOCUS_distance = LOCUS_speed = LOCUS_status = LOCUS_percent = 0;
+}
+
+bool Quectel_L80_GPS::parse(char *nmea)
+{
+ if (nmea[strlen(nmea) - 4] == '*') {
+ uint16_t sum = parseHex(nmea[strlen(nmea) - 3]) * 16;
+ sum += parseHex(nmea[strlen(nmea) - 2]);
+
+ /* compute checksum */
+ for (uint8_t i = 2; i < (strlen(nmea) - 4); i++) {
+ sum ^= nmea[i];
+ }
+ if (sum != 0) {
+ /* bad checksum */
+ return false;
+ }
+ }
+ int32_t degree;
+ long min;
+ char degreebuff[10];
+ /* look for a few common sentences */
+ if (strstr(nmea, "$GPGGA")) {
+ /* found GGA */
+ char *p = nmea;
+ /* get time */
+ p = strchr(p, ',') + 1;
+ double timef = atof(p);
+ uint32_t time = timef;
+ hours = time / 10000;
+ minutes = (time % 10000) / 100;
+ seconds = (time % 100);
+
+ milliseconds = fmod(timef, 1.0) * 1000;
+
+ /* parse out latitude */
+ p = strchr(p, ',') + 1;
+ if (',' != *p) {
+ strncpy(degreebuff, p, 2);
+ p += 2;
+ degreebuff[2] = '\0';
+ degree = atol(degreebuff) * 10000000;
+ strncpy(degreebuff, p, 2);
+ p += 3; /* skip decimal point */
+ strncpy(degreebuff + 2, p, 4);
+ degreebuff[6] = '\0';
+ min = 50 * atol(degreebuff) / 3;
+ latitude_fixed = degree + min;
+ latitude = degree / 100000 + min * 0.000006F;
+ latitudeDegrees = (latitude - 100 * int(latitude / 100)) / 60.0;
+ latitudeDegrees += int(latitude / 100);
+ }
+
+ p = strchr(p, ',') + 1;
+ if (',' != *p) {
+ if (p[0] == 'S') latitudeDegrees *= -1.0;
+ if (p[0] == 'N') lat = 'N';
+ else if (p[0] == 'S') lat = 'S';
+ else if (p[0] == ',') lat = 0;
+ else return false;
+ }
+
+ /* parse out longitude */
+ p = strchr(p, ',') + 1;
+ if (',' != *p) {
+ strncpy(degreebuff, p, 3);
+ p += 3;
+ degreebuff[3] = '\0';
+ degree = atol(degreebuff) * 10000000;
+ strncpy(degreebuff, p, 2);
+ p += 3; /* skip decimal point */
+ strncpy(degreebuff + 2, p, 4);
+ degreebuff[6] = '\0';
+ min = 50 * atol(degreebuff) / 3;
+ longitude_fixed = degree + min;
+ longitude = degree / 100000 + min * 0.000006F;
+ longitudeDegrees = (longitude - 100 * int(longitude / 100)) / 60.0;
+ longitudeDegrees += int(longitude / 100);
+ }
+
+ p = strchr(p, ',') + 1;
+ if (',' != *p) {
+ if (p[0] == 'W') longitudeDegrees *= -1.0;
+ if (p[0] == 'W') lon = 'W';
+ else if (p[0] == 'E') lon = 'E';
+ else if (p[0] == ',') lon = 0;
+ else return false;
+ }
+
+ p = strchr(p, ',') + 1;
+ if (',' != *p) {
+ fixQuality = atoi(p);
+ }
+
+ p = strchr(p, ',') + 1;
+ if (',' != *p) {
+ satellites = atoi(p);
+ }
+
+ p = strchr(p, ',') + 1;
+ if (',' != *p) {
+ HDOP = atof(p);
+ }
+
+ p = strchr(p, ',') + 1;
+ if (',' != *p) {
+ altitude = atof(p);
+ }
+
+ p = strchr(p, ',') + 1;
+ p = strchr(p, ',') + 1;
+ if (',' != *p) {
+ geoidheight = atof(p);
+ }
+ return true;
+ }
+ if (strstr(nmea, "$GPRMC")) {
+ /* found RMC */
+ char *p = nmea;
+
+ /* get time */
+ p = strchr(p, ',') + 1;
+ double timef = atof(p);
+ uint32_t time = timef;
+ hours = time / 10000;
+ minutes = (time % 10000) / 100;
+ seconds = (time % 100);
+
+ milliseconds = fmod(timef, 1.0) * 1000;
+
+ p = strchr(p, ',') + 1;
+ if (p[0] == 'A')
+ fix = true;
+ else if (p[0] == 'V')
+ fix = false;
+ else
+ return false;
+
+ /* parse out latitude */
+ p = strchr(p, ',') + 1;
+ if (',' != *p) {
+ strncpy(degreebuff, p, 2);
+ p += 2;
+ degreebuff[2] = '\0';
+ long degree = atol(degreebuff) * 10000000;
+ strncpy(degreebuff, p, 2);
+ p += 3; /* skip decimal point */
+ strncpy(degreebuff + 2, p, 4);
+ degreebuff[6] = '\0';
+ min = 50 * atol(degreebuff) / 3;
+ latitude_fixed = degree + min;
+ latitude = degree / 100000 + min * 0.000006F;
+ latitudeDegrees = (latitude - 100 * int(latitude / 100)) / 60.0;
+ latitudeDegrees += int(latitude / 100);
+ }
+
+ p = strchr(p, ',') + 1;
+ if (',' != *p) {
+ if (p[0] == 'S') latitudeDegrees *= -1.0;
+ if (p[0] == 'N') lat = 'N';
+ else if (p[0] == 'S') lat = 'S';
+ else if (p[0] == ',') lat = 0;
+ else return false;
+ }
+
+ /* parse out longitude */
+ p = strchr(p, ',') + 1;
+ if (',' != *p) {
+ strncpy(degreebuff, p, 3);
+ p += 3;
+ degreebuff[3] = '\0';
+ degree = atol(degreebuff) * 10000000;
+ strncpy(degreebuff, p, 2);
+ p += 3; /* skip decimal point */
+ strncpy(degreebuff + 2, p, 4);
+ degreebuff[6] = '\0';
+ min = 50 * atol(degreebuff) / 3;
+ longitude_fixed = degree + min;
+ longitude = degree / 100000 + minutes * 0.000006F;
+ longitudeDegrees = (longitude - 100 * int(longitude / 100)) / 60.0;
+ longitudeDegrees += int(longitude / 100);
+ }
+
+ p = strchr(p, ',') + 1;
+ if (',' != *p) {
+ if (p[0] == 'W') longitudeDegrees *= -1.0;
+ if (p[0] == 'W') lon = 'W';
+ else if (p[0] == 'E') lon = 'E';
+ else if (p[0] == ',') lon = 0;
+ else return false;
+ }
+ /* speed */
+ p = strchr(p, ',')+1;
+ if (',' != *p) {
+ speed = atof(p);
+ }
+
+ /* angle */
+ p = strchr(p, ',') + 1;
+ if (',' != *p) {
+ angle = atof(p);
+ }
+
+ p = strchr(p, ',') + 1;
+ if (',' != *p) {
+ uint32_t fulldate = atof(p);
+ day = fulldate / 10000;
+ month = (fulldate % 10000) / 100;
+ year = (fulldate % 100);
+ }
+
+ return true;
+ }
+
+ return false;
+}
+
+char Quectel_L80_GPS::read(void)
+{
+ char c = 0;
+
+ if (paused) return c;
+
+ if(!gpsHwSerial->readable()) return c;
+
+ c = gpsHwSerial->getc();
+#ifdef SERIAL_DEBUG
+ pcSerial.print(c);
+#endif
+
+ if (c == '\n') {
+ currentline[lineidx] = 0;
+
+ if (currentline == line1) {
+ currentline = line2;
+ lastline = line1;
+ } else {
+ currentline = line1;
+ lastline = line2;
+ }
+
+#ifdef SERIAL_DEBUG
+ pcSerial.println("----");
+ pcSerial.println((char *)lastline);
+ pcSerial.println("----");
+#endif
+ lineidx = 0;
+ recvdflag = true;
+ }
+
+ currentline[lineidx++] = c;
+ if (lineidx >= MAXLINELENGTH)
+ lineidx = MAXLINELENGTH-1;
+
+ return c;
+}
+
+void Quectel_L80_GPS::sendCommand(const char *str)
+{
+ gpsHwSerial->printf("%s\n", str);
+}
+
+bool Quectel_L80_GPS::newNMEAreceived(void)
+{
+ return recvdflag;
+}
+
+void Quectel_L80_GPS::pause(bool p)
+{
+ paused = p;
+}
+
+char *Quectel_L80_GPS::lastNMEA(void)
+{
+ recvdflag = false;
+ return (char *)lastline;
+}
+
+/* read a Hex value and return the decimal equivalent */
+uint8_t Quectel_L80_GPS::parseHex(char c)
+{
+ if (c < '0')
+ return 0;
+ if (c <= '9')
+ return c - '0';
+ if (c < 'A')
+ return 0;
+ if (c <= 'F')
+ return (c - 'A') + 10;
+ // if (c > 'F')
+ return 0;
+}
+
+bool Quectel_L80_GPS::waitForSentence(const char *waitstr, uint8_t max)
+{
+ char str[20];
+
+ uint8_t i = 0;
+ while (i < max) {
+ read();
+
+ if (newNMEAreceived()) {
+ char *nmea = lastNMEA();
+ strncpy(str, nmea, 20);
+ str[19] = 0;
+ i++;
+
+ if (strstr(str, waitstr))
+ return true;
+ }
+ }
+
+ return false;
+}
+
+uint8_t Quectel_L80_GPS::getHour(void)
+{
+ return hours;
+}
+
+uint8_t Quectel_L80_GPS::getMinutes(void)
+{
+ return minutes;
+}
+
+uint8_t Quectel_L80_GPS::getSeconds(void)
+{
+ return seconds;
+}
+
+uint8_t Quectel_L80_GPS::getMilliseconds(void)
+{
+ return milliseconds;
+}
+
+uint8_t Quectel_L80_GPS::getDay(void)
+{
+ return day;
+}
+
+uint8_t Quectel_L80_GPS::getMonth(void)
+{
+ return month;
+}
+
+uint8_t Quectel_L80_GPS::getYear(void)
+{
+ return year;
+}
+
+float Quectel_L80_GPS::getLatitude(void)
+{
+ return latitude;
+}
+
+float Quectel_L80_GPS::getLongitude(void)
+{
+ return longitude;
+}
+
+int32_t Quectel_L80_GPS::getLatitudeFixed(void)
+{
+ return latitude_fixed;
+}
+
+int32_t Quectel_L80_GPS::getLongitudeFixed(void)
+{
+ return longitude_fixed;
+}
+
+float Quectel_L80_GPS::getLatitudeDegrees(void)
+{
+ return latitudeDegrees;
+}
+
+float Quectel_L80_GPS::getLongitudeDegrees(void)
+{
+ return longitudeDegrees;
+}
+
+float Quectel_L80_GPS::getAltitude(void)
+{
+ return altitude;
+}
+
+float Quectel_L80_GPS::getGeoidheight(void)
+{
+ return geoidheight;
+}
+
+float Quectel_L80_GPS::getSpeed(void)
+{
+ return speed;
+}
+
+float Quectel_L80_GPS::getAngle(void)
+{
+ return angle;
+}
+
+float Quectel_L80_GPS::getMagVariation(void)
+{
+ return magvariation;
+}
+
+float Quectel_L80_GPS::getHDOP(void)
+{
+ return HDOP;
+}
+
+char Quectel_L80_GPS::getLatCardinalDir(void)
+{
+ return lat;
+}
+
+char Quectel_L80_GPS::getLonCardinalDir(void)
+{
+ return lon;
+}
+
+char Quectel_L80_GPS::getMagCardinalDir(void)
+{
+ return mag;
+}
+
+bool Quectel_L80_GPS::isFixed(void)
+{
+ return fix;
+}
+
+uint8_t Quectel_L80_GPS::getQuality(void)
+{
+ return fixQuality;
+}
+
+uint8_t Quectel_L80_GPS::getSatellites(void)
+{
+ return satellites;
+}
+
+bool Quectel_L80_GPS::LOCUS_StartLogger(void)
+{
+ sendCommand(PMTK_LOCUS_STARTLOG);
+ recvdflag = false;
+ return waitForSentence(PMTK_LOCUS_STARTSTOPACK);
+}
+
+bool Quectel_L80_GPS::LOCUS_StopLogger(void)
+{
+ sendCommand(PMTK_LOCUS_STOPLOG);
+ recvdflag = false;
+ return waitForSentence(PMTK_LOCUS_STARTSTOPACK);
+}
+
+bool Quectel_L80_GPS::LOCUS_ReadStatus(void)
+{
+ sendCommand(PMTK_LOCUS_QUERY_STATUS);
+
+ if (!waitForSentence("$PMTKLOG"))
+ return false;
+
+ char *response = lastNMEA();
+ uint16_t parsed[10];
+ uint8_t i;
+
+ for (i = 0; i < 10; i++) {
+ parsed[i] = -1;
+ }
+
+ response = strchr(response, ',');
+ for (i = 0; i < 10; i++) {
+ if (!response || (response[0] == 0) || (response[0] == '*'))
+ break;
+ response++;
+ parsed[i] = 0;
+ while ((response[0] != ',') && (response[0] != '*') && (response[0] != 0)) {
+ parsed[i] *= 10;
+ char c = response[0];
+ if (isdigit(c))
+ parsed[i] += c - '0';
+ else
+ parsed[i] = c;
+ response++;
+ }
+ }
+ LOCUS_serial = parsed[0];
+ LOCUS_type = parsed[1];
+ if (isalpha(parsed[2])) {
+ parsed[2] = parsed[2] - 'a' + 10;
+ }
+ LOCUS_mode = parsed[2];
+ LOCUS_config = parsed[3];
+ LOCUS_interval = parsed[4];
+ LOCUS_distance = parsed[5];
+ LOCUS_speed = parsed[6];
+ LOCUS_status = !parsed[7];
+ LOCUS_records = parsed[8];
+ LOCUS_percent = parsed[9];
+
+ return true;
+}
+
+uint16_t Quectel_L80_GPS::LOCUS_GetSerial()
+{
+ return LOCUS_serial;
+}
+
+uint16_t Quectel_L80_GPS::LOCUS_GetRecords()
+{
+ return LOCUS_records;
+}
+
+uint8_t Quectel_L80_GPS::LOCUS_GetType()
+{
+ return LOCUS_type;
+}
+
+uint8_t Quectel_L80_GPS::LOCUS_GetMode()
+{
+ return LOCUS_mode;
+}
+
+uint8_t Quectel_L80_GPS::LOCUS_GetConfig()
+{
+ return LOCUS_config;
+}
+
+uint8_t Quectel_L80_GPS::LOCUS_GetInterval()
+{
+ return LOCUS_interval;
+}
+
+uint8_t Quectel_L80_GPS::LOCUS_GetDistance()
+{
+ return LOCUS_distance;
+}
+
+uint8_t Quectel_L80_GPS::LOCUS_GetSpeed()
+{
+ return LOCUS_speed;
+}
+
+uint8_t Quectel_L80_GPS::LOCUS_GetStatus()
+{
+ return LOCUS_status;
+}
+
+uint8_t Quectel_L80_GPS::LOCUS_GetPercent()
+{
+ return LOCUS_percent;
+}
+
+bool Quectel_L80_GPS::setStandbyMode(void)
+{
+ if (inStandbyMode) {
+ /* Returns false if already in standby mode */
+ return false;
+ } else {
+ inStandbyMode = true;
+ inFullOnMode = false;
+ inAlwaysLocateMode = false;
+ recvdflag = false;
+ sendCommand(PMTK_STANDBY);
+ return waitForSentence(PMTK_STANDBY_SUCCESS);
+ }
+}
+
+bool Quectel_L80_GPS::wakeupStandby(void)
+{
+ if (inStandbyMode) {
+ inStandbyMode = false;
+ inFullOnMode = true;
+ inAlwaysLocateMode = false;
+ recvdflag = false;
+ sendCommand(""); /* send byte to wake it up */
+ return waitForSentence(PMTK_AWAKE);
+ } else {
+ /* Returns false if not in standby mode, nothing to wakeup */
+ return false;
+ }
+}
+
+/* AlwaysLocate Mode APIs: */
+bool Quectel_L80_GPS::setAlwaysLocateMode(void)
+{
+ if (inAlwaysLocateMode) {
+ /* Returns false if already in AlwayLocate mode,
+ * so that you do not wake it up by sending commands to GPS */
+ return false;
+ } else {
+ inStandbyMode = false;
+ inFullOnMode = false;
+ inAlwaysLocateMode = true;
+ recvdflag = false;
+ sendCommand(PMTK_ALWAYSLOCATE_STANDBY);
+ return waitForSentence(PMTK_ALWAYSLOCATE_STANDBY_SUCCESS);
+ }
+}
+
+bool Quectel_L80_GPS::wakeupAlwaysLocate(void)
+{
+ if (inAlwaysLocateMode) {
+ inStandbyMode = false;
+ inFullOnMode = true;
+ inAlwaysLocateMode = false;
+ sendCommand(PMTK_ALWAYSLOCATE_EXIT);
+ return true;
+ } else {
+ /* Returns false if not in AlwaysLocate mode, nothing to wakeup */
+ return false;
+ }
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/Quectel_L80_GPS.h Fri Apr 12 17:00:42 2019 +0000
@@ -0,0 +1,222 @@
+/***********************************************************************
+This is the Quectel L80 GPS library.
+It is based on the Adafruit GPS library and has been adapted in order to
+work with Mbed OS.
+
+Initially written by Limor Fried/Ladyada for Adafruit Industries.
+Modified by Biagio Montaruli <biagio.hkr@gmail.com>
+BSD license, check license.txt for more information
+All text above must be included in any redistribution
+************************************************************************/
+
+#ifndef __QUECTEL_L80_GPS_H
+#define __QUECTEL_L80_GPS_H
+
+/* *
+ * Commands to set the update rate from once a second (1 Hz) to
+ * 10 times a second (10Hz). Note that these only control the rate at which the
+ * position is echoed, to actually speed up the position fix you must also send
+ * one of the position fix rate commands below too.
+ */
+#define PMTK_SET_NMEA_UPDATE_100_MILLIHERTZ "$PMTK220,10000*2F"
+#define PMTK_SET_NMEA_UPDATE_200_MILLIHERTZ "$PMTK220,5000*1B"
+#define PMTK_SET_NMEA_UPDATE_1HZ "$PMTK220,1000*1F"
+#define PMTK_SET_NMEA_UPDATE_2HZ "$PMTK220,500*2B"
+#define PMTK_SET_NMEA_UPDATE_5HZ "$PMTK220,200*2C"
+#define PMTK_SET_NMEA_UPDATE_10HZ "$PMTK220,100*2F"
+/* Position fix update rate commands. */
+#define PMTK_API_SET_FIX_CTL_100_MILLIHERTZ "$PMTK300,10000,0,0,0,0*2C"
+#define PMTK_API_SET_FIX_CTL_200_MILLIHERTZ "$PMTK300,5000,0,0,0,0*18"
+#define PMTK_API_SET_FIX_CTL_1HZ "$PMTK300,1000,0,0,0,0*1C"
+#define PMTK_API_SET_FIX_CTL_5HZ "$PMTK300,200,0,0,0,0*2F"
+
+#define PMTK_SET_BAUD_57600 "$PMTK251,57600*2C"
+#define PMTK_SET_BAUD_9600 "$PMTK251,9600*17"
+
+/* turn on only the second sentence (GPRMC) */
+#define PMTK_SET_NMEA_OUTPUT_RMCONLY "$PMTK314,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*29"
+/* turn on GPRMC and GGA */
+#define PMTK_SET_NMEA_OUTPUT_RMCGGA "$PMTK314,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*28"
+/* turn on ALL THE DATA */
+#define PMTK_SET_NMEA_OUTPUT_ALLDATA "$PMTK314,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0*28"
+/* turn off output */
+#define PMTK_SET_NMEA_OUTPUT_OFF "$PMTK314,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0*28"
+
+/*
+ * NOTE: to generate your own sentences, check out the MTK command datasheet and
+ * use a checksum calculator
+ */
+
+#define PMTK_LOCUS_STARTLOG "$PMTK185,0*22"
+#define PMTK_LOCUS_STOPLOG "$PMTK185,1*23"
+#define PMTK_LOCUS_STARTSTOPACK "$PMTK001,185,3*3C"
+#define PMTK_LOCUS_QUERY_STATUS "$PMTK183*38"
+#define PMTK_LOCUS_ERASE_FLASH "$PMTK184,1*22"
+#define LOCUS_OVERLAP 0
+#define LOCUS_FULLSTOP 1
+
+#define PMTK_ENABLE_SBAS "$PMTK313,1*2E"
+#define PMTK_ENABLE_WAAS "$PMTK301,2*2E"
+
+/* Standby mode command & boot successful message */
+#define PMTK_STANDBY "$PMTK161,0*28"
+#define PMTK_STANDBY_SUCCESS "$PMTK001,161,3*36"
+#define PMTK_AWAKE "$PMTK010,002*2D"
+
+/* *
+ * Backup mode commands:
+ * keeping GPS_EN signal low and sending PMTK command "$PMTK225,4*2F" will make
+ * L80 module enter into backup mode forever. To wake the GPS module up you must
+ * pull the GPS_EN signal high.
+ */
+#define PMTK_BACKUP "$PMTK225,4*2F"
+
+/* AlwaysLocate mode commands */
+/* AlwaysLocate standby commands: */
+#define PMTK_ALWAYSLOCATE_STANDBY "$PMTK225,8*23"
+#define PMTK_ALWAYSLOCATE_STANDBY_SUCCESS "$PMTK001,225,3*35"
+/* AlwaysLocate backup command: */
+#define PMTK_ALWAYSLOCATE_BACKUP "$PMTK225,9*22"
+/* AlwaysLocate exit command: the gps module returns into full on mode */
+#define PMTK_ALWAYSLOCATE_EXIT "$PMTK225,0*2B"
+
+/* EASY functions: */
+#define PMTK_EASY_ENABLE "$PMTK869,1,1*35"
+#define PMTK_EASY_DISABLE "$PMTK869,1,0*34"
+#define PMTK_EASY_CHECK_STATUS "$PMTK869,0*29"
+#define PMTK_EASY_STATUS_ENABLED "$PMTK869,2,1*36"
+#define PMTK_EASY_STATUS_DISABLED "$PMTK869,2,0*37"
+
+/* Get the release and version: */
+#define PMTK_Q_RELEASE "$PMTK605*31"
+
+/* Request for updates on antenna status */
+#define PGCMD_ANTENNA "$PGCMD,33,1*6C"
+#define PGCMD_NOANTENNA "$PGCMD,33,0*6D"
+
+/* AIC function: */
+#define PMTK_AIC_ENABLE "$PMTK286,1*23"
+#define PMTK_AIC_DISABLE "$PMTK286,0*22"
+
+/* Maximum timeout for a response */
+#define MAXWAITSENTENCE 10
+
+/* Maximum length of NMEA senstences */
+#define MAXLINELENGTH 120
+
+#ifdef SERIAL_DEBUG
+Serial pcSerial(USBTX, USBRX);
+#endif
+
+class Quectel_L80_GPS
+{
+public:
+ Quectel_L80_GPS(Serial *ser);
+
+ char *lastNMEA(void);
+ bool newNMEAreceived();
+ void common_init(void);
+
+ void sendCommand(const char *);
+
+ void pause(bool b);
+
+ bool parseNMEA(char *response);
+ uint8_t parseHex(char c);
+
+ char read(void);
+ bool parse(char *);
+
+ uint8_t getHour(void);
+ uint8_t getMinutes(void);
+ uint8_t getSeconds(void);
+ uint8_t getMilliseconds(void);
+
+ uint8_t getYear(void);
+ uint8_t getMonth(void);
+ uint8_t getDay(void);
+
+ float getLatitude(void);
+ float getLongitude(void);
+ int32_t getLatitudeFixed(void);
+ int32_t getLongitudeFixed(void);
+ float getLatitudeDegrees(void);
+ float getLongitudeDegrees(void);
+ float getAltitude(void);
+ float getGeoidheight(void);
+ float getSpeed(void);
+ float getAngle(void);
+ float getMagVariation(void);
+ float getHDOP(void);
+
+ char getLatCardinalDir(void);
+ char getLonCardinalDir(void);
+ char getMagCardinalDir(void);
+
+ bool isFixed(void);
+ uint8_t getQuality(void);
+
+ uint8_t getSatellites(void);
+
+ bool wakeupStandby(void);
+ bool setStandbyMode(void);
+
+ bool setAlwaysLocateMode(void);
+ bool wakeupAlwaysLocate(void);
+
+ bool waitForSentence(const char *wait, uint8_t max = MAXWAITSENTENCE);
+ bool LOCUS_StartLogger(void);
+ bool LOCUS_StopLogger(void);
+ bool LOCUS_ReadStatus(void);
+
+ uint16_t LOCUS_GetSerial();
+ uint16_t LOCUS_GetRecords();
+ uint8_t LOCUS_GetType();
+ uint8_t LOCUS_GetMode();
+ uint8_t LOCUS_GetConfig();
+ uint8_t LOCUS_GetInterval();
+ uint8_t LOCUS_GetDistance();
+ uint8_t LOCUS_GetSpeed();
+ uint8_t LOCUS_GetStatus();
+ uint8_t LOCUS_GetPercent();
+
+private:
+ Serial *gpsHwSerial;
+
+ bool paused;
+ bool inStandbyMode;
+ bool inFullOnMode;
+ bool inAlwaysLocateMode;
+
+ bool recvdflag;
+ /* use two buffer: read one line in and leave one for the main program */
+ char line1[MAXLINELENGTH];
+ char line2[MAXLINELENGTH];
+ /* index into the current line */
+ uint8_t lineidx;
+ /* pointers to the double buffers */
+ char *currentline;
+ char *lastline;
+
+ uint8_t hours, minutes, seconds, year, month, day;
+ uint16_t milliseconds;
+ /* floating point latitude and longitude value in degrees */
+ float latitude, longitude;
+ /* Fixed point latitude and longitude value with degrees stored in units of
+ * 1/100000 degrees, and minutes stored in units of 1/100000 degrees.
+ */
+ int32_t latitude_fixed, longitude_fixed;
+ float latitudeDegrees, longitudeDegrees;
+ float geoidheight, altitude;
+ float speed, angle, magvariation, HDOP;
+ char lat, lon, mag;
+ bool fix;
+ uint8_t fixQuality, satellites;
+
+ uint16_t LOCUS_serial, LOCUS_records;
+ uint8_t LOCUS_type, LOCUS_mode, LOCUS_config, LOCUS_interval, LOCUS_distance,
+ LOCUS_speed, LOCUS_status, LOCUS_percent;
+ uint8_t parseResponse(char *response);
+};
+
+#endif
\ No newline at end of file