Skip to content

Commit e988f05

Browse files
committed
Add helper functions for NAV-HPPOSECEF
1 parent 1804217 commit e988f05

File tree

4 files changed

+235
-0
lines changed

4 files changed

+235
-0
lines changed
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
/*
2+
Get the high precision ECEF coordinates using double
3+
By: Paul Clark
4+
SparkFun Electronics
5+
Date: September 8th, 2022
6+
License: MIT. See license file for more information but you can
7+
basically do whatever you want with this code.
8+
9+
This example shows how to read the high-precision ECEF
10+
positional solution. Please see below for information about the units.
11+
12+
** This example will only work correctly on platforms which support 64-bit double **
13+
14+
Feel like supporting open source hardware?
15+
Buy a board from SparkFun!
16+
ZED-F9P RTK2: https://www.sparkfun.com/products/15136
17+
NEO-M8P RTK: https://www.sparkfun.com/products/15005
18+
19+
Hardware Connections:
20+
Plug a Qwiic cable into the GNSS and (e.g.) a Redboard Artemis https://www.sparkfun.com/products/15444
21+
or an Artemis Thing Plus https://www.sparkfun.com/products/15574
22+
If you don't have a platform with a Qwiic connection use the SparkFun Qwiic Breadboard Jumper (https://www.sparkfun.com/products/14425)
23+
Open the serial monitor at 115200 baud to see the output
24+
*/
25+
26+
#include <Wire.h> // Needed for I2C to GNSS
27+
28+
#define myWire Wire // This will work on the Redboard Artemis and the Artemis Thing Plus using Qwiic
29+
//#define myWire Wire1 // Uncomment this line if you are using the extra SCL1/SDA1 pins (D17 and D16) on the Thing Plus
30+
31+
#include <SparkFun_u-blox_GNSS_Arduino_Library.h> //http://librarymanager/All#SparkFun_u-blox_GNSS
32+
SFE_UBLOX_GNSS myGNSS;
33+
34+
long lastTime = 0; //Simple local timer. Limits amount if I2C traffic to u-blox module.
35+
36+
void setup()
37+
{
38+
Serial.begin(115200);
39+
while (!Serial); //Wait for user to open terminal
40+
41+
myWire.begin();
42+
43+
//myGNSS.enableDebugging(Serial); // Uncomment this line to enable debug messages
44+
45+
if (myGNSS.begin(myWire) == false) //Connect to the u-blox module using Wire port
46+
{
47+
Serial.println(F("u-blox GNSS not detected at default I2C address. Please check wiring. Freezing."));
48+
while (1)
49+
;
50+
}
51+
52+
// Check that this platform supports 64-bit (8 byte) double
53+
if (sizeof(double) < 8)
54+
{
55+
Serial.println(F("Warning! Your platform does not support 64-bit double."));
56+
Serial.println(F("The ECEF coordinates will be inaccurate."));
57+
}
58+
59+
myGNSS.setI2COutput(COM_TYPE_UBX); //Set the I2C port to output UBX only (turn off NMEA noise)
60+
//myGNSS.saveConfiguration(); //Save the current settings to flash and BBR
61+
}
62+
63+
void loop()
64+
{
65+
//Query module only every second.
66+
//The module only responds when a new position is available.
67+
if (millis() - lastTime > 1000)
68+
{
69+
lastTime = millis(); //Update the timer
70+
71+
// getHighResECEFX: returns the X coordinate from HPPOSECEF as an int32_t in cm
72+
// getHighResECEFXHp: returns the high resolution component of the X coordinate from HPPOSECEF as an int8_t in mm*10^-1 (0.1mm)
73+
// getHighResECEFY: returns the Y coordinate from HPPOSECEF as an int32_t in cm
74+
// getHighResECEFYHp: returns the high resolution component of the Y coordinate from HPPOSECEF as an int8_t in mm*10^-1 (0.1mm)
75+
// getHighResECEFZ: returns the Z coordinate from HPPOSECEF as an int32_t in cm
76+
// getHighResECEFZHp: returns the high resolution component of the Z coordinate from HPPOSECEF as an int8_t in mm*10^-1 (0.1mm)
77+
// getPositionAccuracy: returns the position accuracy estimate from HPPOSLLH as an uint32_t in mm (note: not 0.1mm)
78+
79+
// First, let's collect the position data
80+
int32_t ECEFX = myGNSS.getHighResECEFX();
81+
int8_t ECEFXHp = myGNSS.getHighResECEFXHp();
82+
int32_t ECEFY = myGNSS.getHighResECEFY();
83+
int8_t ECEFYHp = myGNSS.getHighResECEFYHp();
84+
int32_t ECEFZ = myGNSS.getHighResECEFZ();
85+
int8_t ECEFZHp = myGNSS.getHighResECEFZHp();
86+
uint32_t accuracy = myGNSS.getPositionAccuracy();
87+
88+
// Defines storage for the ECEF coordinates as double
89+
double d_ECEFX;
90+
double d_ECEFY;
91+
double d_ECEFZ;
92+
93+
// Assemble the high precision coordinates
94+
d_ECEFX = ((double)ECEFX) / 100.0; // Convert from cm to m
95+
d_ECEFX += ((double)ECEFXHp) / 10000.0; // Now add the high resolution component ( mm * 10^-1 = m * 10^-4 )
96+
d_ECEFY = ((double)ECEFY) / 100.0; // Convert from cm to m
97+
d_ECEFY += ((double)ECEFYHp) / 10000.0; // Now add the high resolution component ( mm * 10^-1 = m * 10^-4 )
98+
d_ECEFZ = ((double)ECEFZ) / 100.0; // Convert from cm to m
99+
d_ECEFZ += ((double)ECEFZHp) / 10000.0; // Now add the high resolution component ( mm * 10^-1 = m * 10^-4 )
100+
101+
// Print the coordinates with 4 decimal places (0.1mm)
102+
Serial.print("X (m): ");
103+
Serial.print(d_ECEFX, 4);
104+
Serial.print(", Y (m): ");
105+
Serial.print(d_ECEFY, 4);
106+
Serial.print(", Z (m): ");
107+
Serial.print(d_ECEFZ, 4);
108+
109+
// Now define float storage for the accuracy
110+
float f_accuracy;
111+
112+
// Convert the horizontal accuracy (mm) to a float
113+
f_accuracy = accuracy;
114+
// Now convert to m
115+
f_accuracy = f_accuracy / 1000.0; // Convert from mm to m
116+
117+
// Finally, do the printing
118+
Serial.print(", Accuracy (m): ");
119+
Serial.println(f_accuracy, 3); // Print the accuracy with 3 decimal places
120+
}
121+
}

