Skip to content
This repository was archived by the owner on Jan 28, 2021. It is now read-only.
30 changes: 29 additions & 1 deletion examples/Example13_PVT/Example1_AutoPVT/Example1_AutoPVT.ino
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,8 @@ void setup()
void loop()
{
// Calling getPVT returns true if there actually is a fresh navigation solution available.
if (myGPS.getPVT())
// Start the reading only when valid LLH is available
if (myGPS.getPVT() && (myGPS.getInvalidLlh() == false))
{
Serial.println();
long latitude = myGPS.getLatitude();
Expand Down Expand Up @@ -105,6 +106,33 @@ void loop()
Serial.print(horizontalAccEst);
Serial.print(F(" (mm)"));

int speedAccEst = myGPS.getSpeedAccEst();
Serial.print(F(" SpeedAccEst: "));
Serial.print(speedAccEst);
Serial.print(F(" (mm/s)"));

int headAccEst = myGPS.getHeadingAccEst();
Serial.print(F(" HeadAccEst: "));
Serial.print(headAccEst);
Serial.print(F(" (degrees * 10^-5)"));

if (myGPS.getHeadVehValid() == true) {
int headVeh = myGPS.getHeadVeh();
Serial.print(F(" HeadVeh: "));
Serial.print(headVeh);
Serial.print(F(" (degrees * 10^-5)"));

int magDec = myGPS.getMagDec();
Serial.print(F(" MagDec: "));
Serial.print(magDec);
Serial.print(F(" (degrees * 10^-2)"));

int magAcc = myGPS.getMagAcc();
Serial.print(F(" MagAcc: "));
Serial.print(magAcc);
Serial.print(F(" (degrees * 10^-2)"));
}

Serial.println();
} else {
Serial.print(".");
Expand Down
7 changes: 7 additions & 0 deletions keywords.txt
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,13 @@ getVerticalAccEst KEYWORD2
getNedNorthVel KEYWORD2
getNedEastVel KEYWORD2
getNedDownVel KEYWORD2
getSpeedAccEst KEYWORD2
getHeadingAccEst KEYWORD2
getInvalidLlh KEYWORD2
getHeadVeh KEYWORD2
getMagDec KEYWORD2
getMagAcc KEYWORD2
getHeadVehValid KEYWORD2

setPortOutput KEYWORD2
setPortInput KEYWORD2
Expand Down
99 changes: 95 additions & 4 deletions src/SparkFun_Ublox_Arduino_Library.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1027,8 +1027,9 @@ void SFE_UBLOX_GPS::processUBXpacket(ubxPacket *msg)

fixType = extractByte(20 - startingSpot);
gnssFixOk = extractByte(21 - startingSpot) & 0x1; //Get the 1st bit
diffSoln = extractByte(21 - startingSpot) >> 1 & 0x1; //Get the 2nd bit
diffSoln = (extractByte(21 - startingSpot) >> 1) & 0x1; //Get the 2nd bit
carrierSolution = extractByte(21 - startingSpot) >> 6; //Get 6th&7th bits of this byte
headVehValid = (extractByte(21 - startingSpot) >> 5) & 0x1; // Get the 5th bit
SIV = extractByte(23 - startingSpot);
longitude = extractSignedLong(24 - startingSpot);
latitude = extractSignedLong(28 - startingSpot);
Expand All @@ -1039,10 +1040,15 @@ void SFE_UBLOX_GPS::processUBXpacket(ubxPacket *msg)
nedNorthVel = extractSignedLong(48 - startingSpot);
nedEastVel = extractSignedLong(52 - startingSpot);
nedDownVel = extractSignedLong(56 - startingSpot);

groundSpeed = extractSignedLong(60 - startingSpot);
headingOfMotion = extractSignedLong(64 - startingSpot);
speedAccEst = extractLong(68 - startingSpot);
headingAccEst = extractLong(72 - startingSpot);
pDOP = extractInt(76 - startingSpot);
invalidLlh = extractByte(78 - startingSpot) & 0x1;
headVeh = extractSignedLong(84 - startingSpot);
magDec = extractSignedInt(88 - startingSpot);
magAcc = extractInt(90 - startingSpot);

//Mark all datums as fresh (not read before)
moduleQueried.gpsiTOW = true;
Expand All @@ -1059,23 +1065,28 @@ void SFE_UBLOX_GPS::processUBXpacket(ubxPacket *msg)
moduleQueried.all = true;
moduleQueried.gnssFixOk = true;
moduleQueried.diffSoln = true;
moduleQueried.headVehValid = true;
moduleQueried.longitude = true;
moduleQueried.latitude = true;
moduleQueried.altitude = true;
moduleQueried.altitudeMSL = true;

moduleQueried.horizontalAccEst = true;
moduleQueried.verticalAccEst = true;
moduleQueried.nedNorthVel = true;
moduleQueried.nedEastVel = true;
moduleQueried.nedDownVel = true;

moduleQueried.SIV = true;
moduleQueried.fixType = true;
moduleQueried.carrierSolution = true;
moduleQueried.groundSpeed = true;
moduleQueried.headingOfMotion = true;
moduleQueried.speedAccEst = true;
moduleQueried.headingAccEst = true;
moduleQueried.pDOP = true;
moduleQueried.invalidLlh = true;
moduleQueried.headVeh = true;
moduleQueried.magDec = true;
moduleQueried.magAcc = true;
}
else if (msg->id == UBX_NAV_HPPOSLLH && msg->len == 36)
{
Expand Down Expand Up @@ -3111,6 +3122,19 @@ uint16_t SFE_UBLOX_GPS::extractInt(uint8_t spotToStart)
return (val);
}

//Just so there is no ambiguity about whether a uint16_t will cast to a int16_t correctly...
int16_t SFE_UBLOX_GPS::extractSignedInt(int8_t spotToStart)
{
union // Use a union to convert from uint16_t to int16_t
{
uint16_t unsignedInt;
int16_t signedInt;
} stSignedInt;

stSignedInt.unsignedInt = extractInt(spotToStart);
return (stSignedInt.signedInt);
}

//Given a spot, extract a byte from the payload
uint8_t SFE_UBLOX_GPS::extractByte(uint8_t spotToStart)
{
Expand Down Expand Up @@ -3195,6 +3219,54 @@ bool SFE_UBLOX_GPS::getTimeValid(uint16_t maxWait)
return (gpsTimeValid);
}

uint32_t SFE_UBLOX_GPS::getSpeedAccEst(uint16_t maxWait)
{
if (moduleQueried.speedAccEst == false)
getPVT(maxWait);
moduleQueried.speedAccEst = false; //Since we are about to give this to user, mark this data as stale
return (speedAccEst);
}

uint32_t SFE_UBLOX_GPS::getHeadingAccEst(uint16_t maxWait)
{
if (moduleQueried.headingAccEst == false)
getPVT(maxWait);
moduleQueried.headingAccEst = false; //Since we are about to give this to user, mark this data as stale
return (headingAccEst);
}

bool SFE_UBLOX_GPS::getInvalidLlh(uint16_t maxWait)
{
if (moduleQueried.invalidLlh == false)
getPVT(maxWait);
moduleQueried.invalidLlh = false; //Since we are about to give this to user, mark this data as stale
return (invalidLlh);
}

int32_t SFE_UBLOX_GPS::getHeadVeh(uint16_t maxWait)
{
if (moduleQueried.headVeh == false)
getPVT(maxWait);
moduleQueried.headVeh = false; //Since we are about to give this to user, mark this data as stale
return (headVeh);
}

int16_t SFE_UBLOX_GPS::getMagDec(uint16_t maxWait)
{
if (moduleQueried.magDec == false)
getPVT(maxWait);
moduleQueried.magDec = false; //Since we are about to give this to user, mark this data as stale
return (magDec);
}

uint16_t SFE_UBLOX_GPS::getMagAcc(uint16_t maxWait)
{
if (moduleQueried.magAcc == false)
getPVT(maxWait);
moduleQueried.magAcc = false; //Since we are about to give this to user, mark this data as stale
return (magAcc);
}

//Get the current millisecond
uint16_t SFE_UBLOX_GPS::getMillisecond(uint16_t maxWait)
{
Expand Down Expand Up @@ -3780,6 +3852,18 @@ uint8_t SFE_UBLOX_GPS::getCarrierSolutionType(uint16_t maxWait)
return (carrierSolution);
}

//Get whether head vehicle valid or not
bool SFE_UBLOX_GPS::getHeadVehValid(uint16_t maxWait)
{
if (moduleQueried.headVehValid == false)
getPVT(maxWait);
moduleQueried.headVehValid = false; //Since we are about to give this to user, mark this data as stale
moduleQueried.all = false;

return (headVehValid);
}


//Get the ground speed in mm/s
int32_t SFE_UBLOX_GPS::getGroundSpeed(uint16_t maxWait)
{
Expand Down Expand Up @@ -3901,6 +3985,7 @@ void SFE_UBLOX_GPS::flushPVT()
moduleQueried.all = false;
moduleQueried.gnssFixOk = false;
moduleQueried.diffSoln = false;
moduleQueried.headVehValid = false;
moduleQueried.longitude = false;
moduleQueried.latitude = false;
moduleQueried.altitude = false;
Expand All @@ -3910,7 +3995,13 @@ void SFE_UBLOX_GPS::flushPVT()
moduleQueried.carrierSolution = false;
moduleQueried.groundSpeed = false;
moduleQueried.headingOfMotion = false;
moduleQueried.speedAccEst = false;
moduleQueried.headingAccEst = false;
moduleQueried.pDOP = false;
moduleQueried.invalidLlh = false;
moduleQueried.headVeh = false;
moduleQueried.magDec = false;
moduleQueried.magAcc = false;
}

//Mark all the HPPOSLLH data as read/stale. This is handy to get data alignment after CRC failure
Expand Down
27 changes: 22 additions & 5 deletions src/SparkFun_Ublox_Arduino_Library.h
Original file line number Diff line number Diff line change
Expand Up @@ -507,17 +507,16 @@ class SFE_UBLOX_GPS

bool getGnssFixOk(uint16_t maxWait = getPVTmaxWait); //Get whether we have a valid fix (i.e within DOP & accuracy masks)
bool getDiffSoln(uint16_t maxWait = getPVTmaxWait); //Get whether differential corrections were applied
bool getHeadVehValid(uint16_t maxWait = getPVTmaxWait);
int32_t getLatitude(uint16_t maxWait = getPVTmaxWait); //Returns the current latitude in degrees * 10^-7. Auto selects between HighPrecision and Regular depending on ability of module.
int32_t getLongitude(uint16_t maxWait = getPVTmaxWait); //Returns the current longitude in degrees * 10-7. Auto selects between HighPrecision and Regular depending on ability of module.
int32_t getAltitude(uint16_t maxWait = getPVTmaxWait); //Returns the current altitude in mm above ellipsoid
int32_t getAltitudeMSL(uint16_t maxWait = getPVTmaxWait); //Returns the current altitude in mm above mean sea level

int32_t getHorizontalAccEst(uint16_t maxWait = getPVTmaxWait);
int32_t getVerticalAccEst(uint16_t maxWait = getPVTmaxWait);
int32_t getNedNorthVel(uint16_t maxWait = getPVTmaxWait);
int32_t getNedEastVel(uint16_t maxWait = getPVTmaxWait);
int32_t getNedDownVel(uint16_t maxWait = getPVTmaxWait);

uint8_t getSIV(uint16_t maxWait = getPVTmaxWait); //Returns number of sats used in fix
uint8_t getFixType(uint16_t maxWait = getPVTmaxWait); //Returns the type of fix: 0=no, 3=3D, 4=GNSS+Deadreckoning
uint8_t getCarrierSolutionType(uint16_t maxWait = getPVTmaxWait); //Returns RTK solution: 0=no, 1=float solution, 2=fixed solution
Expand All @@ -535,6 +534,12 @@ class SFE_UBLOX_GPS
uint32_t getTimeOfWeek(uint16_t maxWait = getPVTmaxWait);
bool getDateValid(uint16_t maxWait = getPVTmaxWait);
bool getTimeValid(uint16_t maxWait = getPVTmaxWait);
uint32_t getSpeedAccEst(uint16_t maxWait = getPVTmaxWait);
uint32_t getHeadingAccEst(uint16_t maxWait = getPVTmaxWait);
bool getInvalidLlh(uint16_t maxWait = getPVTmaxWait);
int32_t getHeadVeh(uint16_t maxWait = getPVTmaxWait);
int16_t getMagDec(uint16_t maxWait = getPVTmaxWait);
uint16_t getMagAcc(uint16_t maxWait = getPVTmaxWait);

int32_t getHighResLatitude(uint16_t maxWait = getHPPOSLLHmaxWait);
int8_t getHighResLatitudeHp(uint16_t maxWait = getHPPOSLLHmaxWait);
Expand Down Expand Up @@ -730,9 +735,9 @@ class SFE_UBLOX_GPS
bool gpsDateValid;
bool gpsTimeValid;


bool gnssFixOk; //valid fix (i.e within DOP & accuracy masks)
bool diffSoln; //Differential corrections were applied
bool headVehValid;
int32_t latitude; //Degrees * 10^-7 (more accurate than floats)
int32_t longitude; //Degrees * 10^-7 (more accurate than floats)
int32_t altitude; //Number of mm above ellipsoid
Expand All @@ -747,7 +752,13 @@ class SFE_UBLOX_GPS
uint8_t carrierSolution; //Tells us when we have an RTK float/fixed solution
int32_t groundSpeed; //mm/s
int32_t headingOfMotion; //degrees * 10^-5
uint32_t speedAccEst;
uint32_t headingAccEst;
uint16_t pDOP; //Positional dilution of precision * 10^-2 (dimensionless)
bool invalidLlh;
int32_t headVeh;
int16_t magDec;
uint16_t magAcc;
uint8_t versionLow; //Loaded from getProtocolVersion().
uint8_t versionHigh;

Expand Down Expand Up @@ -943,6 +954,7 @@ class SFE_UBLOX_GPS
uint32_t extractLong(uint8_t spotToStart); //Combine four bytes from payload into long
int32_t extractSignedLong(uint8_t spotToStart); //Combine four bytes from payload into signed long (avoiding any ambiguity caused by casting)
uint16_t extractInt(uint8_t spotToStart); //Combine two bytes from payload into int
int16_t extractSignedInt(int8_t spotToStart);
uint8_t extractByte(uint8_t spotToStart); //Get byte from payload
int8_t extractSignedChar(uint8_t spotToStart); //Get signed 8-bit value from payload
void addToChecksum(uint8_t incoming); //Given an incoming byte, adjust rollingChecksumA/B
Expand Down Expand Up @@ -1022,23 +1034,28 @@ class SFE_UBLOX_GPS
uint32_t all : 1;
uint32_t gnssFixOk : 1;
uint32_t diffSoln : 1;
uint32_t headVehValid : 1;
uint32_t longitude : 1;
uint32_t latitude : 1;
uint32_t altitude : 1;
uint32_t altitudeMSL : 1;

uint32_t horizontalAccEst : 1;
uint32_t verticalAccEst : 1;
uint32_t nedNorthVel : 1;
uint32_t nedEastVel : 1;
uint32_t nedDownVel : 1;

uint32_t SIV : 1;
uint32_t fixType : 1;
uint32_t carrierSolution : 1;
uint32_t groundSpeed : 1;
uint32_t headingOfMotion : 1;
uint32_t speedAccEst : 1;
uint32_t headingAccEst : 1;
uint32_t pDOP : 1;
uint32_t invalidLlh : 1;
uint32_t headVeh : 1;
uint32_t magDec : 1;
uint32_t magAcc : 1;
uint32_t versionNumber : 1;
} moduleQueried;

Expand Down