aiuto per gps logger distanza percorsa

Buongiorno a tutti, sto modificando uno sketch di un gps logger trovato su project hub.

questo https://create.arduino.cc/projecthub/yvesmorele/rc-loggerstation-gps-data-logger-for-rc-plane-3ea4cd

vorrei riuscire ad aggiungere un dato relativo alla distanza percorsa dall'accensione e fix.

al momento il progetto funziona tutto eccetto la parte relativa a "dist" che vorrei fosse la distanza che viene percorsa.
al massimo avrà da percorrere 20.000 metri che potrebbero essere visualizzati anche come 20.0
vi chiedo se secondo voi è possibile istruire una finzione del genere con i pezzi a disposizione, sto iniziando a pensare che anche col miglior risultato possibile otterrei un dato inattendibile e fortemente sballato.

questo è il codice

#include <Wire.h>
#include "SSD1306Ascii.h"
#include "SSD1306AsciiWire.h"
#include <TinyGPS++.h>
#include <SoftwareSerial.h>
#include<SD.h>



const int cs_sd=2;
static const int RXPin = 0, TXPin = 1; 
static const uint32_t GPSBaud = 9600;
TinyGPSPlus gps;
SoftwareSerial ss(RXPin, TXPin);

int maxspeed = 0, speed1 = 0;
int maxhigh = 0, high1 = 0;
int maxsatelite = 0, satelite1 = 0;
int Mps = 0, kmh1 = 0, dist =0;
int flat, flat1, flon, flon1,x2lat, x2lon ;

 

#define I2C_ADDRESS 0x3C


#define RST_PIN -1

SSD1306AsciiWire oled;
//------------------------------------------------------------------------------
void setup() {
  Wire.begin();
  ss.begin(GPSBaud);

#if RST_PIN >= 0
  oled.begin(&Adafruit128x64, I2C_ADDRESS, RST_PIN);
#else 
  oled.begin(&Adafruit128x64, I2C_ADDRESS);
#endif 
  oled.setFont(System5x7);
  oled.clear();
  oled.println(" ");
  oled.println("GPS DATA LOGGER");
 
  delay(1000);
  oled.clear();
  
  

   if(!SD.begin(cs_sd))    
  {
   oled.clear();
   oled.print(" SD");
  
    return;
  }
  
    oled.print("SD OK");

    delay(1000);

   oled.clear();
    
  File data = SD.open("log.txt",FILE_WRITE);              
  data.println(""); data.println("log acquisition");    
  data.close(); 
}
//------------------------------------------------------------------------------
void loop() {
   
    satelite1 = (abs(gps.satellites.value()));

    oled.print("V max ");
    oled.print(" H max   ");
    oled.print(" Sat  ");
    oled.println(" ");
  oled.println(" "); 
   
  speed1 = (gps.speed.kmph());
  if ( speed1 > maxspeed) {
    maxspeed = speed1;
  }
 
  oled.setCursor(10 , 60);
  oled.print(maxspeed);
  
  high1 = (gps.altitude.meters());
  if ( high1 > maxhigh) {
    maxhigh = high1;
  }
  oled.setCursor(50 , 60);
  oled.print(maxhigh);

   oled.setCursor(100 , 60);
  oled.print(satelite1);
  oled.println(" "); 
  oled.println(" ");
  oled.print("Km/h");
  oled.print("    M/s ");
  oled.print("   Dist ");
  oled.println(" ");
  oled.println(" "); 

  kmh1 = (gps.speed.kmph());
  
  
 
  oled.setCursor(10 , 110);
  oled.print(kmh1);
  {
  
  Mps = (gps.speed.mps());
 
  
  
 
  oled.setCursor(50 , 110);
  oled.print(Mps);
  
  }
 
  float flat1 = flat;   
  float flon1 = flon; 
  float dist_calc;
  float dist_calc2;
  float diflat = 0;
  float diflon = 0;
  
  
  diflat = radians(x2lat - flat1); 
  flat1 = radians(flat1);  
  x2lat = radians(x2lat); 
  diflon = radians((x2lon) - (flon1));
  dist_calc = (sin(diflat / 2.0) * sin(diflat / 2.0));
  dist_calc2 = cos(flat1);
  dist_calc2 *= cos(x2lat);
  dist_calc2 *= sin(diflon / 2.0);
  dist_calc2 *= sin(diflon / 2.0);
  dist_calc += dist_calc2;
  dist_calc = (2 * atan2(sqrt(dist_calc), sqrt(1.0 - dist_calc)));
  dist_calc *= 6371000.0; 
  
   
  oled.setCursor(90 , 110);
  oled.print(dist_calc);    //distanza in metri 

   
   String Temps=String(gps.time.hour()+1)+(":")+(gps.time.minute())+(":")+(gps.time.second());
  String Date=String(gps.date.day())+("/")+(gps.date.month())+("/")+(gps.date.year());
 

  File data=SD.open("log.txt",FILE_WRITE);
  data.println(Date + " " + Temps + " " + String(gps.location.lat(), 6)+" "+String(gps.location.lng(), 6)+(" ")+String(gps.altitude.meters(),0)+(" ")+String(gps.speed.kmph(),0))+(" ")+String(satelite1); 
  data.close();
  
   
    DelayGPS(100);   
  oled.clear();

}

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

