@@ -63,6 +63,8 @@ DevUBLOXGNSS::DevUBLOXGNSS(void)
6363 _logNMEA.all = 0; // Default to passing no NMEA messages to the file buffer
6464 _processNMEA.all = SFE_UBLOX_FILTER_NMEA_ALL; // Default to passing all NMEA messages to processNMEA
6565 _logRTCM.all = 0; // Default to passing no RTCM messages to the file buffer
66+
67+ createLock(); // Create the lock semaphore - if needed
6668}
6769
6870DevUBLOXGNSS::~DevUBLOXGNSS(void)
@@ -88,6 +90,8 @@ DevUBLOXGNSS::~DevUBLOXGNSS(void)
8890 delete[] spiBuffer; // Created with new[]
8991 spiBuffer = nullptr;
9092 }
93+
94+ deleteLock(); // Delete the lock semaphore - if required
9195}
9296
9397// Stop all automatic message processing. Free all used RAM
@@ -2140,6 +2144,8 @@ bool DevUBLOXGNSS::logThisNMEA()
21402144 logMe = true;
21412145 if ((nmeaAddressField[3] == 'R') && (nmeaAddressField[4] == 'M') && (nmeaAddressField[5] == 'C') && (_logNMEA.bits.UBX_NMEA_RMC == 1))
21422146 logMe = true;
2147+ if ((nmeaAddressField[3] == 'T') && (nmeaAddressField[4] == 'H') && (nmeaAddressField[5] == 'S') && (_logNMEA.bits.UBX_NMEA_THS == 1))
2148+ logMe = true;
21432149 if ((nmeaAddressField[3] == 'T') && (nmeaAddressField[4] == 'X') && (nmeaAddressField[5] == 'T') && (_logNMEA.bits.UBX_NMEA_TXT == 1))
21442150 logMe = true;
21452151 if ((nmeaAddressField[3] == 'V') && (nmeaAddressField[4] == 'L') && (nmeaAddressField[5] == 'W') && (_logNMEA.bits.UBX_NMEA_VLW == 1))
@@ -2198,6 +2204,8 @@ bool DevUBLOXGNSS::isNMEAHeaderValid()
21982204 return (true);
21992205 if ((nmeaAddressField[3] == 'R') && (nmeaAddressField[4] == 'M') && (nmeaAddressField[5] == 'C'))
22002206 return (true);
2207+ if ((nmeaAddressField[3] == 'T') && (nmeaAddressField[4] == 'H') && (nmeaAddressField[5] == 'S'))
2208+ return (true);
22012209 if ((nmeaAddressField[3] == 'T') && (nmeaAddressField[4] == 'X') && (nmeaAddressField[5] == 'T'))
22022210 return (true);
22032211 if ((nmeaAddressField[3] == 'V') && (nmeaAddressField[4] == 'L') && (nmeaAddressField[5] == 'W'))
@@ -2251,6 +2259,8 @@ bool DevUBLOXGNSS::processThisNMEA()
22512259 return (true);
22522260 if ((nmeaAddressField[3] == 'R') && (nmeaAddressField[4] == 'M') && (nmeaAddressField[5] == 'C') && (_processNMEA.bits.UBX_NMEA_RMC == 1))
22532261 return (true);
2262+ if ((nmeaAddressField[3] == 'T') && (nmeaAddressField[4] == 'H') && (nmeaAddressField[5] == 'S') && (_processNMEA.bits.UBX_NMEA_THS == 1))
2263+ return (true);
22542264 if ((nmeaAddressField[3] == 'T') && (nmeaAddressField[4] == 'X') && (nmeaAddressField[5] == 'T') && (_processNMEA.bits.UBX_NMEA_TXT == 1))
22552265 return (true);
22562266 if ((nmeaAddressField[3] == 'V') && (nmeaAddressField[4] == 'L') && (nmeaAddressField[5] == 'W') && (_processNMEA.bits.UBX_NMEA_VLW == 1))
@@ -7786,6 +7796,72 @@ bool DevUBLOXGNSS::resetOdometer(uint16_t maxWait)
77867796 return (sendCommand(&packetCfg, maxWait, true) == SFE_UBLOX_STATUS_DATA_SENT); // We are only expecting an ACK
77877797}
77887798
7799+ // Enable / disable the odometer
7800+ bool DevUBLOXGNSS::enableOdometer(bool enable, uint8_t layer, uint16_t maxWait)
7801+ {
7802+ return setVal8(UBLOX_CFG_ODO_USE_ODO, (uint8_t)enable, layer, maxWait);
7803+ }
7804+
7805+ // Read the odometer configuration
7806+ bool DevUBLOXGNSS::getOdometerConfig(uint8_t *flags, uint8_t *odoCfg, uint8_t *cogMaxSpeed, uint8_t *cogMaxPosAcc, uint8_t *velLpGain, uint8_t *cogLpGain, uint8_t layer, uint16_t maxWait)
7807+ {
7808+ bool result = newCfgValget(layer);
7809+ result &= addCfgValget(UBLOX_CFG_ODO_USE_ODO);
7810+ result &= addCfgValget(UBLOX_CFG_ODO_USE_COG);
7811+ result &= addCfgValget(UBLOX_CFG_ODO_OUTLPVEL);
7812+ result &= addCfgValget(UBLOX_CFG_ODO_OUTLPCOG);
7813+ result &= addCfgValget(UBLOX_CFG_ODO_PROFILE);
7814+ result &= addCfgValget(UBLOX_CFG_ODO_COGMAXSPEED);
7815+ result &= addCfgValget(UBLOX_CFG_ODO_COGMAXPOSACC);
7816+ result &= addCfgValget(UBLOX_CFG_ODO_VELLPGAIN);
7817+ result &= addCfgValget(UBLOX_CFG_ODO_COGLPGAIN);
7818+ result &= sendCfgValget(maxWait);
7819+
7820+ if (result)
7821+ {
7822+ uint8_t flagsBit = 0;
7823+ uint8_t flagsByte = 0;
7824+ result &= extractConfigValueByKey(&packetCfg, UBLOX_CFG_ODO_USE_ODO, &flagsBit, 1);
7825+ if (flagsBit)
7826+ flagsByte |= UBX_CFG_ODO_USE_ODO;
7827+ result &= extractConfigValueByKey(&packetCfg, UBLOX_CFG_ODO_USE_COG, &flagsBit, 1);
7828+ if (flagsBit)
7829+ flagsByte |= UBX_CFG_ODO_USE_COG;
7830+ result &= extractConfigValueByKey(&packetCfg, UBLOX_CFG_ODO_OUTLPVEL, &flagsBit, 1);
7831+ if (flagsBit)
7832+ flagsByte |= UBX_CFG_ODO_OUT_LP_VEL;
7833+ result &= extractConfigValueByKey(&packetCfg, UBLOX_CFG_ODO_OUTLPCOG, &flagsBit, 1);
7834+ if (flagsBit)
7835+ flagsByte |= UBX_CFG_ODO_OUT_LP_COG;
7836+ *flags = flagsByte;
7837+
7838+ result &= extractConfigValueByKey(&packetCfg, UBLOX_CFG_ODO_PROFILE, odoCfg, 1);
7839+ result &= extractConfigValueByKey(&packetCfg, UBLOX_CFG_ODO_COGMAXSPEED, cogMaxSpeed, 1);
7840+ result &= extractConfigValueByKey(&packetCfg, UBLOX_CFG_ODO_COGMAXPOSACC, cogMaxPosAcc, 1);
7841+ result &= extractConfigValueByKey(&packetCfg, UBLOX_CFG_ODO_VELLPGAIN, velLpGain, 1);
7842+ result &= extractConfigValueByKey(&packetCfg, UBLOX_CFG_ODO_COGLPGAIN, cogLpGain, 1);
7843+ }
7844+
7845+ return result;
7846+ }
7847+
7848+ // Configure the odometer
7849+ bool DevUBLOXGNSS::setOdometerConfig(uint8_t flags, uint8_t odoCfg, uint8_t cogMaxSpeed, uint8_t cogMaxPosAcc, uint8_t velLpGain, uint8_t cogLpGain, uint8_t layer, uint16_t maxWait)
7850+ {
7851+ bool result = newCfgValset(layer);
7852+ result &= addCfgValset8(UBLOX_CFG_ODO_USE_ODO, flags & UBX_CFG_ODO_USE_ODO ? 1 : 0);
7853+ result &= addCfgValset8(UBLOX_CFG_ODO_USE_COG, flags & UBX_CFG_ODO_USE_COG ? 1 : 0);
7854+ result &= addCfgValset8(UBLOX_CFG_ODO_OUTLPVEL, flags & UBX_CFG_ODO_OUT_LP_VEL ? 1 : 0);
7855+ result &= addCfgValset8(UBLOX_CFG_ODO_OUTLPCOG, flags & UBX_CFG_ODO_OUT_LP_COG ? 1 : 0);
7856+ result &= addCfgValset8(UBLOX_CFG_ODO_PROFILE, odoCfg);
7857+ result &= addCfgValset8(UBLOX_CFG_ODO_COGMAXSPEED, cogMaxSpeed);
7858+ result &= addCfgValset8(UBLOX_CFG_ODO_COGMAXPOSACC, cogMaxPosAcc);
7859+ result &= addCfgValset8(UBLOX_CFG_ODO_VELLPGAIN, velLpGain);
7860+ result &= addCfgValset8(UBLOX_CFG_ODO_COGLPGAIN, cogLpGain);
7861+ result &= sendCfgValset(maxWait);
7862+ return result;
7863+ }
7864+
77897865uint32_t DevUBLOXGNSS::getEnableGNSSConfigKey(sfe_ublox_gnss_ids_e id)
77907866{
77917867 const uint32_t gnssConfigKeys[(uint8_t)SFE_UBLOX_GNSS_ID_UNKNOWN] = {
@@ -15671,6 +15747,8 @@ int32_t DevUBLOXGNSS::getAltitude(uint16_t maxWait)
1567115747// Get the current altitude in mm according to mean sea level
1567215748// Ellipsoid model: https://www.esri.com/news/arcuser/0703/geoid1of3.html
1567315749// Difference between Ellipsoid Model and Mean Sea Level: https://eos-gnss.com/elevation-for-beginners/
15750+ // Also see: https://portal.u-blox.com/s/question/0D52p00008HKDSkCAP/what-geoid-model-is-used-and-where-is-this-calculated
15751+ // and: https://cddis.nasa.gov/926/egm96/egm96.html on 10x10 degree grid
1567415752int32_t DevUBLOXGNSS::getAltitudeMSL(uint16_t maxWait)
1567515753{
1567615754 if (packetUBXNAVPVT == nullptr)
0 commit comments