gps geofence - compile error

srnet:
Using the first fix as the location is not a good idea, you likley need to wait a good minute or more for the location to stabilise. And then detecting a movement of as little as 3.3m might be ambitious. Variations of 3-10m in position are not unusual for a stationary GPS.

Also depends where the GPS actually is, what is the application ?

I am trying to write an application for marine use
I want to save the first good fix and then compare the saved coords to the current coords the gps has.
please see my latest code
I know its wrong
but I dont know how to fix it.

#include <TinyGPS++.h> // Include the TinyGPS++ library
TinyGPSPlus gps; // Create a TinyGPSPlus object


#define GPS_BAUD 9600 // GPS module baud rate


#define ARDUINO_GPS_RX 14 // GPS TX, Arduino RX pin
#define ARDUINO_GPS_TX 13 // GPS RX, Arduino TX pin


// Define the serial monitor port. On the Uno, and Leonardo this is 'Serial'
//  on other boards this may be 'SerialUSB'
#define SerialMonitor Serial






double GPSlock()
{
    float initialLat;
    float initialLng;


  while (Serial1.available() > 0) {
    gps.encode(Serial1.read());
  }


  if ( gps.satellites.value() >= 1 && gps.hdop.hdop() <= 6 && gps.sentencesWithFix() > 1) {


float    initialLat = gps.location.lat();
float    initialLng = gps.location.lng();
    SerialMonitor.print("initialLat: ");
    Serial.println(initialLat, 6);
    SerialMonitor.print("initialLng: ");
    Serial.println(initialLng, 6);
  }
    return  initialLat;  initialLng;


}






void setup() {
   SerialMonitor.begin(9600);
  Serial1.begin(GPS_BAUD);
 
}


void loop() {
 
 
 Serial.println(GPSlock());
 delay(1000);


}

A function can return only one value. The statement after the first semicolon does nothing.

    return  initialLat;  initialLng;

If you make these two variables global (declare them outside of any function), then all parts of your program can access them.

    float initialLat;
    float initialLng;

You really need to brush up on (or learn) the basics of C/C++ programming. We strongly recommend to study the examples that come with the Arduino IDE, and relevant examples of the many on-line programming tutorials.

yantypas:
I am trying to write an application for marine use
I want to save the first good fix and then compare the saved coords to the current coords the gps has.
please see my latest code
I know its wrong
but I dont know how to fix it.

The code in post 13 did not give you a clue? Hummm, well I tried.

Any help greatly appreciated!

I;m trying to find a way to save gps data in order to juxstapose it to real time data

thank you.

Idahowalker:
The code in post 13 did not give you a clue? Hummm, well I tried.

I thought its too complicated for what I am trying to do but I;ll give it a shot.
thank you for your effort.
I am an absolute beginner.
Y

For an "absolute beginner" you have picked a difficult project.

Expect a lot of frustration, trying to run before learning to crawl.

Thank you for your answer jremington,

I have a concept for a prototype and I will do anything to make it happen.
crawl, run, fly, you name it.

Y

If you are thinking of making a commercial product, such as a GPS movement detector or anti-theft device, those have been available for a long time.

For assistance writing advanced code, consider posting on the Gigs and Collaborations forum section. You may be asked to pay for the help.

Thank you.

Hello Idahowalker,