questo è il display come si presenta adesso, funziona tutto eccetto dist che resta a zero.

date le perplessità adesso sto pensando di ottenere la distanza percorsa con un reed o un A3144.
non so se avrò lo spazio necessario per aggiungere un conteggio a impulsi nella memoria disponibile.
sto giusto studiando adesso la via per fare un contachilometri con un sensore magnetico ma dovrei scrivere qualcosa di molto semplice per farlo convivere nello stesso sketch.
avete suggerimenti?
grazie a tutti.

nonostante tutto ci sto ancora provando.. ho cambiato libreria gps con neogps.h
sembra finzionare quasi tutto eccetto l'altitudine.. non so perchè, se dipende dal gps oppure ho sbagliato qualcosa nel codice.

non so perchè non mi rileva l'altitudine, con tinygps++ la prendeva per ultima ma in tempi ragionevoli, con neogps anche dolo 10 minuti ho sempre i numeri a zero e non capisco più se dipende dal programma oppure dal gps.

ho provato a usare Altitude come int, come flow, ad aggiungere Altitude=0 ma vado a casaccio se non posso escludere che sia un altro motivo anche perchè sarà un mese che studio questa materia.

adesso sto anche cercando di riportare i valori del gps sulla scheda SD ma quello che ho scritto lo devo ancora verificare portando il gps all'esterno.

gli altri parametri distance, speed e max speed funzionano tutti bene.

per favore potete dare un occhiata a questo codice per vedere se trovate errori o possibili migliorie?
grazie a tutti per il vostro tempo.

#include <SPI.h>
#include <SD.h>
#include <Wire.h>
#include "SSD1306Ascii.h"
#include "SSD1306AsciiWire.h"
#include <NMEAGPS.h>
#include <SoftwareSerial.h>
//#include <NeoSWSerial.h>
const int cs_sd=2;
#define I2C_ADDRESS 0x3C
#define RST_PIN -1
SSD1306AsciiWire lcd;
NMEAGPS gps;
gps_fix fix;
File myFile;
float odo;
float Speed; 
float alt;
NeoGPS::Location_t    lastLoc;
bool                  lastLocOK = false;
static const int RXPin = 5, TXPin = 4;
static const uint32_t GPSBaud = 9600;
SoftwareSerial gpsPort(RXPin, TXPin);
const int SHOW_INTERVAL = 1;
const int INITIAL_SHOW  = (2 * SHOW_INTERVAL) - 1; 
    int show          = INITIAL_SHOW;
