How to store GPS initial/fixed position for distance measuring

Hello all, I am using the included code, that I've found on the internet and changed according to my needs, to transmit data such as battery voltage, motor temperature and GPS data (speed and position) from my RC model to the radio system (FlySky FS-i6).
Everything works perfectly. However, I would like to also receive the distance of the model from the home point, which is the point that the gps signal is fixed. For this, I am using the below function that already exists in TinyGPS++ library.
Now, my problem is that I do not understand how to store the coordinates as soon as the GPS signal is fixed and use them in the function to determine the distance. As it is, the distance will become 0m and stay zero because the if statement will loop forever. homeLat and homeLng are the variables that should store the initial coordinates only once. I would appreciate any suggestions. Thank you in advance. P.S. the used equipment is NEO-7M GPS and Arduino Nano.

 if (gps.location.isValid())  {
           distance = (TinyGPSPlus::distanceBetween(gps.location.lat(), gps.location.lng(), homeLat, homeLng)) ; }
        else { distance = 9999; }


  #include <iBUSTelemetry.h>     
  #include <Wire.h>
  #include <TinyGPS++.h>
  #include <SPI.h>

  TinyGPSPlus gps;

  #define UPDATE_INTERVAL 500

  #define voltagePin A0 // pin for voltage sensor
  #define tempPin    A1 // pin for temperature sensor

    // variables for GPS coordinates (initial position)
    float distance;
    float homeLat;
    float homeLng;

    iBUSTelemetry telemetry(9); // digital pin D9 for iBUS

    uint32_t prevMillis =0;  

    float meters ; 
    float voltage  = 0.0;
  
  void setup()
  {
    Serial.begin(9600);

    Wire.begin();
    telemetry.begin(); 
        
    // telemetry sensors definition
    telemetry.addSensor(IBUS_MEAS_TYPE_EXTV);       // main battery voltage
    telemetry.addSensor(IBUS_MEAS_TYPE_SPE);        // speed km/h
    telemetry.addSensor(IBUS_MEAS_TYPE_ALT);        // altitude
    telemetry.addSensor(IBUS_MEAS_TYPE_GPS_LAT);    // latitude
    telemetry.addSensor(IBUS_MEAS_TYPE_GPS_LON);    // longitude
    telemetry.addSensor(IBUS_MEAS_TYPE_GPS_STATUS); // satellite status
    telemetry.addSensor(IBUS_MEAS_TYPE_GPS_DIST);   // distance from home point
    telemetry.addSensor(IBUS_MEAS_TYPE_TEM);        // temperature       
  }

  void loop()
  { 
    updateValues(); 
    telemetry.run();  
  }

  void updateValues()
  {
    if (Serial.available()) {
        gps.encode(Serial.read()); }
  
    float meters = (gps.altitude.meters());
    voltage = float((analogRead(voltagePin)*5.00) / 204.8); // (7500/37500 = 0.2) 7500Ω = R1 , 30000Ω = R2

    // temperature reading
    int reading = analogRead(tempPin);
    float sensvolt = reading * (5000 / 1024.0);                                                 
    float temp = (sensvolt - 500);

    if (gps.location.isValid()) {
      homeLat = gps.location.lat();
      homeLng = gps.location.lng();
        exit;
      }
    
        if (gps.location.isValid())  {
           distance = (TinyGPSPlus::distanceBetween(gps.location.lat(), gps.location.lng(), homeLat, homeLng)) ; }
        else { distance = 9999; }
        
    // timeout
     uint32_t currMillis = millis();

    if (currMillis - prevMillis >= UPDATE_INTERVAL) {             
        prevMillis = currMillis;   
  
    // display of sensor data on radio control
    telemetry.setSensorValue(1, voltage*100) ;                   // main battery voltage
    telemetry.setSensorValue(2, gps.speed.kmph()*10) ;           // speed
    telemetry.setSensorValue(3, (meters)*100.0) ;                // altitude
    telemetry.setSensorValue(4, (gps.location.lat()*10000000)) ; // latitude
    telemetry.setSensorValue(5, (gps.location.lng()*10000000)) ; // longitude
    telemetry.setSensorValue(6, (gps.satellites.value())) ;      // number of sattelites
    telemetry.setSensorValue(7, distance) ;                      // distance from home point
    telemetry.setSensorValue(8, temp) ; }                        // motor temperature
    
} // end of program

Why not initially stay in setup(), or a function called from it, until the position is valid then, when it is save the current lat/long in variables as the home position that you use later on loop()