keywords.txt

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -585,6 +585,12 @@ getMagAcc KEYWORD2
585585
getHeadVehValid KEYWORD2
586586

587587
getPositionAccuracy KEYWORD2
588+
getHighResECEFX KEYWORD2
589+
getHighResECEFY KEYWORD2
590+
getHighResECEFZ KEYWORD2
591+
getHighResECEFXHp KEYWORD2
592+
getHighResECEFYHp KEYWORD2
593+
getHighResECEFZHp KEYWORD2
588594

589595
getTimeOfWeekFromHPPOSLLH KEYWORD2
590596
getHighResLongitude KEYWORD2

src/SparkFun_u-blox_GNSS_Arduino_Library.cpp

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17527,6 +17527,108 @@ uint32_t SFE_UBLOX_GNSS::getPositionAccuracy(uint16_t maxWait)
1752717527
return (tempAccuracy);
1752817528
}
1752917529

17530+
// Get the current 3D high precision X coordinate
17531+
// Returns a long representing the coordinate in cm
17532+
int32_t SFE_UBLOX_GNSS::getHighResECEFX(uint16_t maxWait)
17533+
{
17534+
if (packetUBXNAVHPPOSECEF == NULL)
17535+
initPacketUBXNAVHPPOSECEF(); // Check that RAM has been allocated for the HPPOSECEF data
17536+
if (packetUBXNAVHPPOSECEF == NULL) // Bail if the RAM allocation failed
17537+
return 0;
17538+
17539+
if (packetUBXNAVHPPOSECEF->moduleQueried.moduleQueried.bits.ecefX == false)
17540+
getNAVHPPOSECEF(maxWait);
17541+
packetUBXNAVHPPOSECEF->moduleQueried.moduleQueried.bits.ecefX = false; // Since we are about to give this to user, mark this data as stale
17542+
packetUBXNAVHPPOSECEF->moduleQueried.moduleQueried.bits.all = false;
17543+
17544+
return (packetUBXNAVHPPOSECEF->data.ecefX);
17545+
}
17546+
17547+
// Get the current 3D high precision Y coordinate
17548+
// Returns a long representing the coordinate in cm
17549+
int32_t SFE_UBLOX_GNSS::getHighResECEFY(uint16_t maxWait)
17550+
{
17551+
if (packetUBXNAVHPPOSECEF == NULL)
17552+
initPacketUBXNAVHPPOSECEF(); // Check that RAM has been allocated for the HPPOSECEF data
17553+
if (packetUBXNAVHPPOSECEF == NULL) // Bail if the RAM allocation failed
17554+
return 0;
17555+
17556+
if (packetUBXNAVHPPOSECEF->moduleQueried.moduleQueried.bits.ecefY == false)
17557+
getNAVHPPOSECEF(maxWait);
17558+
packetUBXNAVHPPOSECEF->moduleQueried.moduleQueried.bits.ecefY = false; // Since we are about to give this to user, mark this data as stale
17559+
packetUBXNAVHPPOSECEF->moduleQueried.moduleQueried.bits.all = false;
17560+
17561+
return (packetUBXNAVHPPOSECEF->data.ecefY);
17562+
}
17563+
17564+
// Get the current 3D high precision Z coordinate
17565+
// Returns a long representing the coordinate in cm
17566+
int32_t SFE_UBLOX_GNSS::getHighResECEFZ(uint16_t maxWait)
17567+
{
17568+
if (packetUBXNAVHPPOSECEF == NULL)
17569+
initPacketUBXNAVHPPOSECEF(); // Check that RAM has been allocated for the HPPOSECEF data
17570+
if (packetUBXNAVHPPOSECEF == NULL) // Bail if the RAM allocation failed
17571+
return 0;
17572+
17573+
if (packetUBXNAVHPPOSECEF->moduleQueried.moduleQueried.bits.ecefZ == false)
17574+
getNAVHPPOSECEF(maxWait);
17575+
packetUBXNAVHPPOSECEF->moduleQueried.moduleQueried.bits.ecefZ = false; // Since we are about to give this to user, mark this data as stale
17576+
packetUBXNAVHPPOSECEF->moduleQueried.moduleQueried.bits.all = false;
17577+
17578+
return (packetUBXNAVHPPOSECEF->data.ecefZ);
17579+
}
17580+
17581+
// Get the high precision component of the ECEF X coordinate
17582+
// Returns a signed byte representing the component as 0.1*mm
17583+
int8_t SFE_UBLOX_GNSS::getHighResECEFXHp(uint16_t maxWait)
17584+
{
17585+
if (packetUBXNAVHPPOSECEF == NULL)
17586+
initPacketUBXNAVHPPOSECEF(); // Check that RAM has been allocated for the HPPOSECEF data
17587+
if (packetUBXNAVHPPOSECEF == NULL) // Bail if the RAM allocation failed
17588+
return 0;
17589+
17590+
if (packetUBXNAVHPPOSECEF->moduleQueried.moduleQueried.bits.ecefXHp == false)
17591+
getNAVHPPOSECEF(maxWait);
17592+
packetUBXNAVHPPOSECEF->moduleQueried.moduleQueried.bits.ecefXHp = false; // Since we are about to give this to user, mark this data as stale
17593+
packetUBXNAVHPPOSECEF->moduleQueried.moduleQueried.bits.all = false;
17594+
17595+
return (packetUBXNAVHPPOSECEF->data.ecefXHp);
17596+
}
17597+
17598+
// Get the high precision component of the ECEF Y coordinate
17599+
// Returns a signed byte representing the component as 0.1*mm
17600+
int8_t SFE_UBLOX_GNSS::getHighResECEFYHp(uint16_t maxWait)
17601+
{
17602+
if (packetUBXNAVHPPOSECEF == NULL)
17603+
initPacketUBXNAVHPPOSECEF(); // Check that RAM has been allocated for the HPPOSECEF data
17604+
if (packetUBXNAVHPPOSECEF == NULL) // Bail if the RAM allocation failed
17605+
return 0;
17606+
17607+
if (packetUBXNAVHPPOSECEF->moduleQueried.moduleQueried.bits.ecefYHp == false)
17608+
getNAVHPPOSECEF(maxWait);
17609+
packetUBXNAVHPPOSECEF->moduleQueried.moduleQueried.bits.ecefYHp = false; // Since we are about to give this to user, mark this data as stale
17610+
packetUBXNAVHPPOSECEF->moduleQueried.moduleQueried.bits.all = false;
17611+
17612+
return (packetUBXNAVHPPOSECEF->data.ecefYHp);
17613+
}
17614+
17615+
// Get the high precision component of the ECEF Z coordinate
17616+
// Returns a signed byte representing the component as 0.1*mm
17617+
int8_t SFE_UBLOX_GNSS::getHighResECEFZHp(uint16_t maxWait)
17618+
{
17619+
if (packetUBXNAVHPPOSECEF == NULL)
17620+
initPacketUBXNAVHPPOSECEF(); // Check that RAM has been allocated for the HPPOSECEF data
17621+
if (packetUBXNAVHPPOSECEF == NULL) // Bail if the RAM allocation failed
17622+
return 0;
17623+
17624+
if (packetUBXNAVHPPOSECEF->moduleQueried.moduleQueried.bits.ecefZHp == false)
17625+
getNAVHPPOSECEF(maxWait);
17626+
packetUBXNAVHPPOSECEF->moduleQueried.moduleQueried.bits.ecefZHp = false; // Since we are about to give this to user, mark this data as stale
17627+
packetUBXNAVHPPOSECEF->moduleQueried.moduleQueried.bits.all = false;
17628+
17629+
return (packetUBXNAVHPPOSECEF->data.ecefZHp);
17630+
}
17631+
1753017632
// ***** HPPOSLLH Helper Functions
1753117633