thank you :slight_smile: very much for sharing you knowledge with me.
I am still trying to make it work but I fail. I cannot understand how you manage to save the fix on - lGPS_Lat0, lGPS_Lon0, tempLat, tempLon - separately!
I have been altering the code (I tried to use TinyGPSPlus::distanceBetween to calc the distance because I am interested in distances less than a meter (cm).

I appreciate any help

DEBUG

23:53:02.986 -> templat :101
23:53:02.986 -> tempLon :35
23:53:02.986 -> lGPS_Lat0 :101
23:53:02.986 -> lGPS_Lon0 :35
23:53:02.986 -> lDistance :0

#include <TinyGPS++.h>    // Include the TinyGPS++ library
TinyGPSPlus gps;          // Create a TinyGPSPlus object

#define GPS_BAUD 9600     // GPS module baud rate
#define ARDUINO_GPS_RX 14 // GPS TX, Arduino RX pin
#define ARDUINO_GPS_TX 13 // GPS RX, Arduino TX pin
#define debug Serial

long lGPS_Lat0 = 0;
long lGPS_Lon0 = 0;
int  lDistance = 0;

byte DistaceResetPin = 3;
byte StartStopDistanceCounterPin = 5;

void fCalDistance()
{


  if (digitalRead(StartStopDistanceCounterPin) == LOW)
  {
    //get lat lon values if lat is 0
    StartStopDistanceCounter();
    
    long tempLat = gps.location.lat();
    long tempLon = gps.location.lng();

    //add new distance to previous distance
    lDistance = lDistance + TinyGPSPlus::distanceBetween(lGPS_Lat0, lGPS_Lon0, tempLat, tempLon);

    //reset to last used measuring point
    lGPS_Lat0 = tempLat;
    lGPS_Lon0 = tempLon;

    debug.print(F("templat :"));   Serial.println(tempLat, 6);
    debug.print(F("tempLon :"));   Serial.println(tempLon, 6);
    debug.print(F("lGPS_Lat0 :")); Serial.println(lGPS_Lat0, 6);
    debug.print(F("lGPS_Lon0 :")); Serial.println(lGPS_Lon0, 6);
    debug.print(F("lDistance :")); Serial.println(lDistance, 6);

    smartDelay(0);
  }

}
void StartStopDistanceCounter()
{
  if (lGPS_Lat0 == 0)
  {
    //save starting lat n lon if needed
    lGPS_Lat0 = gps.location.lat();
    lGPS_Lon0 = gps.location.lng();

    smartDelay(0);
  }
}
void ResetDistanceCounter()
{

  if (digitalRead(DistaceResetPin) == HIGH)
  {
    //byteUpdateDistanceInterval = 0;
    lDistance = 0;
    lGPS_Lat0 = 0;
    lGPS_Lon0 = 0;

  }
}
void gpsInfo()
{
  // Print latitude, longitude, altitude in feet, course, speed, date, time,
  // and the number of visible satellites.

  debug.println();
  debug.print(F("Alt in m: ")); debug.println(gps.altitude.meters(), 2);
  debug.print(F("Sats: ")); debug.println(gps.satellites.value());
  debug.print(F("HDOP: ")); debug.println(gps.hdop.hdop(), 1);
  debug.print(F("Sentences With Fix: ")); debug.println(gps.sentencesWithFix());
  debug.print(F("Lat: ")); debug.println(gps.location.lat(), 6);
  debug.print(F("Long: ")); debug.println(gps.location.lng(), 6);
  debug.println();
  
  /*debug.print(F("https://www.google.com/maps/?q="));
  debug.print(gps.location.lat(), 6);
  debug.print(F(","));
  debug.print(gps.location.lng(), 6);
  */
  
  debug.println();
  smartDelay(1000);

}

static void smartDelay(unsigned long ms)
{
  unsigned long start = millis();
  do
  {
    while (Serial1.available())
      gps.encode(Serial1.read());
  } 
  while (millis() - start < ms);
}

void setup() {

  Serial.begin(GPS_BAUD);
  Serial1.begin(GPS_BAUD);

  pinMode(StartStopDistanceCounterPin, INPUT); //StartStopDistanceCounter
  pinMode(DistaceResetPin, INPUT);    //DistaceReset

}

void loop() {

  fCalDistance();
  StartStopDistanceCounter();
  ResetDistanceCounter();
  gpsInfo();
  smartDelay(0);
  
}

From the topic Re: How to parse RAW Lat and Long TinyGPS++ post number 4 by
jremington
on how to convert TinyGPS++ raw values to a long integer.

https://forum.arduino.cc/index.php?topic=706479.0

long scale=10000000UL;
long lat = gps.location.rawLat().deg*scale+gps.location.rawLat().billionths/100UL;
if(gps.location.rawLat().negative) lat=-lat;
long lon = gps.location.rawLng().deg*scale+gps.location.rawLng().billionths/100UL;
if(gps.location.rawLng().negative) lon=-lon;

If you are using a Uno/Mega (8/16 bit) you will lose precision.

Using TinyGPS++ distance between TinyGPS++ using distanceBetween - Libraries - Particle

https://community.particle.io/t/tinygps-using-distancebetween/2823

Thank you again for helping me,

I get the following error:

collect2: error: ld returned 1 exit status
exit status 1
Error compiling for board Arduino MKR WiFi 1010.

I am willing to pay for the solution.

King Regards,

Yannis

#include <TinyGPS++.h> // Include the TinyGPS++ library

TinyGPSPlus gps; // Create a TinyGPSPlus object

#define GPS_BAUD 9600 // GPS module baud rate
#define ARDUINO_GPS_RX 14 // GPS TX, Arduino RX pin
#define ARDUINO_GPS_TX 13 // GPS RX, Arduino TX pin
#define debug Serial

long lGPS_Lat0 = 0;
long lGPS_Lon0 = 0;
int  lDistance = 0;

byte DistaceResetPin = 3;
byte StartStopDistanceCounterPin = 5; 

long scale = 10000000UL;
long lat;
long lon;

double makeCoords() // get coordinates from GPS
{

  smartDelay(0);

  long lat = gps.location.rawLat().deg * scale + gps.location.rawLat().billionths / 100UL;
  if (gps.location.rawLat().negative) lat = -lat;
  long lon = gps.location.rawLng().deg * scale + gps.location.rawLng().billionths / 100UL;
  if (gps.location.rawLng().negative) lon = -lon;

}

void fCalDistance()
{


  if (digitalRead(StartStopDistanceCounterPin) == LOW)
  {
    //get lat lon values if lat is 0
    StartStopDistanceCounter();

    long tempLat = lat;
    long tempLon = lon;

    //add new distance to previous distance
    lDistance = (lDistance + TinyGPSPlus::distanceBetween(lGPS_Lat0, lGPS_Lon0, tempLat, tempLon));

    //reset to last used measuring point
    lGPS_Lat0 = tempLat;
    lGPS_Lon0 = tempLon;

    debug.print("templat :");   Serial.println((tempLat), 6);
    debug.print("tempLon :");   Serial.println((tempLon), 6);
    debug.print("lGPS_Lat0 :"); Serial.println((lGPS_Lat0), 6);
    debug.print("lGPS_Lon0 :"); Serial.println((lGPS_Lon0), 6);
    debug.print("lDistance :"); Serial.println((lDistance), 6);

    smartDelay(0);
  }

}

void StartStopDistanceCounter()
{
  if (lGPS_Lat0 == 0)
  {
    //save starting lat n lon if needed
    lGPS_Lat0 = gps.location.lat();
    lGPS_Lon0 = gps.location.lng();

    smartDelay(0);
  }
}

void ResetDistanceCounter()
{

  if (digitalRead(DistaceResetPin) == HIGH)
  {
    //byteUpdateDistanceInterval = 0;
    lDistance = 0;
    lGPS_Lat0 = 0;
    lGPS_Lon0 = 0;

  }
}

void gpsInfo()
{
  // Print latitude, longitude, altitude in feet, course, speed, date, time,
  // and the number of visible satellites.


  debug.print("Sats: "); debug.println(gps.satellites.value());
  debug.print("HDOP: "); debug.println(gps.hdop.hdop(), 1);
  debug.print("Sentences With Fix: "); debug.println(gps.sentencesWithFix());

  debug.print("Lat: "); debug.println(gps.location.lat(), 6);
  debug.print("Long: "); debug.println(gps.location.lng(), 6);

  debug.println();
  smartDelay(1000);

}

static void smartDelay(unsigned long ms) 

{
  unsigned long start = millis();
  do
  {
    while (Serial1.available())
      gps.encode(Serial1.read());
  } 
  while (millis() - start < ms);
}


/* static */
double TinyGPSPlus::distanceBetween(double lGPS_Lat0, double lGPS_Lon0, double tempLat, double tempLon)
{
  // returns distance in meters between two positions, both specified
  // as signed decimal-degrees latitude and longitude. Uses great-circle
  // distance computation for hypothetical sphere of radius 6372795 meters.
  // Because Earth is no exact sphere, rounding errors may be up to 0.5%.
  // Courtesy of Maarten Lamers

 
  double delta = radians(lGPS_Lat0 - tempLon);
  double sdlong = sin(delta);
  double cdlong = cos(delta);
  lGPS_Lat0 = radians(lGPS_Lat0);
  tempLat = radians(tempLat);
  double slGPS_Lat0 = sin(lGPS_Lat0);
  double clGPS_Lat0 = cos(lGPS_Lat0);
  double stempLat = sin(tempLat);
  double ctempLat = cos(tempLat);
  delta = (clGPS_Lat0 * stempLat) - (slGPS_Lat0 * ctempLat * cdlong);
  delta = sq(delta);
  delta += sq(ctempLat * sdlong);
  delta = sqrt(delta);
  double denom = (slGPS_Lat0 * stempLat) + (clGPS_Lat0 * ctempLat * cdlong);
  delta = atan2(delta, denom);
  return delta * 6372795;
}

void setup() {

  Serial.begin(GPS_BAUD);
  Serial1.begin(GPS_BAUD);

  pinMode(StartStopDistanceCounterPin, INPUT);  //StartStopDistanceCounter
  pinMode(DistaceResetPin, INPUT);    //DistaceReset


  //pinMode(13, INPUT);  //GPS RX
  //pinMode(14, OUTPUT); //GPS TX


  digitalWrite(7, LOW);
  digitalWrite(12, LOW);

}

void loop() {

  while (Serial1.available())
    gps.encode(Serial1.read());

  fCalDistance();
  StartStopDistanceCounter();
  ResetDistanceCounter();
  gpsInfo();
  makeCoords();
  smartDelay(0);


}

Sorry, don't know what a collect2 error is. Try gigs and collaborations.

yantypas:
I have been altering the code (I tried to use TinyGPSPlus::distanceBetween to calc the distance because I am interested in distances less than a meter (cm).

GPS isn't that accurate. On a good day, you can get a position within three meters, but it may be substantially worse. Try leaving your GPS in place and have it spit out its position. Usually the position drifts gently and occasionally leaps multiple meters away. Trying to do anything with centimeters is going to be impractical.

Differential GPS will do better, but I suspect even that would not give you the accuracy you're looking for.

wildbill:
GPS isn't that accurate. On a good day, you can get a position within three meters, but it may be substantially worse.

I frequently test GPSs in my garden, 3m is indeed good and a 10m variation is not that unusual.

If there was a cunning wheeze way of using code (with non differential GPSs) to improve on that much, you would assume everyone would be doing it and\or the code would be built into the GPS .......................

How about that ZED-F9P module ?

It's super accurate if you're using RTK - i.e. you need a base station transmitting position corrections. Without it, Sparkfun's version boasts 2.5m accuracy, which is probably best case.

Hello,

please help me find the mistake

I am getting this printed out in the serial monitor:

01:15:33.642 -> makeCoords
01:15:33.642 -> lGPS_Lat0 = 551424425
01:15:33.642 -> lGPS_Lon0 = 441102220
01:15:33.642 -> tempLat = 0
01:15:33.642 -> tempLon = 0
01:15:33.642 -> distance = 16782150
01:15:33.642 ->
01:15:33.642 -> Lat: 37.987910
01:15:33.642 -> Long: 23.789313
01:15:33.642 -> rawLat: 379879100
01:15:33.642 -> rawLong: 237893133
01:15:33.642 -> Sats: 4
01:15:33.642 -> HDOP: 1.8

#include <TinyGPS++.h> // Include the TinyGPS++ library
TinyGPSPlus gps; // Create a TinyGPSPlus object

#define GPS_BAUD 9600 // GPS module baud rate
#define ARDUINO_GPS_RX 14 // GPS TX, Arduino RX pin
#define ARDUINO_GPS_TX 13 // GPS RX, Arduino TX pin
#define debug Serial

int  lDistance = 0;
byte DistaceResetPin = 3;
byte makeCoordsPin = 5;
long scale = 10000000UL;

long distance;

long lGPS_Lat0 = 0;
long lGPS_Lon0 = 0;

long tempLat = 0;
long tempLon = 0;

double calcDistance()
{

distance = TinyGPSPlus::distanceBetween(lGPS_Lat0, lGPS_Lon0, tempLat, tempLon);


}

double makeCoords()
{
  if (digitalRead(makeCoordsPin) == HIGH)
  {

     long  tempLat = gps.location.rawLat().deg  + gps.location.rawLat().billionths / 100UL;
     long  tempLon = gps.location.rawLng().deg  + gps.location.rawLng().billionths / 100UL;
    
    lGPS_Lat0 = tempLat;
    lGPS_Lon0 = tempLon;
  }
}

double resetCoords()
{
  if (digitalRead(DistaceResetPin) == HIGH)
  {
 
    lGPS_Lat0 = 0;
    lGPS_Lon0 = 0;
    
  }
}


void setup() {

  debug.begin(GPS_BAUD);
  Serial1.begin(GPS_BAUD);

  pinMode(makeCoordsPin, INPUT);


}

void loop() {

  while (Serial1.available())
  gps.encode(Serial1.read());
  
  makeCoords();
  printInfo();
  resetCoords();
  calcDistance();

}
void printInfo()
{
  debug.println();
  debug.println("makeCoords");
  debug.print("lGPS_Lat0 = "); debug.println(lGPS_Lat0, 6);
  debug.print("lGPS_Lon0 = "); debug.println(lGPS_Lon0, 6);
  debug.print("tempLat = "); debug.println(tempLat, 6);
  debug.print("tempLon = "); debug.println(tempLon, 6);
  debug.print("distance = "); debug.println(distance);
  debug.println();
  debug.print("Lat: ");  debug.println(gps.location.lat(), 6);
  debug.print("Long: "); debug.println(gps.location.lng(), 6);
  debug.print("rawLat: ");  debug.println(gps.location.rawLat().deg * scale + gps.location.rawLat().billionths / 100UL);
  debug.print("rawLong: "); debug.println(gps.location.rawLng().deg * scale + gps.location.rawLng().billionths / 100UL);
  debug.print("Sats: "); debug.println(gps.satellites.value());
  debug.print("HDOP: "); debug.println(gps.hdop.hdop(), 1);
  delay(1000);
}

your templat and templong are your last position. If your last position is zero and your current position is something, then you've traveled a great distance.

TinyGPSPlus::distanceBetween(currLat, currLong, lastLat, lastLong)

It's all in the documentation.

If your last last and long are zero then put the current lat and long into templat templong to give them a starting point.

Hey,

thank you againg for taking the time to help me!
Really really appreciate your messages. I know very little about coding and arduino and you helped me a lot!
I think this works.. Im nit sure because my breadboard/wires dont work well and I have ti fix them by hand in order to get values. But I managed to set BASE coords (tempLat & tempLong) at some point..

Please see below:
(I think its the right version of code)

#include <TinyGPS++.h> // Include the TinyGPS++ library
TinyGPSPlus gps; // Create a TinyGPSPlus object

#define GPS_BAUD 9600 // GPS module baud rate
#define ARDUINO_GPS_RX 14 // GPS TX, Arduino RX pin
#define ARDUINO_GPS_TX 13 // GPS RX, Arduino TX pin
#define debug Serial

int  lDistance = 0;
byte DistaceResetPin = 3;
byte makeCoordsPin = 5;
long scale = 10000000UL;

long distance;

long gpsLat0;
long gpsLon0;

long tempLat;
long tempLon;



double calcDistance()
{
  distance = TinyGPSPlus::distanceBetween(gpsLat0, gpsLon0, tempLat, tempLon);
  // returns distance in meters between two positions, both specified
  // as signed decimal-degrees latitude and longitude. Uses great-circle
  // distance computation for hypothetical sphere of radius 6372795 meters.
  // Because Earth is no exact sphere, rounding errors may be up to 0.5%.
  // Courtesy of Maarten Lamers
  double delta = radians(gpsLon0-tempLon);
  double sdlong = sin(delta);
  double cdlong = cos(delta);
  gpsLat0 = radians(gpsLat0);
  tempLat = radians(tempLat);
  double slat1 = sin(gpsLat0);
  double clat1 = cos(gpsLat0);
  double slat2 = sin(tempLat);
  double clat2 = cos(tempLat);
  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 makeCoords()
{

  gpsLat0 = gps.location.rawLat().deg * scale + gps.location.rawLat().billionths / 100UL;
  gpsLon0 = gps.location.rawLng().deg * scale + gps.location.rawLng().billionths / 100UL;
}

double makeCoords2()
{
  if (digitalRead(makeCoordsPin) == HIGH)

  {
   gpsLat0 = gps.location.rawLat().deg * scale + gps.location.rawLat().billionths / 100UL;
   gpsLon0 = gps.location.rawLng().deg * scale + gps.location.rawLng().billionths / 100UL;
   
   //pass the current coords to tempLat & tempLong
   tempLat = gpsLat0;
   tempLon = gpsLon0;
   
  }
  else {
    //do nothing
  }
}
  double resetCoords()
  {
    if (digitalRead(DistaceResetPin) == HIGH)
    {
      //reset all coords values
      gpsLat0 = 0;
      gpsLon0 = 0;
      tempLat = 0;
      tempLon = 0;

    }
  }


  void setup() {

    debug.begin(GPS_BAUD);
    Serial1.begin(GPS_BAUD);

    pinMode(makeCoordsPin, INPUT);


  }

  void loop() {


    makeCoords();
    printInfo();
    resetCoords();
    calcDistance();
    makeCoords2();

  }

  void printInfo()
  {

    while (Serial1.available())
    {
      gps.encode(Serial1.read());
    }

    debug.println();
    debug.println("makeCoords");
    debug.print("gpsLat0 = "); debug.println(gpsLat0);
    debug.print("gpsLon0 = "); debug.println(gpsLon0);
    debug.print("tempLat = "); debug.println(tempLat);
    debug.print("tempLon = "); debug.println(tempLon);
    debug.print("distance = "); debug.print(distance / 100000); debug.println(" m");
    debug.println();
    debug.print("Lat: ");  debug.println(gps.location.lat(), 6);
    debug.print("Long: "); debug.println(gps.location.lng(), 6);
    debug.print("rawLat: ");  debug.println(gps.location.rawLat().deg * scale + gps.location.rawLat().billionths / 100UL);
    debug.print("rawLong: "); debug.println(gps.location.rawLng().deg * scale + gps.location.rawLng().billionths / 100UL);
    debug.print("Sats: "); debug.println(gps.satellites.value());
    debug.print("HDOP: "); debug.println(gps.hdop.hdop(), 1);
    delay(1000);
  }