const int   BUZZER_PIN  = 6;
const float SPEED_LIMIT = 0.1; //55.0; // kph
int maxs = 0; 
void setup(){
Serial.begin(9600);
gpsPort.begin(GPSBaud);
Wire.begin();
lcd.begin(&Adafruit128x64, I2C_ADDRESS);
lcd.setFont(TimesNewRoman16_bold);
lcd.clear();
lcd.println("  GPS LOGGER");
lcd.println(" ");
lcd.println("   WELCOME");
delay(3000);
lcd.clear();
if(!SD.begin(cs_sd)){
lcd.clear();
lcd.println(" ");
lcd.print("NO SD");
delay(3000);
return;}
lcd.println(" ");
lcd.print("SD Card OK");
delay(2000);
lcd.clear();
File data = SD.open("log.txt",FILE_WRITE);              
data.println(""); 
data.println("Data   Ora+2     Lat      Lon      Alt   Vel  Dis" );    
data.close();}
void loop(){
if (gps.available( gpsPort )) {  
gps_fix fix = gps.read();  
show = (show + 1) % SHOW_INTERVAL;
if (fix.valid.speed && (fix.speed_kph() > SPEED_LIMIT)) {
    digitalWrite( BUZZER_PIN, HIGH );   
 } else {
 digitalWrite( BUZZER_PIN, LOW ); } 
 if (fix.valid.location) { 
 if (lastLocOK) {
 odo += fix.location.DistanceKm( lastLoc );
 Speed = (fix.speed_kph());}
lastLoc   = fix.location;
lastLocOK = true;}
if ( Speed > maxs) 
maxs = Speed;
if (fix.valid.altitude)
 alt = ( fix.altitude () );
if (show == 0) {
#define MAX_CHARS 22
char displayBufffer[MAX_CHARS];
lcd.setCursor(0,0);   
snprintf(displayBufffer, MAX_CHARS, " Km  :  %  3d.%02d", (int)odo, (int)(odo * 100)%100);
lcd.println(displayBufffer);   
snprintf(displayBufffer, MAX_CHARS, "Kmh:  %  3d.%02d", (int)Speed, (int)(Speed * 100)%100);
lcd.println(displayBufffer);
snprintf(displayBufffer, MAX_CHARS, "Vmx:  %  3d.%02d", (int)maxs, (int)(maxs * 100)%100);
lcd.println(displayBufffer);
snprintf(displayBufffer, MAX_CHARS, " Alt   :  %  3d.%02d", (int)alt, (int)(alt * 100)%100);
lcd.println(displayBufffer);}    
String Temps=String(fix.dateTime.hours +1)+(":")+(fix.dateTime.minutes)+(":")+(fix.dateTime.seconds);
String Date=String(fix.dateTime.day)+("/")+(fix.dateTime.month)+("/")+(fix.dateTime.year);  
File data=SD.open("log.txt",FILE_WRITE);
data.println(Date +("  ")+ Temps +("  ")+ String(fix.latitude(), 6)+("  ")+String(fix.longitude(), 6)+("  ")+String(alt)+("  ") +String(Speed)+("  ")+ String(odo)); 
data.close();}}

ok non importa più.. adesso funziona tutto e anche bene.
ho editato e aggiornato lo sketch

saluti

per favore, vorrei chiedervi un aiuto per capire cosa dovrei scrivere per ottenere una determinata funzione che vorrei aggiungere al gps logger.

vorrei azzerare un dato in entrata come si fa per tarare le bilance sullo zero indipendentemente dal peso della ciotola.
in questo caso vorrei aggiungere una variabile "disl" dislivello che misuri i metri in altitudine dal momento del fix o reset del gps.
per esempio prima di scendere una collina per sapere quanti metri di dislivello sono stati percorsi.

adesso ho creato la variabile disl e ho fatto alcune prove ma tutte mi rendono un dato sul livello del mare +48mt casa mia..
anche disl = (fix.alt.whole); è interessante per la lettura su SD ma è comunque una altitudine slm.

non riesco a capire come dovrei scrivere le stringhe realtive a "disl" per ottenere un numero che parta da zero (campo base) e misuri solo i metri discesi o saliti durante la girata senza dover sottrarre a posteriori i metri slm iniziali.

nello sketch alt = ( fix.altitude()); misura e scrive su sd l'altitudine slm vorrei poter aggiungere "disl" specialmente sul display per sapere solo quanti metri di altitudine (partendo da zero) sono stati percorsi.

potete darmi qualche suggerimento?

#include <SPI.h>
#include <SD.h>
#include <Wire.h>
#include "SSD1306Ascii.h"
#include "SSD1306AsciiWire.h"
#include <NMEAGPS.h>
#include <SoftwareSerial.h>
//#include <NeoSWSerial.h>
const int cs_sd=2;
#define I2C_ADDRESS 0x3C
#define RST_PIN -1
SSD1306AsciiWire lcd;
NMEAGPS gps;
gps_fix fix;
File myFile;
float odo;
float Speed; 
float alt;
int disl; //--dislivello 

NeoGPS::Location_t    lastLoc;
bool                  lastLocOK = false;
static const int RXPin = 5, TXPin = 4; //-- gps pin
static const uint32_t GPSBaud = 9600;
SoftwareSerial gpsPort(RXPin, TXPin);
const int SHOW_INTERVAL = 1;
const int INITIAL_SHOW  = (2 * SHOW_INTERVAL) - 1; 
    int show          = INITIAL_SHOW;
const int   LED_PIN  = 3;  //-- led on at speed limit
const float SPEED_LIMIT = 0.0; // --setup speed limit value es: 55.0; kmh
int maxs = 0; 


