Skip to main content

NEO-M9N-00B - Great Circle Distance

This page contains an example of calculating the distance and bearing from the module's current position to a fixed target location, using a great-circle (Haversine-based) distance calculation.


Initialization

Include the required libraries, create the module object, and add two helper functions for calculating distance and bearing between two coordinates:

#include <Wire.h>
#include <Soldered-GNSS.h>

Soldered_GNSS myGNSS;

long lastTime = 0;

double distanceBetween(long lat1_l, long long1_l, long lat2_l, long long2_l)
{
// Returns distance in meters between two positions using a great-circle
// calculation on a sphere of radius 6372795 m. Rounding errors of up to
// 0.5% are possible since Earth isn't a perfect sphere.
double lat1 = (double)lat1_l / 10000000.0;
double long1 = (double)long1_l / 10000000.0;
double lat2 = (double)lat2_l / 10000000.0;
double long2 = (double)long2_l / 10000000.0;

double delta = radians(long1 - long2);
double sdlong = sin(delta);
double cdlong = cos(delta);
lat1 = radians(lat1);
lat2 = radians(lat2);
double slat1 = sin(lat1);
double clat1 = cos(lat1);
double slat2 = sin(lat2);
double clat2 = cos(lat2);
delta = (clat1 * slat2) - (slat1 * clat2 * cdlong);
delta = sq(delta);
delta += sq(clat2 * sdlong);
delta = sqrt(delta);
double denom = (slat1 * slat2) + (clat1 * clat2 * cdlong);
delta = atan2(delta, denom);
return delta * 6372795;
}

double courseTo(long lat1_l, long long1_l, long lat2_l, long long2_l)
{
// Returns course in degrees (North = 0, West = 270) from position 1 to position 2
double lat1 = (double)lat1_l / 10000000.0;
double long1 = (double)long1_l / 10000000.0;
double lat2 = (double)lat2_l / 10000000.0;
double long2 = (double)long2_l / 10000000.0;

double dlon = radians(long2 - long1);
lat1 = radians(lat1);
lat2 = radians(lat2);
double a1 = sin(dlon) * cos(lat2);
double a2 = sin(lat1) * cos(lat2) * cos(dlon);
a2 = cos(lat1) * sin(lat2) - a2;
a2 = atan2(a1, a2);
if (a2 < 0.0)
{
a2 += TWO_PI;
}
return degrees(a2);
}

In the setup() function, initialize the module:

void setup()
{
Serial.begin(115200);
while (!Serial);
Serial.println("Soldered u-blox GNSS Example - Great Circle Distance");

Wire.begin();

if (myGNSS.begin() == false)
{
Serial.println(F("u-blox GNSS not detected at default I2C address. Please check wiring. Freezing."));
while (1);
}

myGNSS.setI2COutput(COM_TYPE_UBX);
myGNSS.saveConfigSelective(VAL_CFG_SUBSEC_IOPORT);
}

myGNSS.begin()

Initializes the GNSS module and establishes I2C communication

Returns value: Boolean value, true if the module is detected and communication succeeds, false otherwise


Taking measurements

Set your target coordinates, then in the loop() function the module is polled once per second to compute the distance and bearing to that target:

static const long TARGET_LAT = 400909142, TARGET_LON = -1051849833; // Set your own target: degrees * 10^-7

void loop()
{
if (millis() - lastTime > 1000)
{
lastTime = millis();

long latitude = myGNSS.getLatitude();
long longitude = myGNSS.getLongitude();

Serial.print(F("Lat: "));
Serial.print(latitude);
Serial.print(F(" Long: "));
Serial.println(longitude);

double distanceToTarget = distanceBetween(latitude, longitude, TARGET_LAT, TARGET_LON);
Serial.print(F("Distance to target: "));
Serial.print(distanceToTarget, 2);
Serial.print(F(" (m) "));

double courseToTarget = courseTo(latitude, longitude, TARGET_LAT, TARGET_LON);
Serial.print(F("Course to target: "));
Serial.print(courseToTarget, 1);
Serial.println(F(" (degrees)"));
}
}
Serial monitor great circle distance readings
Serial monitor

myGNSS.getLatitude()

Reads the current latitude from the GNSS module

Returns value: Long value, latitude in degrees multiplied by 10^-7

myGNSS.getLongitude()

Reads the current longitude from the GNSS module

Returns value: Long value, longitude in degrees multiplied by 10^-7

ℹ️
The distanceBetween() and courseTo() helper functions aren't part of the library itself, they're plain C++ math included directly in the sketch, adapted from the widely-used TinyGPSPlus library.

Full example

You can find the full sketch below:

Great_Circle_Distance.ino

An example of calculating distance and bearing to a target location with the NEO-M9N-00B module