Geofence Combine Code is giving 0 or 2 when the point is within the radius of the point

I am testing the Geofence functionality of the NEO-M9N Receiver Unit.

  1. When the program is first complied will start to get combined code of 1 indicating that the receiver is within the geofence

  2. After a period of time It will start returning combine status of 0 - unable t determine if the receiver is in or out of the area.

  3. Finally it will switch to a combined status of 2 - the receiver is outside of the radius.

The example code was set to a single fence by commenting out the other 3 Geofences in the example code. The single Geofence to be tested with a radius of the 500 cm.

This also happens when I take the unit outside. Sometimes it just comes up with a combined status of 2 from the start.

Would like to know if I am missing a initialization code for extended checking of the Geofence?

Hardware:

SparkFun Thing Plus/https://www.sparkfun.com/products/15663

SparkFun GPS Breakout - NEO-M9N, SMA (Qwiic)/https://www.sparkfun.com/products/17285

GPS/GNSS Magnetic Mount Antenna - 3m (SMA)/https://www.sparkfun.com/products/14986

All of the connection are using the QWIIC interface. (By the way it is feature.)

Test Software:

/*

u-blox M8 geofence example

Written by Paul Clark (PaulZC)

10th December 2019

License: MIT. See license file for more information but you can

basically do whatever you want with this code.

This example demonstrates how to use the addGeofence and getGeofenceState functions

Feel like supporting open source hardware?

Buy a board from SparkFun!

ZED-F9P RTK2: https://www.sparkfun.com/products/15136

NEO-M8P RTK: https://www.sparkfun.com/products/15005

SAM-M8Q: https://www.sparkfun.com/products/15210

ZOE-M8Q: https://www.sparkfun.com/products/15193

This example powers up the GNSS and reads the fix.

Once a valid 3D fix has been found, the code reads the latitude and longitude.

The code then sets four geofences around that position with a radii of 5m, 10m, 15m and 20m with 95% confidence.

The code then monitors the geofence status.

The LED will be illuminated if you are inside the combined geofence (i.e. within the 20m radius).

This code has been tested on the ZOE-M8Q.

*/

#define LED LED_BUILTIN // Change this if your LED is on a different pin

#include <Wire.h> // Needed for I2C

#include <SparkFun_u-blox_GNSS_Arduino_Library.h> //http://librarymanager/All#SparkFun_u-blox_GNSS

SFE_UBLOX_GNSS myGNSS;

void setup()

{

pinMode(LED, OUTPUT);

// Set up the I2C pins

Wire.begin();

// Start the console serial port

Serial.begin(115200);

while (!Serial); // Wait for the user to open the serial monitor

delay(100);

Serial.println();

Serial.println();

Serial.println(F(“u-blox M8 geofence example”));

Serial.println();

Serial.println();

delay(1000); // Let the GNSS power up

if (myGNSS.begin() == false) //Connect to the u-blox module using Wire port

{

Serial.println(F(“u-blox GNSS not detected at default I2C address. Please check wiring. Freezing.”));

while (1);

}

//myGNSS.enableDebugging(); // Enable debug messages

myGNSS.setI2COutput(COM_TYPE_UBX); // Limit I2C output to UBX (disable the NMEA noise)

//Set output to 20 times per second

// NOTE: Do not drop the frequency less than 10 Hz

// this will not allow enough memory to available for GPS Messages

myGNSS.setNavigationFrequency(20);

delay(20);

Serial.println(F(“Waiting for a 3D fix…”));

byte fixType = 0;

while (fixType < 3)

{

fixType = myGNSS.getFixType(); // Get the fix type

Serial.print(F("Fix: ")); // Print it

Serial.print(fixType);

if(fixType == 0) Serial.print(F(" = No fix"));

else if(fixType == 1) Serial.print(F(" = Dead reckoning"));

else if(fixType == 2) Serial.print(F(" = 2D"));

else if(fixType == 3) Serial.print(F(" = 3D"));

else if(fixType == 4) Serial.print(F(" = GNSS + Dead reckoning"));

else if(fixType == 5) Serial.print(F(" = Time only"));

Serial.println();

delay(1000);

}

Serial.println(F(“3D fix found!”));

long latitude = myGNSS.getLatitude(); // Get the latitude in degrees * 10^-7

Serial.print(F("Lat: "));

Serial.print(latitude);

long longitude = myGNSS.getLongitude(); // Get the longitude in degrees * 10^-7

Serial.print(F(" Long: "));

Serial.println(longitude);

uint32_t radius = 500; // Set the radius to 5m (radius is in m * 10^-2 i.e. cm)

byte confidence = 2; // Set the confidence level: 0=none, 1=68%, 2=95%, 3=99.7%, 4=99.99%

// Call clearGeofences() to clear all existing geofences.

Serial.print(F("Clearing any existing geofences. clearGeofences returned: "));

Serial.println(myGNSS.clearGeofences());

// It is possible to define up to four geofences.

// Call addGeofence up to four times to define them.

Serial.println(F(“Setting the geofences:”));

Serial.print(F("addGeofence for geofence 1 returned: "));

Serial.println(myGNSS.addGeofence(latitude, longitude, radius, confidence));

/*

radius = 1000; // 10m

Serial.print(F("addGeofence for geofence 2 returned: "));

Serial.println(myGNSS.addGeofence(latitude, longitude, radius, confidence));

radius = 1500; // 15m

Serial.print(F("addGeofence for geofence 3 returned: "));

Serial.println(myGNSS.addGeofence(latitude, longitude, radius, confidence));

radius = 2000; // 20m

Serial.print(F("addGeofence for geofence 4 returned: "));

Serial.println(myGNSS.addGeofence(latitude, longitude, radius, confidence));

*/

}

