|
| 1 | +/* |
| 2 | + Get the high precision geodetic solution for latitude and longitude using double |
| 3 | + By: Nathan Seidle |
| 4 | + Modified by: Paul Clark (PaulZC) |
| 5 | + SparkFun Electronics |
| 6 | + Date: April 17th, 2020 |
| 7 | + License: MIT. See license file for more information but you can |
| 8 | + basically do whatever you want with this code. |
| 9 | +
|
| 10 | + This example shows how to inspect the accuracy of the high-precision |
| 11 | + positional solution. Please see below for information about the units. |
| 12 | +
|
| 13 | + ** This example will only work correctly on platforms which support 64-bit double ** |
| 14 | +
|
| 15 | + Feel like supporting open source hardware? |
| 16 | + Buy a board from SparkFun! |
| 17 | + ZED-F9P RTK2: https://www.sparkfun.com/products/15136 |
| 18 | + NEO-M8P RTK: https://www.sparkfun.com/products/15005 |
| 19 | +
|
| 20 | + Hardware Connections: |
| 21 | + Plug a Qwiic cable into the GPS and (e.g.) a Redboard Artemis https://www.sparkfun.com/products/15444 |
| 22 | + or an Artemis Thing Plus https://www.sparkfun.com/products/15574 |
| 23 | + If you don't have a platform with a Qwiic connection use the SparkFun Qwiic Breadboard Jumper (https://www.sparkfun.com/products/14425) |
| 24 | + Open the serial monitor at 115200 baud to see the output |
| 25 | +*/ |
| 26 | + |
| 27 | +#include <Wire.h> // Needed for I2C to GPS |
| 28 | + |
| 29 | +#define myWire Wire // This will work on the Redboard Artemis and the Artemis Thing Plus using Qwiic |
| 30 | +//#define myWire Wire1 // Uncomment this line if you are using the extra SCL1/SDA1 pins (D17 and D16) on the Thing Plus |
| 31 | + |
| 32 | +#include "SparkFun_Ublox_Arduino_Library.h" //http://librarymanager/All#SparkFun_Ublox_GPS |
| 33 | +SFE_UBLOX_GPS myGPS; |
| 34 | + |
| 35 | +long lastTime = 0; //Simple local timer. Limits amount if I2C traffic to Ublox module. |
| 36 | + |
| 37 | +void setup() |
| 38 | +{ |
| 39 | + Serial.begin(115200); |
| 40 | + while (!Serial); //Wait for user to open terminal |
| 41 | + |
| 42 | + myWire.begin(); |
| 43 | + |
| 44 | + //myGPS.enableDebugging(Serial); // Uncomment this line to enable debug messages |
| 45 | + |
| 46 | + if (myGPS.begin(myWire) == false) //Connect to the Ublox module using Wire port |
| 47 | + { |
| 48 | + Serial.println(F("Ublox GPS not detected at default I2C address. Please check wiring. Freezing.")); |
| 49 | + while (1) |
| 50 | + ; |
| 51 | + } |
| 52 | + |
| 53 | + // Check that this platform supports 64-bit (8 byte) double |
| 54 | + if (sizeof(double) < 8) |
| 55 | + { |
| 56 | + Serial.println(F("Warning! Your platform does not support 64-bit double.")); |
| 57 | + Serial.println(F("The latitude and longitude will be inaccurate.")); |
| 58 | + } |
| 59 | + |
| 60 | + myGPS.setI2COutput(COM_TYPE_UBX); //Set the I2C port to output UBX only (turn off NMEA noise) |
| 61 | + |
| 62 | + //myGPS.setNavigationFrequency(20); //Set output to 20 times a second |
| 63 | + |
| 64 | + byte rate = myGPS.getNavigationFrequency(); //Get the update rate of this module |
| 65 | + Serial.print("Current update rate: "); |
| 66 | + Serial.println(rate); |
| 67 | + |
| 68 | + //myGPS.saveConfiguration(); //Save the current settings to flash and BBR |
| 69 | +} |
| 70 | + |
| 71 | +void loop() |
| 72 | +{ |
| 73 | + //Query module only every second. |
| 74 | + //The module only responds when a new position is available. |
| 75 | + if (millis() - lastTime > 1000) |
| 76 | + { |
| 77 | + lastTime = millis(); //Update the timer |
| 78 | + |
| 79 | + // getHighResLatitude: returns the latitude from HPPOSLLH as an int32_t in degrees * 10^-7 |
| 80 | + // getHighResLatitudeHp: returns the high resolution component of latitude from HPPOSLLH as an int8_t in degrees * 10^-9 |
| 81 | + // getHighResLongitude: returns the longitude from HPPOSLLH as an int32_t in degrees * 10^-7 |
| 82 | + // getHighResLongitudeHp: returns the high resolution component of longitude from HPPOSLLH as an int8_t in degrees * 10^-9 |
| 83 | + // getElipsoid: returns the height above ellipsoid as an int32_t in mm |
| 84 | + // getElipsoidHp: returns the high resolution component of the height above ellipsoid as an int8_t in mm * 10^-1 |
| 85 | + // getMeanSeaLevel: returns the height above mean sea level as an int32_t in mm |
| 86 | + // getMeanSeaLevelHp: returns the high resolution component of the height above mean sea level as an int8_t in mm * 10^-1 |
| 87 | + // getHorizontalAccuracy: returns the horizontal accuracy estimate from HPPOSLLH as an uint32_t in mm * 10^-1 |
| 88 | + |
| 89 | + // First, let's collect the position data |
| 90 | + int32_t latitude = myGPS.getHighResLatitude(); |
| 91 | + int8_t latitudeHp = myGPS.getHighResLatitudeHp(); |
| 92 | + int32_t longitude = myGPS.getHighResLongitude(); |
| 93 | + int8_t longitudeHp = myGPS.getHighResLongitudeHp(); |
| 94 | + int32_t ellipsoid = myGPS.getElipsoid(); |
| 95 | + int8_t ellipsoidHp = myGPS.getElipsoidHp(); |
| 96 | + int32_t msl = myGPS.getMeanSeaLevel(); |
| 97 | + int8_t mslHp = myGPS.getMeanSeaLevelHp(); |
| 98 | + uint32_t accuracy = myGPS.getHorizontalAccuracy(); |
| 99 | + |
| 100 | + // Defines storage for the lat and lon as double |
| 101 | + double d_lat; // latitude |
| 102 | + double d_lon; // longitude |
| 103 | + |
| 104 | + // Assemble the high precision latitude and longitude |
| 105 | + d_lat = ((double)latitude) / 10000000.0; // Convert latitude from degrees * 10^-7 to degrees |
| 106 | + d_lat += ((double)latitudeHp) / 1000000000.0; // Now add the high resolution component (degrees * 10^-9 ) |
| 107 | + d_lon = ((double)longitude) / 10000000.0; // Convert longitude from degrees * 10^-7 to degrees |
| 108 | + d_lon += ((double)longitudeHp) / 1000000000.0; // Now add the high resolution component (degrees * 10^-9 ) |
| 109 | + |
| 110 | + // Print the lat and lon |
| 111 | + Serial.print("Lat (deg): "); |
| 112 | + Serial.print(d_lat, 9); |
| 113 | + Serial.print(", Lon (deg): "); |
| 114 | + Serial.print(d_lon, 9); |
| 115 | + |
| 116 | + // Now define float storage for the heights and accuracy |
| 117 | + float f_ellipsoid; |
| 118 | + float f_msl; |
| 119 | + float f_accuracy; |
| 120 | + |
| 121 | + // Calculate the height above ellipsoid in mm * 10^-1 |
| 122 | + f_ellipsoid = (ellipsoid * 10) + ellipsoidHp; |
| 123 | + // Now convert to m |
| 124 | + f_ellipsoid = f_ellipsoid / 10000.0; // Convert from mm * 10^-1 to m |
| 125 | + |
| 126 | + // Calculate the height above mean sea level in mm * 10^-1 |
| 127 | + f_msl = (msl * 10) + mslHp; |
| 128 | + // Now convert to m |
| 129 | + f_msl = f_msl / 10000.0; // Convert from mm * 10^-1 to m |
| 130 | + |
| 131 | + // Convert the horizontal accuracy (mm * 10^-1) to a float |
| 132 | + f_accuracy = accuracy; |
| 133 | + // Now convert to m |
| 134 | + f_accuracy = f_accuracy / 10000.0; // Convert from mm * 10^-1 to m |
| 135 | + |
| 136 | + // Finally, do the printing |
| 137 | + Serial.print(", Ellipsoid (m): "); |
| 138 | + Serial.print(f_ellipsoid, 4); // Print the ellipsoid with 4 decimal places |
| 139 | + |
| 140 | + Serial.print(", Mean Sea Level (m): "); |
| 141 | + Serial.print(f_msl, 4); // Print the mean sea level with 4 decimal places |
| 142 | + |
| 143 | + Serial.print(", Accuracy (m): "); |
| 144 | + Serial.println(f_accuracy, 4); // Print the accuracy with 4 decimal places |
| 145 | + } |
| 146 | +} |
0 commit comments