diff --git libraries/SparkFun_Ublox_Arduino_Library/src/SparkFun_Ublox_Arduino_Library.cpp libraries/SparkFun_Ublox_Arduino_Library/src/SparkFun_Ublox_Arduino_Library.cpp index f3f4490..6d3ffcb 100644 --- libraries/SparkFun_Ublox_Arduino_Library/src/SparkFun_Ublox_Arduino_Library.cpp +++ libraries/SparkFun_Ublox_Arduino_Library/src/SparkFun_Ublox_Arduino_Library.cpp @@ -938,6 +938,49 @@ void SFE_UBLOX_GPS::processUBXpacket(ubxPacket *msg) moduleQueried.headingOfMotion = true; moduleQueried.pDOP = true; } + else if (msg->id == UBX_NAV_TIMEUTC && msg->len == 20) + { + timeOfWeek = extractLong(0); + gpsMillisecond = extractLong(0) % 1000; //Get last three digits of iTOW + // extractLong(4); // time accuracy estimate + gpsYear = extractInt(12); + gpsMonth = extractByte(14); + gpsDay = extractByte(15); + gpsHour = extractByte(16); + gpsMinute = extractByte(17); + gpsSecond = extractByte(18); + gpsNanosecond = extractLong(8); //Includes milliseconds + uint8_t valid = extractByte(19); + bool gotTime = (valid & 4) ? true : false; // assume all other fields filled once we have TUTC + + //Mark all datums as fresh (not read before) + moduleQueried.gpsiTOW = gotTime; // valid tow + moduleQueried.gpsYear = gotTime; // valid week num + moduleQueried.gpsMonth = gotTime; + moduleQueried.gpsDay = gotTime; // valid UTC + moduleQueried.gpsHour = gotTime; + moduleQueried.gpsMinute = gotTime; + moduleQueried.gpsSecond = gotTime; + moduleQueried.gpsNanosecond = gotTime; + } + else if (msg->id == UBX_NAV_POSLLH && msg->len == 28) + { + timeOfWeek = extractLong(0); + longitude = extractLong(4); + latitude = extractLong(8); + altitude = extractLong(12); + altitudeMSL = extractLong(16); + horizontalAccuracy = extractLong(20); + verticalAccuracy = extractLong(24); + + moduleQueried.gpsiTOW = true; + moduleQueried.longitude = true; + moduleQueried.latitude = true; + moduleQueried.altitude = true; + moduleQueried.altitudeMSL = true; + highResModuleQueried.horizontalAccuracy = true; + highResModuleQueried.verticalAccuracy = true; + } else if (msg->id == UBX_NAV_HPPOSLLH && msg->len == 36) { timeOfWeek = extractLong(4); @@ -1002,6 +1045,13 @@ void SFE_UBLOX_GPS::processUBXpacket(ubxPacket *msg) _debugSerial->println(((float)(int32_t)extractLong(32)) / 10000.0f); } } + else { + if (_printDebug == true) + { + _debugSerial->print(F("Unexpected nav packet ")); + _debugSerial->println(msg->id); + } + } break; } } @@ -2644,7 +2694,7 @@ int8_t SFE_UBLOX_GPS::extractSignedChar(uint8_t spotToStart) uint16_t SFE_UBLOX_GPS::getYear(uint16_t maxWait) { if (moduleQueried.gpsYear == false) - getPVT(maxWait); + getT(maxWait); moduleQueried.gpsYear = false; //Since we are about to give this to user, mark this data as stale return (gpsYear); } @@ -2653,7 +2703,7 @@ uint16_t SFE_UBLOX_GPS::getYear(uint16_t maxWait) uint8_t SFE_UBLOX_GPS::getMonth(uint16_t maxWait) { if (moduleQueried.gpsMonth == false) - getPVT(maxWait); + getT(maxWait); moduleQueried.gpsMonth = false; //Since we are about to give this to user, mark this data as stale return (gpsMonth); } @@ -2662,7 +2712,7 @@ uint8_t SFE_UBLOX_GPS::getMonth(uint16_t maxWait) uint8_t SFE_UBLOX_GPS::getDay(uint16_t maxWait) { if (moduleQueried.gpsDay == false) - getPVT(maxWait); + getT(maxWait); moduleQueried.gpsDay = false; //Since we are about to give this to user, mark this data as stale return (gpsDay); } @@ -2671,7 +2721,7 @@ uint8_t SFE_UBLOX_GPS::getDay(uint16_t maxWait) uint8_t SFE_UBLOX_GPS::getHour(uint16_t maxWait) { if (moduleQueried.gpsHour == false) - getPVT(maxWait); + getT(maxWait); moduleQueried.gpsHour = false; //Since we are about to give this to user, mark this data as stale return (gpsHour); } @@ -2680,7 +2730,7 @@ uint8_t SFE_UBLOX_GPS::getHour(uint16_t maxWait) uint8_t SFE_UBLOX_GPS::getMinute(uint16_t maxWait) { if (moduleQueried.gpsMinute == false) - getPVT(maxWait); + getT(maxWait); moduleQueried.gpsMinute = false; //Since we are about to give this to user, mark this data as stale return (gpsMinute); } @@ -2689,7 +2739,7 @@ uint8_t SFE_UBLOX_GPS::getMinute(uint16_t maxWait) uint8_t SFE_UBLOX_GPS::getSecond(uint16_t maxWait) { if (moduleQueried.gpsSecond == false) - getPVT(maxWait); + getT(maxWait); moduleQueried.gpsSecond = false; //Since we are about to give this to user, mark this data as stale return (gpsSecond); } @@ -2698,7 +2748,7 @@ uint8_t SFE_UBLOX_GPS::getSecond(uint16_t maxWait) uint16_t SFE_UBLOX_GPS::getMillisecond(uint16_t maxWait) { if (moduleQueried.gpsiTOW == false) - getPVT(maxWait); + getT(maxWait); moduleQueried.gpsiTOW = false; //Since we are about to give this to user, mark this data as stale return (gpsMillisecond); } @@ -2707,11 +2757,13 @@ uint16_t SFE_UBLOX_GPS::getMillisecond(uint16_t maxWait) int32_t SFE_UBLOX_GPS::getNanosecond(uint16_t maxWait) { if (moduleQueried.gpsNanosecond == false) - getPVT(maxWait); + getT(maxWait); moduleQueried.gpsNanosecond = false; //Since we are about to give this to user, mark this data as stale return (gpsNanosecond); } +bool neo6M = true; + //Get the latest Position/Velocity/Time solution and fill all global variables boolean SFE_UBLOX_GPS::getPVT(uint16_t maxWait) { @@ -2762,10 +2814,72 @@ boolean SFE_UBLOX_GPS::getPVT(uint16_t maxWait) } } +// Update our time info (using correct call for the chipset) +boolean SFE_UBLOX_GPS::getT(uint16_t maxWait) +{ + return !neo6M ? getPVT(maxWait) : getTIMEUTC(maxWait); +} + +// Update our time info (using correct call for the chipset) +boolean SFE_UBLOX_GPS::getP(uint16_t maxWait) +{ + return !neo6M ? getPVT(maxWait) : getPOSLLH(maxWait); +} + +//Get time (supported on NEO 6M) +boolean SFE_UBLOX_GPS::getTIMEUTC(uint16_t maxWait) +{ + debugPrintln((char *)F("getTIMEUTC: Polling")); + + //The GPS is not automatically reporting navigation position so we have to poll explicitly + packetCfg.cls = UBX_CLASS_NAV; + packetCfg.id = UBX_NAV_TIMEUTC; + packetCfg.len = 0; + //packetCfg.startingSpot = 20; //Begin listening at spot 20 so we can record up to 20+MAX_PAYLOAD_SIZE = 84 bytes Note:now hard-coded in processUBX + + //The data is parsed as part of processing the response + sfe_ublox_status_e retVal = sendCommand(&packetCfg, maxWait); + + if (retVal == SFE_UBLOX_STATUS_DATA_RECEIVED) + return (true); + + if (_printDebug == true) + { + _debugSerial->print(F("getTIMEUTC retVal: ")); + _debugSerial->println(statusString(retVal)); + } + return (false); +} + +//Get posllh (supported on NEO 6M) +boolean SFE_UBLOX_GPS::getPOSLLH(uint16_t maxWait) +{ + debugPrintln((char *)F("getPOSLLH: Polling")); + + //The GPS is not automatically reporting navigation position so we have to poll explicitly + packetCfg.cls = UBX_CLASS_NAV; + packetCfg.id = UBX_NAV_POSLLH; + packetCfg.len = 0; + //packetCfg.startingSpot = 20; //Begin listening at spot 20 so we can record up to 20+MAX_PAYLOAD_SIZE = 84 bytes Note:now hard-coded in processUBX + + //The data is parsed as part of processing the response + sfe_ublox_status_e retVal = sendCommand(&packetCfg, maxWait); + + if (retVal == SFE_UBLOX_STATUS_DATA_RECEIVED) + return (true); + + if (_printDebug == true) + { + _debugSerial->print(F("getPOSLLH retVal: ")); + _debugSerial->println(statusString(retVal)); + } + return (false); +} + uint32_t SFE_UBLOX_GPS::getTimeOfWeek(uint16_t maxWait /* = 250*/) { if (moduleQueried.gpsiTOW == false) - getPVT(maxWait); + getT(maxWait); moduleQueried.gpsiTOW = false; //Since we are about to give this to user, mark this data as stale return (timeOfWeek); } @@ -2895,7 +3009,7 @@ uint32_t SFE_UBLOX_GPS::getPositionAccuracy(uint16_t maxWait) int32_t SFE_UBLOX_GPS::getLatitude(uint16_t maxWait) { if (moduleQueried.latitude == false) - getPVT(maxWait); + getP(maxWait); moduleQueried.latitude = false; //Since we are about to give this to user, mark this data as stale moduleQueried.all = false; @@ -2907,7 +3021,7 @@ int32_t SFE_UBLOX_GPS::getLatitude(uint16_t maxWait) int32_t SFE_UBLOX_GPS::getLongitude(uint16_t maxWait) { if (moduleQueried.longitude == false) - getPVT(maxWait); + getP(maxWait); moduleQueried.longitude = false; //Since we are about to give this to user, mark this data as stale moduleQueried.all = false; @@ -2918,7 +3032,7 @@ int32_t SFE_UBLOX_GPS::getLongitude(uint16_t maxWait) int32_t SFE_UBLOX_GPS::getAltitude(uint16_t maxWait) { if (moduleQueried.altitude == false) - getPVT(maxWait); + getP(maxWait); moduleQueried.altitude = false; //Since we are about to give this to user, mark this data as stale moduleQueried.all = false; @@ -2931,7 +3045,7 @@ int32_t SFE_UBLOX_GPS::getAltitude(uint16_t maxWait) int32_t SFE_UBLOX_GPS::getAltitudeMSL(uint16_t maxWait) { if (moduleQueried.altitudeMSL == false) - getPVT(maxWait); + getP(maxWait); moduleQueried.altitudeMSL = false; //Since we are about to give this to user, mark this data as stale moduleQueried.all = false; diff --git libraries/SparkFun_Ublox_Arduino_Library/src/SparkFun_Ublox_Arduino_Library.h libraries/SparkFun_Ublox_Arduino_Library/src/SparkFun_Ublox_Arduino_Library.h index dfa6ce4..61b4c25 100644 --- libraries/SparkFun_Ublox_Arduino_Library/src/SparkFun_Ublox_Arduino_Library.h +++ libraries/SparkFun_Ublox_Arduino_Library/src/SparkFun_Ublox_Arduino_Library.h @@ -532,6 +532,11 @@ public: boolean assumeAutoPVT(boolean enabled, boolean implicitUpdate = true); //In case no config access to the GPS is possible and PVT is send cyclically already boolean setAutoPVT(boolean enabled, uint16_t maxWait = defaultMaxWait); //Enable/disable automatic PVT reports at the navigation frequency boolean getPVT(uint16_t maxWait = getPVTmaxWait); //Query module for latest group of datums and load global vars: lat, long, alt, speed, SIV, accuracies, etc. If autoPVT is disabled, performs an explicit poll and waits, if enabled does not block. Retruns true if new PVT is available. + boolean getT(uint16_t maxWait = getPVTmaxWait); //Query module for latest group of datums and load global vars: lat, long, alt, speed, SIV, accuracies, etc. If autoPVT is disabled, performs an explicit poll and waits, if enabled does not block. Retruns true if new PVT is available. + boolean getP(uint16_t maxWait = getPVTmaxWait); //Query module for latest group of datums and load global vars: lat, long, alt, speed, SIV, accuracies, etc. If autoPVT is disabled, performs an explicit poll and waits, if enabled does not block. Retruns true if new PVT is available. + boolean getTIMEUTC(uint16_t maxWait = getPVTmaxWait); //Query module for current time Neo6M only. Retruns true if new PVT is available. + boolean getPOSLLH(uint16_t maxWait = getPVTmaxWait); //Query module for current time Neo6M only. Retruns true if new PVT is available. + boolean setAutoPVT(boolean enabled, boolean implicitUpdate, uint16_t maxWait = defaultMaxWait); //Enable/disable automatic PVT reports at the navigation frequency, with implicitUpdate == false accessing stale data will not issue parsing of data in the rxbuffer of your interface, instead you have to call checkUblox when you want to perform an update boolean getHPPOSLLH(uint16_t maxWait = getHPPOSLLHmaxWait); //Query module for latest group of datums and load global vars: lat, long, alt, speed, SIV, accuracies, etc. If autoPVT is disabled, performs an explicit poll and waits, if enabled does not block. Retruns true if new PVT is available. void flushPVT(); //Mark all the PVT data as read/stale. This is handy to get data alignment after CRC failure