What you are doing is: "Every time the position is valid, update 'homeLat' and 'homeLng'"

What you probably want to do is:
"The FIRST time the position is valid, update 'homeLat' and 'homeLng'". To do that, set a flag when you update 'homeLat' and 'homeLng'. Don't update 'homeLat' and 'homeLng' if the flag is already set.

Hello and thank you for the reply. I am aware that the coordinates keep updating, I intentionally left the if statement to point this out. At first I was thinking if it is possible to break somehow the if statement as soon as the coordinates were updated for the first time, but your suggestion seem to be a better and simpler idea. Do you think that the below code would make sense? Haven't tried it yet.

  #include <iBUSTelemetry.h>     
  #include <Wire.h>
  #include <TinyGPS++.h>
  #include <SPI.h>

  TinyGPSPlus gps;

  #define UPDATE_INTERVAL 500

  #define voltagePin A0 // pin for voltage sensor
  #define tempPin    A1 // pin for temperature sensor

    // variables for GPS coordinates (initial position)
    float distance;
    float homeLat;
    float homeLng;

    iBUSTelemetry telemetry(9); // digital pin D9 for iBUS

    uint32_t prevMillis =0;  

    float meters ; 
    float voltage  = 0.0;

	bool myFlag = false;
  
  void setup()
  {
    Serial.begin(9600);

    Wire.begin();
    telemetry.begin(); 
        
    // telemetry sensors definition
    telemetry.addSensor(IBUS_MEAS_TYPE_EXTV);       // main battery voltage
    telemetry.addSensor(IBUS_MEAS_TYPE_SPE);        // speed km/h
    telemetry.addSensor(IBUS_MEAS_TYPE_ALT);        // altitude
    telemetry.addSensor(IBUS_MEAS_TYPE_GPS_LAT);    // latitude
    telemetry.addSensor(IBUS_MEAS_TYPE_GPS_LON);    // longitude
    telemetry.addSensor(IBUS_MEAS_TYPE_GPS_STATUS); // satellite status
    telemetry.addSensor(IBUS_MEAS_TYPE_GPS_DIST);   // distance from home point
    telemetry.addSensor(IBUS_MEAS_TYPE_TEM);        // temperature       
  }

  void loop()
  { 
    updateValues(); 
    telemetry.run();  
  }

  void updateValues()
  {
    if (Serial.available()) {
        gps.encode(Serial.read()); }

    float meters = (gps.altitude.meters());
    voltage = float((analogRead(voltagePin)*5.00) / 204.8); // (7500/37500 = 0.2) 7500Ω = R1 , 30000Ω = R2

    // temperature reading
    int reading = analogRead(tempPin);
    float sensvolt = reading * (5000 / 1024.0);                                                 
    float temp = (sensvolt - 500);

    if (gps.location.isValid()) {
       if (myFlag == false) {
        homeLat = gps.location.lat();
        homeLng = gps.location.lng();
        myFlag = true;
          }
       }
        
        if (gps.location.isValid())  {        
           distance = (TinyGPSPlus::distanceBetween(gps.location.lat(), gps.location.lng(), homeLat, homeLng)) ; }
        else { distance = 9999; }
        
    // timeout
     uint32_t currMillis = millis();

    if (currMillis - prevMillis >= UPDATE_INTERVAL) {             
        prevMillis = currMillis;   
  
    // display of sensor data on radio control
    telemetry.setSensorValue(1, voltage*100) ;                   // main battery voltage
    telemetry.setSensorValue(2, gps.speed.kmph()*10) ;           // speed
    telemetry.setSensorValue(3, (meters)*100.0) ;                // altitude
    telemetry.setSensorValue(4, (gps.location.lat()*10000000)) ; // latitude
    telemetry.setSensorValue(5, (gps.location.lng()*10000000)) ; // longitude
    telemetry.setSensorValue(6, (gps.satellites.value())) ;      // number of sattelites
    telemetry.setSensorValue(7, distance) ;                      // distance from home point
    telemetry.setSensorValue(8, temp) ; }                        // motor temperature  
} // end of program

Yes, that should work.

You don't need to check .isValid() twice:

    if (gps.location.isValid()) {
       if (myFlag == false) {
        homeLat = gps.location.lat();
        homeLng = gps.location.lng();
        myFlag = true;
       }

       distance = (TinyGPSPlus::distanceBetween(gps.location.lat(), gps.location.lng(), homeLat, homeLng)) ; 
    }
    else { distance = 9999; }

I have tested the code and works perfectly! Thank you for your suggestion.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.