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: " print (((float )extractLong (4 )) / 1000 .0f ); Serial.print ("  " 
578+  Serial.print (" LON: " print (((float )(int32_t )extractLong (8 )) / 10000000 .0f ); Serial.print ("  " 
579+  Serial.print (" LAT: " print (((float )(int32_t )extractLong (12 )) / 10000000 .0f ); Serial.print ("  " 
580+  Serial.print (" ELI M: " print (((float )(int32_t )extractLong (16 )) / 1000 .0f ); Serial.print ("  " 
581+  Serial.print (" MSL M: " print (((float )(int32_t )extractLong (20 )) / 1000 .0f ); Serial.print ("  " 
582+  Serial.print (" GEO: " print (((float )(int32_t )extractLong (24 ))/ 1000 .0f ); Serial.print ("  " 
583+  Serial.print (" HA 2D M: " print (((float )extractLong (28 )) / 1000 .0f ); Serial.print ("  " 
584+  Serial.print (" VERT M: " 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