1753217634
uint32_t SFE_UBLOX_GNSS::getTimeOfWeekFromHPPOSLLH(uint16_t maxWait)

src/SparkFun_u-blox_GNSS_Arduino_Library.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1408,6 +1408,12 @@ class SFE_UBLOX_GNSS
14081408
// Helper functions for HPPOSECEF
14091409

14101410
uint32_t getPositionAccuracy(uint16_t maxWait = defaultMaxWait); // Returns the 3D accuracy of the current high-precision fix, in mm. Supported on NEO-M8P, ZED-F9P,
1411+
int32_t getHighResECEFX(uint16_t maxWait = defaultMaxWait); // Returns the ECEF X coordinate (cm)
1412+
int32_t getHighResECEFY(uint16_t maxWait = defaultMaxWait); // Returns the ECEF Y coordinate (cm)
1413+
int32_t getHighResECEFZ(uint16_t maxWait = defaultMaxWait); // Returns the ECEF Z coordinate (cm)
1414+
int8_t getHighResECEFXHp(uint16_t maxWait = defaultMaxWait); // Returns the ECEF X coordinate High Precision Component (0.1 mm)
1415+
int8_t getHighResECEFYHp(uint16_t maxWait = defaultMaxWait); // Returns the ECEF Y coordinate High Precision Component (0.1 mm)
1416+
int8_t getHighResECEFZHp(uint16_t maxWait = defaultMaxWait); // Returns the ECEF Z coordinate High Precision Component (0.1 mm)
14111417

14121418
// Helper functions for HPPOSLLH
14131419

0 commit comments

Comments
 (0)