uint8_t SIV;

boolean result;

// Create storage for the geofence state

geofenceState currentGeofenceState;

void loop()

{

result = myGNSS.getGeofenceState(currentGeofenceState);

Serial.print(F("getGeofenceState returned: ")); // Print the combined state

Serial.print(result); // Get the geofence state

if (!result) // If getGeofenceState did not return true

{

Serial.println(F(“.”)); // Tidy up

return; // and go round the loop again

}

if (myGNSS.getPVT() && (myGNSS.getInvalidLlh() == false)) {

// get the number of current satellites being tracked

SIV = myGNSS.getSIV();

Serial.print(F(". # of Sat: "));

Serial.print(SIV);

} else {

Serial.print(F(“. # of Sat: 0”));

}

Serial.print(F(". status is: ")); // Print the status

Serial.print(currentGeofenceState.status);

Serial.print(F(". numFences is: ")); // Print the numFences

Serial.print(currentGeofenceState.numFences);

Serial.print(F(". combState is: ")); // Print the combined state

Serial.print(currentGeofenceState.combState);

if (currentGeofenceState.combState == 0)

{

Serial.print(F(" = Unknown"));

digitalWrite(LED, LOW);

}

if (currentGeofenceState.combState == 1)

{

Serial.print(F(" = Inside"));

digitalWrite(LED, HIGH);

}

else if (currentGeofenceState.combState == 2)

{

Serial.print(F(" = Outside"));

digitalWrite(LED, LOW);

}

Serial.print(F(". The individual states are: ")); // Print the state of each geofence

for(int i = 0; i < currentGeofenceState.numFences; i++)

{

if (i > 0) Serial.print(F(“,”));

Serial.print(currentGeofenceState.states*);*

  • }*
  • Serial.println();*
  • delay(1000);*
    }

Hello @jmcleanjr2021 ,

The behavior you are seeing is expected… Here is what is happening:

  • The geofence location is set as soon as the receiver gets a 3D fix.

  • The receiver will continue to refine its position over the next seconds and minutes. It calculates a better estimate of its position. That position could easily be more than 5m away from the initial 3D fix.
  • There are things which will help: use a larger radius for the geofence; and/or give the receiver more time to refine its position before you set the geofence.

    Best wishes,

    Paul

    Paul,

    Thanks for the reply. It is easy to forget that GPS does not work very fact until has time to settle in.

    Is there a way to know when the GPS receiver has a better fix on the location? The application i am going to be developing is automotive.

    I like to use the Horizontal Accuracy Estimate.

    Try:

    myGNSS. getHorizontalAccEst();

    You can watch the value reduce (get better) as time goes on.

    Thanks again for the help I will give it try.

    Paul,

    Just a quick question. I the ublox documentation they talk about version of the protocol. WHen I tried the getProtocolVersionHigh and getProtocolVersionLow i got 0.1 how does this relate to the u-blox protocol versions.

    Please try running Example8:

    https://github.com/sparkfun/SparkFun_u- … ersion.ino

    You should see 32.1 ? That’s the protocol version: major.minor.