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