void setup(){
  pinMode (LED_PIN, OUTPUT);
Serial.begin(9600);
gpsPort.begin(GPSBaud);
Wire.begin();
lcd.begin(&Adafruit128x64, I2C_ADDRESS);
lcd.setFont(TimesNewRoman16_bold);
lcd.clear();
lcd.println("  GPS");
lcd.println(" ");
lcd.println("   WELCOME");
delay(3000);
lcd.clear();
if(!SD.begin(cs_sd)){
lcd.clear();
lcd.println(" ");
lcd.print("NO SD");
delay(3000);
return;}
lcd.println(" ");
lcd.print("SD Card OK");
delay(2000);
lcd.clear();
File data = SD.open("log.csv",FILE_WRITE);              
data.println(""); 
data.println("Data  Hr+1  Lat  Lon  Disl  Alt  Vel  Dist" ); //-- Hr+1 add your local time difference   
data.close();}
void loop(){
if (gps.available( gpsPort )) {  
gps_fix fix = gps.read();  
show = (show + 1) % SHOW_INTERVAL;
if (fix.valid.speed && (fix.speed_kph() > SPEED_LIMIT)) {
    digitalWrite( LED_PIN, HIGH );   
 } else {
 digitalWrite( LED_PIN, LOW ); } 
 if (fix.valid.location) { 
 if (lastLocOK) {
 odo += fix.location.DistanceKm( lastLoc );
 Speed = (fix.speed_kph());}
lastLoc   = fix.location;
lastLocOK = true;}
if ( Speed > maxs) 
maxs = Speed;
if (fix.valid.altitude)
 alt = ( fix.altitude());
 
 disl = (fix.alt.whole);//--dislivello
 
 
  
  
if (show == 0) {
#define MAX_CHARS 22
char displayBufffer[MAX_CHARS];
lcd.setCursor(0,0);   
snprintf(displayBufffer, MAX_CHARS, " Km  :  %  3d.%02d", (int)odo, (int)(odo * 100)%100);
lcd.println(displayBufffer);   
snprintf(displayBufffer, MAX_CHARS, "Kmh:  %  3d.%02d", (int)Speed, (int)(Speed * 100)%100);
lcd.println(displayBufffer);
snprintf(displayBufffer, MAX_CHARS, "Vmx:  %  3d.%02d", (int)maxs, (int)(maxs * 100)%100);
lcd.println(displayBufffer);
snprintf(displayBufffer, MAX_CHARS, "Disl  :  %  3d.%02d", (int)alt, (int)(alt * 100)%100); 
lcd.println(displayBufffer);}    
String Temps=String(fix.dateTime.hours +1)+(":")+(fix.dateTime.minutes)+(":")+(fix.dateTime.seconds);
String Date=String(fix.dateTime.day)+("/")+(fix.dateTime.month)+("/")+(fix.dateTime.year);  
File data=SD.open("log.csv",FILE_WRITE);
data.println(Date +("  ")+ Temps +("  ")+ String(fix.latitude(), 6)+("  ")+String(fix.longitude(), 6)+("  ")+String(disl)+("  ")+String(alt)+("  ")+String(Speed)+("  ")+ String(odo)); 
data.close();}}

Non basta fare la differenza rispetto a un valore preimpostato?

Piuttosto, non capisco bene come funziona il tuo programma, ma hai considerato che la distanza percorsa non è semplicemente la distanza tra il punto di partenza e quello di arrivo? I due punti potrebbero anche essere coincidenti, quindi devi misurare abbastanza spesso la distanza percorsa e sommarla.

grazie della risposta. non posso preimpostare un valore, vorrei che appunto qualsiasi sia il valore dell'altitudine slm essa si azzerasse per la variabile "disl" al momento che il gps aggancia il segnale dei satelliti.
appurato che il fix rileva 48 metri sul livello del mare vorrei che "disl" mostrasse quel valore come zero.
arrivato sulla colina alta 100 metri vorrei leggere circa 100 senza dover sottrarre l'altitudine slm dal momento della partenza.
idem in discesa con un valore -100

è la stessa cosa che si fa azzerando una bilancia per escludere la tara della ciotola, credo che il concetto sia molto simile.

di fatto anche adesso posso fare benissimo i conti, su SD vedo l'altitudine "alt" al punto di partenza e all'arrivo.
ma sul display sarebbe più pratico poter leggere solo i metri di dislivello effettivamente percorsi.

per la distanza percorsa nel viaggio la libreria neogps ha una funzione specifica "fix location distance" per calcolarla in modo progressivo.
per quello che ho potuto vedere nelle girate che ho già fatto è abbastanza affidabile a patto di non fermarsi spesso.. nelle pause il gps un minimo crede di stare ancora camminando, magari 0,1-0,3mt scarica lentamente il buffer e questo aggiunge metri.... ma siamo nell'ordine dei 40-50 metri aggiunti in circa 10-15 minuti nei quali il gps viene lasciato immobile.

stasera per esempio ho fatto una girata di 6.4km con alcune brevi pause, col garmin sono risultati invece essere 6.1km.
sono comunque tolleranze che mi vanno benissimo per l'uso che ne faccio.