1717 Development environment specifics:
1818 Arduino IDE 1.8.5
1919
20+ Modified by David Mann @ Loggerhead Instruments, 16 April 2019
21+ - Added support for parsing date and time
22+ - Added functions getYear(), getMonth(), getDay(), getHour(), getMinute(), getSecond()
23+
24+ Modified by Steven Rowland, June 11th, 2019
25+ - Added functionality for reading HPPOSLLH (High Precision Geodetic Position)
26+ - Added getTimeOfWeek(), getHighResLatitude(). getHighResLongitude(), getElipsoid(),
27+ getMeanSeaLevel(), getHorizontalAccuracy(), getVerticalAccuracy(), getHPPOSLLH()
28+ - Modified ProcessUBXPacket to parse HPPOSLLH packet
29+ - Added query staleness verification for HPPOSLLH data
30+
2031 This program is distributed in the hope that it will be useful,
2132 but WITHOUT ANY WARRANTY; without even the implied warranty of
2233 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
@@ -541,6 +552,38 @@ void SFE_UBLOX_GPS::processUBXpacket(ubxPacket *msg)
541552 moduleQueried.headingOfMotion = true ;
542553 moduleQueried.pDOP = true ;
543554 }
555+ else if (msg->id == UBX_NAV_HPPOSLLH && msg->len == 36 ){
556+ timeOfWeek = extractLong (4 );
557+ highResLatitude = extractLong (8 );
558+ highResLongitude = extractLong (12 );
559+ elipsoid = extractLong (16 );
560+ meanSeaLevel = extractLong (20 );
561+ geoidSeparation = extractLong (24 );
562+ horizontalAccuracy = extractLong (28 );
563+ verticalAccuracy = extractLong (32 );
564+
565+ highResModuleQueried.all = true ;
566+ highResModuleQueried.timeOfWeek = true ;
567+ highResModuleQueried.highResLatitude = true ;
568+ highResModuleQueried.highResLongitude = true ;
569+ highResModuleQueried.elipsoid = true ;
570+ highResModuleQueried.meanSeaLevel = true ;
571+ highResModuleQueried.geoidSeparation = true ;
572+ highResModuleQueried.horizontalAccuracy = true ;
573+ highResModuleQueried.verticalAccuracy = true ;
574+
575+ if (_printDebug == true )
576+ {
577+ Serial.print (" Sec: " ); Serial.print (((float )extractLong (4 )) / 1000 .0f ); Serial.print (" " );
578+ Serial.print (" LON: " ); Serial.print (((float )(int32_t )extractLong (8 )) / 10000000 .0f ); Serial.print (" " );
579+ Serial.print (" LAT: " ); Serial.print (((float )(int32_t )extractLong (12 )) / 10000000 .0f ); Serial.print (" " );
580+ Serial.print (" ELI M: " ); Serial.print (((float )(int32_t )extractLong (16 )) / 1000 .0f ); Serial.print (" " );
581+ Serial.print (" MSL M: " ); Serial.print (((float )(int32_t )extractLong (20 )) / 1000 .0f ); Serial.print (" " );
582+ Serial.print (" GEO: " ); Serial.print (((float )(int32_t )extractLong (24 ))/ 1000 .0f ); Serial.print (" " );
583+ Serial.print (" HA 2D M: " ); Serial.print (((float )extractLong (28 )) / 1000 .0f ); Serial.print (" " );
584+ Serial.print (" VERT M: " ); Serial.print (((float )extractLong (32 )) / 1000 .0f ); Serial.print (" " );
585+ }
586+ }
544587 break ;
545588 }
546589}
@@ -721,8 +764,8 @@ void SFE_UBLOX_GPS::printPacket(ubxPacket *packet)
721764 _debugSerial->print (" ID:" );
722765 _debugSerial->print (packet->id , HEX);
723766
724- // _debugSerial->print(" Len: 0x");
725- // _debugSerial->print(packet->len, HEX);
767+ _debugSerial->print (" Len: 0x" );
768+ _debugSerial->print (packet->len , HEX);
726769
727770 _debugSerial->print (" Payload:" );
728771
@@ -1197,19 +1240,19 @@ boolean SFE_UBLOX_GPS::setAutoPVT(boolean enable, uint16_t maxWait)
11971240uint32_t SFE_UBLOX_GPS::extractLong (uint8_t spotToStart)
11981241{
11991242 uint32_t val = 0 ;
1200- val |= (int32_t )payloadCfg[spotToStart + 0 ] << 8 * 0 ;
1201- val |= (int32_t )payloadCfg[spotToStart + 1 ] << 8 * 1 ;
1202- val |= (int32_t )payloadCfg[spotToStart + 2 ] << 8 * 2 ;
1203- val |= (int32_t )payloadCfg[spotToStart + 3 ] << 8 * 3 ;
1243+ val |= (uint32_t )payloadCfg[spotToStart + 0 ] << 8 * 0 ;
1244+ val |= (uint32_t )payloadCfg[spotToStart + 1 ] << 8 * 1 ;
1245+ val |= (uint32_t )payloadCfg[spotToStart + 2 ] << 8 * 2 ;
1246+ val |= (uint32_t )payloadCfg[spotToStart + 3 ] << 8 * 3 ;
12041247 return (val);
12051248}
12061249
12071250// Given a spot in the payload array, extract two bytes and build an int
12081251uint16_t SFE_UBLOX_GPS::extractInt (uint8_t spotToStart)
12091252{
12101253 uint16_t val = 0 ;
1211- val |= (int16_t )payloadCfg[spotToStart + 0 ] << 8 * 0 ;
1212- val |= (int16_t )payloadCfg[spotToStart + 1 ] << 8 * 1 ;
1254+ val |= (uint16_t )payloadCfg[spotToStart + 0 ] << 8 * 0 ;
1255+ val |= (uint16_t )payloadCfg[spotToStart + 1 ] << 8 * 1 ;
12131256 return (val);
12141257}
12151258
@@ -1296,6 +1339,74 @@ boolean SFE_UBLOX_GPS::getPVT(uint16_t maxWait)
12961339 }
12971340}
12981341
1342+ uint32_t SFE_UBLOX_GPS::getTimeOfWeek (uint16_t maxWait/* = 250*/ ){
1343+ if (highResModuleQueried.timeOfWeek == false )
1344+ getHPPOSLLH ();
1345+ highResModuleQueried.timeOfWeek = false ; // Since we are about to give this to user, mark this data as stale
1346+ return (timeOfWeek);
1347+ }
1348+
1349+ int32_t SFE_UBLOX_GPS::getHighResLatitude (uint16_t maxWait/* = 250*/ ){
1350+ if (highResModuleQueried.highResLatitude == false )
1351+ getHPPOSLLH ();
1352+ highResModuleQueried.highResLatitude = false ; // Since we are about to give this to user, mark this data as stale
1353+ return (highResLatitude);
1354+ }
1355+
1356+ int32_t SFE_UBLOX_GPS::getHighResLongitude (uint16_t maxWait/* = 250*/ ){
1357+ if (highResModuleQueried.highResLongitude == false )
1358+ getHPPOSLLH ();
1359+ highResModuleQueried.highResLongitude = false ; // Since we are about to give this to user, mark this data as stale
1360+ return (highResLongitude);
1361+ }
1362+
1363+ int32_t SFE_UBLOX_GPS::getElipsoid (uint16_t maxWait/* = 250*/ ){
1364+ if (highResModuleQueried.elipsoid == false )
1365+ getHPPOSLLH ();
1366+ highResModuleQueried.elipsoid = false ; // Since we are about to give this to user, mark this data as stale
1367+ return (elipsoid);
1368+ }
1369+
1370+ int32_t SFE_UBLOX_GPS::getMeanSeaLevel (uint16_t maxWait/* = 250*/ ){
1371+ if (highResModuleQueried.meanSeaLevel == false )
1372+ getHPPOSLLH ();
1373+ highResModuleQueried.meanSeaLevel = false ; // Since we are about to give this to user, mark this data as stale
1374+ return (meanSeaLevel);
1375+ }
1376+
1377+ int32_t SFE_UBLOX_GPS::getGeoidSeparation (uint16_t maxWait/* = 250*/ ){
1378+ if (highResModuleQueried.geoidSeparation == false )
1379+ getHPPOSLLH ();
1380+ highResModuleQueried.geoidSeparation = false ; // Since we are about to give this to user, mark this data as stale
1381+ return (geoidSeparation);
1382+ }
1383+
1384+ uint32_t SFE_UBLOX_GPS::getHorizontalAccuracy (uint16_t maxWait/* = 250*/ ){
1385+ if (highResModuleQueried.horizontalAccuracy == false )
1386+ getHPPOSLLH ();
1387+ highResModuleQueried.horizontalAccuracy = false ; // Since we are about to give this to user, mark this data as stale
1388+ return (horizontalAccuracy);
1389+ }
1390+
1391+ uint32_t SFE_UBLOX_GPS::getVerticalAccuracy (uint16_t maxWait/* = 250*/ ){
1392+ if (highResModuleQueried.verticalAccuracy == false )
1393+ getHPPOSLLH ();
1394+ highResModuleQueried.verticalAccuracy = false ; // Since we are about to give this to user, mark this data as stale
1395+ return (verticalAccuracy);
1396+ }
1397+
1398+ boolean SFE_UBLOX_GPS::getHPPOSLLH (uint16_t maxWait)
1399+ {
1400+ // The GPS is not automatically reporting navigation position so we have to poll explicitly
1401+ packetCfg.cls = UBX_CLASS_NAV;
1402+ packetCfg.id = UBX_NAV_HPPOSLLH;
1403+ packetCfg.len = 0 ;
1404+
1405+ return sendCommand (packetCfg, maxWait);
1406+ return (false ); // If command send fails then bail
1407+ }
1408+
1409+
12991410// Get the current 3D high precision positional accuracy - a fun thing to watch
13001411// Returns a long representing the 3D accuracy in millimeters
13011412uint32_t SFE_UBLOX_GPS::getPositionAccuracy (uint16_t maxWait)
@@ -1557,4 +1668,4 @@ boolean SFE_UBLOX_GPS::getRELPOSNED(uint16_t maxWait)
15571668 relPosInfo.refObsMiss = flags & (1 << 7 );
15581669
15591670 return (true );
1560- }
1671+ }
0 commit comments