Need help with Groove GPS

Hello everyone, my code is working well except for one thing. When the GPS sends values for the first time after compiling this one sends me something like this : "$GPGGA,145343.000,4836.0112,N,00744.3196,E,1,8,1.26,139.7,M,47.$GPGGA,145353.000,4836.0112,N,00744.3196,E,1,7,1.57,139.7,M,47.9,M,,*5A" but i want to know how i can get rid of the extra GPS values so I can just keep one GPS value like this $GPGGA,145353.000,4836.0112,N,00744.3196,E,1,7,1.57,139.7,M,47.9,M,,*5A

#include <SoftwareSerial.h>
#include <Wire.h>
#include <RTClib.h>
#include <forcedClimate.h>
#include <ChainableLED.h>
#include <SdFat.h>
#include <EEPROM.h>

#define MODE_STANDARD 1
#define MODE_MAINTENANCE 2
#define MODE_ECO 3
#define MODE_CONFIGURATION 4

#define PIN_BOUTON_VERT 2
#define PIN_BOUTON_ROUGE 3
#define PIN_LUMIN A3
#define PIN_SD 4
#define TAILLE_TABLEAU 15
#define inactivite 30 

SdFat SD;
RTC_DS1307 rtc;
ForcedClimate climateSensor = ForcedClimate();
ChainableLED leds(8, 9, 1);

SoftwareSerial SoftSerial(6, 7);

int mode_actu = 0;
int mode_prec;
bool EtatBoutonVert = false;
unsigned long TempsBoutonVert;
bool EtatBoutonRouge = false;
unsigned long TempsBoutonRouge;
unsigned long TempsInactif;
int adresse = 0;
bool etatGPS = true;
unsigned long start_maintenance = 0;
bool initialisation_GPS_capteurs = true;

const int ParametresDefault[TAILLE_TABLEAU] =
    {
        10,   // LOG_INTERVAL,
        2048, // FILE_MAX_SIZE,
        30,   // TIMEOUT,
        1,    // LUMIN,
        255,  // LUMIN_LOW,
        768,  // LUMIN_HIGH,
        1,    // TEMP_AIR,
        -10,  // MIN_TEMP_AIR,
        60,   // MAX_TEMP_AIR,
        1,    // HYGR,
        0,    // HYGR_MINT,
        50,   // HYGR_MAXT,
        1,    // PRESSURE
        850,  // PRESSURE_MIN
        1080  // PRESSURE_MAX
};

int ParametresConfig[TAILLE_TABLEAU] =
    {
        10,   // LOG_INTERVAL,
        2048, // FILE_MAX_SIZE,
        30,   // TIMEOUT,
        1,    // LUMIN,
        255,  // LUMIN_LOW,
        768,  // LUMIN_HIGH,
        1,    // TEMP_AIR,
        -10,  // MIN_TEMP_AIR,
        60,   // MAX_TEMP_AIR,
        1,    // HYGR,
        0,    // HYGR_MINT,
        50,   // HYGR_MAXT,
        1,    // PRESSURE
        850,  // PRESSURE_MIN
        1080  // PRESSURE_MAX
};

#define LOG_INTERVAL_INDEX 0
#define FILE_MAX_SIZE_INDEX 1
#define TIMEOUT_INDEX 2
#define LUMIN_INDEX 3
#define LUMIN_LOW_INDEX 4
#define LUMIN_HIGH_INDEX 5
#define TEMP_AIR_INDEX 6
#define MIN_TEMP_AIR_INDEX 7
#define MAX_TEMP_AIR_INDEX 8
#define HYGR_INDEX 9
#define HYGR_MINT_INDEX 10
#define HYGR_MAXT_INDEX 11
#define PRESSURE_INDEX 12
#define PRESSURE_MIN_INDEX 13
#define PRESSURE_MAX_INDEX 14

File32 Fichier;

unsigned long TempsDerniereMesure = 0;
char RevisionFichier = '0';

bool VerificationEEPROM = false;
long LOG_INTERVAL = ParametresConfig[LOG_INTERVAL_INDEX];

void BoutonRougeInterruption(void);
void BoutonVertInterruption(void);

void Mode_standard();
void Mode_Maintenance();
void Mode_economique();
void Mode_config();
void LEDMode();
void Enregistrement_SD();
void ChangerHorloge(int annee, int mois, int jour, int heure, int minute, int seconde);

void GenerationDonnees();
void DonneesGPS();
void connexionSD();
void erreur_acces_horloge();
void erreur_acces_GPS();
void erreur_acces_donnees_capteurs();
void erreur_donnees_incoherentes();
void erreur_carte_SD_pleine();
void erreur_acces_ecriture();
void ModificationConfig(int index);
void Affichage(String Donnees, bool ligne);
void PointVirgule();
void SeparateurHorloge();
void Creation();

void ClearMoniteurSerie();
void LireEEPROM(int ParametresConfig[TAILLE_TABLEAU]);

void setup()
{
  Serial.begin(9600);
  SoftSerial.begin(9600);

  ClearMoniteurSerie();

  pinMode(PIN_BOUTON_VERT, INPUT);
  pinMode(PIN_BOUTON_ROUGE, INPUT);

  Wire.begin();
  leds.init();
  climateSensor.begin();

  connexionSD();
  Serial.println(F("Connexion à la carte SD réussie."));
  leds.setColorRGB(0, 255, 255, 255);

  while (!rtc.begin())
  {
    Serial.println(F("Module RTC pas trouvé"));
    erreur_acces_horloge();
  }

  rtc.adjust(DateTime((__DATE__), (__TIME__)));

  attachInterrupt(digitalPinToInterrupt(PIN_BOUTON_VERT), BoutonVertInterruption, CHANGE);
  attachInterrupt(digitalPinToInterrupt(PIN_BOUTON_ROUGE), BoutonRougeInterruption, CHANGE);

  LireEEPROM(ParametresConfig);

  for (int i = 0; i < TAILLE_TABLEAU; i++)
  {
    if (ParametresConfig[i] != ParametresDefault[i])
    {
      VerificationEEPROM = true;
      break;
    }
  }

  if (!VerificationEEPROM)
  {
    for (int i = 0; i < TAILLE_TABLEAU; i++)
    {
      EEPROM.put(i * sizeof(long), ParametresDefault[i]);
    }
  }

  if (digitalRead(PIN_BOUTON_ROUGE) == LOW)
  {
    mode_actu = MODE_CONFIGURATION;
  }

  else
  {
    mode_actu = MODE_STANDARD;
  }

  TempsDerniereMesure = millis();
}

void loop()
{
  switch (mode_actu)
  {
  case MODE_STANDARD:
    Mode_standard();
    break;
  case MODE_MAINTENANCE:
    Mode_Maintenance();
    break;
  case MODE_ECO:
    Mode_economique();
    break;
  case MODE_CONFIGURATION:
    Mode_config();
    break;
  }
}

void BoutonVertInterruption(void)
{
  if ((digitalRead(PIN_BOUTON_VERT) == LOW) && (!EtatBoutonVert))
  {
    EtatBoutonVert = true;
    TempsBoutonVert = millis();
  }
  else if ((digitalRead(PIN_BOUTON_VERT) == HIGH) && (EtatBoutonVert))
  {
    EtatBoutonVert = false;
    if ((millis() - TempsBoutonVert) >= (5000))
    {
      if (mode_actu == MODE_STANDARD)
      {
        mode_actu = MODE_ECO;
        LEDMode();
      }
      else if (mode_actu == MODE_ECO)
      {
        mode_actu = MODE_STANDARD;
        LEDMode();
      }
    }
  }
}

void BoutonRougeInterruption(void)
{
  if ((digitalRead(PIN_BOUTON_ROUGE) == LOW) && (!EtatBoutonRouge))
  {
    EtatBoutonRouge = true;
    TempsBoutonRouge = millis();
  }

  else if (digitalRead(PIN_BOUTON_ROUGE) == HIGH && (EtatBoutonRouge))
  {
    EtatBoutonRouge = false;
    if ((millis() - TempsBoutonRouge) >= 5000)
    {
      TempsBoutonRouge = millis();
      switch (mode_actu)
      {
      case MODE_CONFIGURATION:
        mode_actu = MODE_STANDARD;
        LEDMode();
        break;
      case MODE_STANDARD:
      case MODE_ECO:
        mode_prec = mode_actu;
        mode_actu = MODE_MAINTENANCE;
        LEDMode();
        break;
      case MODE_MAINTENANCE:
        mode_actu = mode_prec;
        mode_prec = 0;
        switch (mode_actu)
        {
        case MODE_STANDARD:
          LEDMode();
          break;
        case MODE_ECO:
          LEDMode();
          break;
        }
      }
    }
  }
}

void Mode_standard()
{
  LEDMode();
  connexionSD();
  if ((millis() - TempsDerniereMesure) >= (LOG_INTERVAL * 10000))// * 60000))
  {
    Enregistrement_SD();
    TempsDerniereMesure = millis();
    LEDMode();
  }
}

void Mode_Maintenance()
{
  LEDMode();
  if(millis() - start_maintenance < 10000)
    return;
  start_maintenance = millis();
  Serial.println();
  Serial.println(F("Horloge | Luminosité | Température (°C) | Hygrométrie (%) | Pression (HPa) | Données GPS"));
  Creation();
  LEDMode();
}

void Mode_economique()
{
  LEDMode();
  connexionSD();
  if ((millis() - TempsDerniereMesure) >= (LOG_INTERVAL)) //* 1200000))
  {
    Enregistrement_SD();
    TempsDerniereMesure = millis();
    LEDMode();
  }
}


void Mode_config()
{
  LEDMode();
  if ((millis() - TempsInactif) > (inactivite * 1000)) // A changer pour test soutenance (inactivite * 60000)
  {
  Serial.println(F("Fin de la configuration. Retour au mode standard."));
  mode_actu = MODE_STANDARD;
  return;
  }

    if (Serial.available() > 0)
    {
      TempsInactif = millis();
      String commande = Serial.readStringUntil('\n');
      int IndexEgal = commande.indexOf('=');

      if(IndexEgal < 0)
      {
        if (commande == F("RESET"))
        {
        for (int i = 0; i < TAILLE_TABLEAU; i++)
        {
          ParametresConfig[i] = ParametresDefault[i];
          EEPROM.put(i * sizeof(long), ParametresConfig[i]);
        }
        Serial.println(F("Reset des paramètres effectué."));
        }
      else if (commande == F("VERSION"))
        {
        Serial.println(F("Version du programme : 1.0"));
        Serial.println(F("Numéro de lot : 1"));
        }
      else 
        {
        Serial.println(F("Commande inexistante."));
        }
      return;
      }

      String nomCommande = commande.substring(0, IndexEgal);
      long Valeur = commande.substring(IndexEgal + 1).toInt();

      if (nomCommande == F("LOG_INTERVAL"))
      {
        ParametresConfig[LOG_INTERVAL_INDEX] = Valeur;
        ModificationConfig(LOG_INTERVAL_INDEX);
      }
      else if (nomCommande == F("FILE_MAX_SIZE"))
      {
        ParametresConfig[FILE_MAX_SIZE_INDEX] = Valeur;
        ModificationConfig(FILE_MAX_SIZE_INDEX);
      }
      else if (nomCommande == F("TIMEOUT"))
      {
        ParametresConfig[TIMEOUT_INDEX] = Valeur;
        ModificationConfig(TIMEOUT_INDEX);
      }
      else if (nomCommande == F("LUMIN"))
      {
        ParametresConfig[LUMIN_INDEX] = Valeur;
        ModificationConfig(LUMIN_INDEX);
      }
      else if (nomCommande == F("LUMIN_LOW"))
      {
        ParametresConfig[LUMIN_LOW_INDEX] = Valeur;
        ModificationConfig(LUMIN_LOW_INDEX);
      }
      else if (nomCommande == F("LUMIN_HIGH"))
      {
        ParametresConfig[LUMIN_HIGH_INDEX] = Valeur;
        ModificationConfig(LUMIN_HIGH_INDEX);
      }
      else if (nomCommande == F("TEMP_AIR"))
      {
        ParametresConfig[TEMP_AIR_INDEX] = Valeur;
        ModificationConfig(TEMP_AIR_INDEX);
      }
      else if (nomCommande == F("MIN_TEMP_AIR"))
      {
        ParametresConfig[MIN_TEMP_AIR_INDEX] = Valeur;
        ModificationConfig(MIN_TEMP_AIR_INDEX);
      }
      else if (nomCommande == F("MAX_TEMP_AIR"))
      {
        ParametresConfig[MAX_TEMP_AIR_INDEX] = Valeur;
        ModificationConfig(MAX_TEMP_AIR_INDEX);
      }
      else if (nomCommande == F("HYGR"))
      {
        ParametresConfig[HYGR_INDEX] = Valeur;
        ModificationConfig(HYGR_INDEX);
      }
      else if (nomCommande == F("HYGR_MINT"))
      {
        ParametresConfig[HYGR_MINT_INDEX] = Valeur;
        ModificationConfig(HYGR_MINT_INDEX);
      }
      else if (nomCommande == F("HYGR_MAXT"))
      {
        ParametresConfig[HYGR_MAXT_INDEX] = Valeur;
        ModificationConfig(HYGR_MAXT_INDEX);
      }
      else if (nomCommande == F("PRESSURE"))
      {
        ParametresConfig[PRESSURE_INDEX] = Valeur;
        ModificationConfig(PRESSURE_INDEX);
      }
      else if (nomCommande == F("PRESSURE_MIN"))
      {
        ParametresConfig[PRESSURE_MIN_INDEX] = Valeur;
        ModificationConfig(PRESSURE_MIN_INDEX);
      }
      else if (nomCommande == F("PRESSURE_MAX"))
      {
        ParametresConfig[PRESSURE_MAX_INDEX] = Valeur;
        ModificationConfig(PRESSURE_MAX_INDEX);
      }
      else if (nomCommande == F("CLOCK"))
      {
        String Horloge = commande.substring(6);
        int annee = Horloge.substring(0, 4).toInt();
        int mois = Horloge.substring(5, 7).toInt();
        int jour = Horloge.substring(8, 10).toInt();
        int heure = Horloge.substring(11, 13).toInt();
        int minute = Horloge.substring(14, 16).toInt();
        int seconde = Horloge.substring(17, 19).toInt();
        ChangerHorloge(annee, mois, jour, heure, minute, seconde);
      }
      else
      {
        Serial.println(F("Commande inexistante."));
      }
  }
}

void Enregistrement_SD()
{
    DateTime Maintenant = rtc.now();
    String NomFichier;
    GenerationDonnees();
    // Si le fichier s'est bien ouvert
    if (Fichier) 
    {
        // Vérifier si la taille du fichier dépasse la taille maximale
        if (Fichier.size() > ParametresConfig[1])
        {
            // Fermer le fichier actuel
            Fichier.close();

            // Incrémenter le caractère de révision du fichier
            RevisionFichier++;

            // Former un nouveau nom de fichier avec la date et heure actuelles
            NomFichier = String(Maintenant.year() % 100) + String(Maintenant.month()) + String(Maintenant.day()) + '_' + String(Maintenant.hour()) + String(Maintenant.minute()) + String(Maintenant.second()) + F(".LOG");

            // Tenter d'ouvrir le nouveau fichier pour écriture
            Fichier = SD.open(NomFichier.c_str(), FILE_WRITE);

            if (!Fichier) 
            {
                // Si l'ouverture du nouveau fichier échoue, cela pourrait signifier que la carte SD est pleine
                Serial.println(F("Erreur lors de la création du nouveau fichier."));
                erreur_carte_SD_pleine();
            }
        }
    } 
    else 
    {
        // Si aucun fichier n'est ouvert
        if (!Fichier) {
             NomFichier = String(Maintenant.year() % 100) + String(Maintenant.month()) + String(Maintenant.day()) + '_' + String(Maintenant.hour()) + String(Maintenant.minute()) + String(Maintenant.second()) + F(".LOG");

            // Tenter d'ouvrir le nouveau fichier pour écriture
            Fichier = SD.open(NomFichier.c_str(), FILE_WRITE);

            if (!Fichier) 
            {
                // Si l'ouverture du nouveau fichier échoue, cela pourrait signifier que la carte SD est pleine
                Serial.println(F("Erreur lors de la création du nouveau fichier."));
                erreur_carte_SD_pleine();
            }
        }
    }
}

void ChangerHorloge(int annee, int mois, int jour, int heure, int minute, int seconde)
{
  DateTime NouvelleHorloge(annee, mois, jour, heure, minute, seconde); // Année, mois, jour, heure, minute, seconde
  rtc.adjust(NouvelleHorloge);
  Serial.println(F("Horloge changée avec succès."));
}

void LEDMode()
{
  switch (mode_actu)
  {
  case MODE_STANDARD:
    leds.setColorRGB(0, 0, 255, 0);
    break;
  case MODE_MAINTENANCE:
    leds.setColorRGB(0, 255, 155, 0);
    break;
  case MODE_ECO:
    leds.setColorRGB(0, 0, 0, 255);
    break;
  case MODE_CONFIGURATION:
    leds.setColorRGB(0, 255, 0, 0);
    break;
  default:
    break;
  }
}

void erreur_acces_horloge()
{                                 // Si erreur d'accès à l'horloge
  leds.setColorRGB(0, 255, 0, 0); // Allume la LED en rouge
  delay(1000);                    // On attend 1 sec
  leds.setColorRGB(0, 0, 0, 255); // Allume la LED en bleu
  delay(1000);                    // On attend 1 sec
}

void erreur_acces_GPS()
{                                   // Si erreur d'accès au GPS
  leds.setColorRGB(0, 255, 0, 0);   // Allume la LED en rouge
  delay(1000);                      // On attend 1 sec
  leds.setColorRGB(0, 255, 255, 0); // Allume la LED en jaune
  delay(1000);                      // On attend 1 sec
}

void erreur_acces_donnees_capteurs()
{                                 // Si erreur d'accès aux données d'un capteur
  leds.setColorRGB(0, 255, 0, 0); // Allume la LED en rouge
  delay(1000);                    // On attend 1 sec
  leds.setColorRGB(0, 0, 255, 0); // Allume la LED en verte
  delay(1000);                    // On attend 1 sec
}

void erreur_donnees_incoherentes()
{                                 // Si données incohérentes
  leds.setColorRGB(0, 255, 0, 0); // Allume la LED en rouge
  delay(1000);                    // On attend 1 sec
  leds.setColorRGB(0, 0, 255, 0); // Allume la LED en vert
  delay(2000);                    // On attend 2 sec
}

void erreur_carte_SD_pleine()
{                                     // Si erreur de carte SD pleine
  leds.setColorRGB(0, 255, 0, 0);     // Allume la LED en rouge
  delay(1000);                        // On attend 1 sec
  leds.setColorRGB(0, 255, 255, 255); // Allume la LED en blanc
  delay(1000);                        // On attend 1 sec
}

void erreur_acces_ecriture()
{                                     // Si erreur d'accès et d'écriture sur la carte SD
  leds.setColorRGB(0, 255, 0, 0);     // On allume la LED en rouge
  delay(1000);                        // On attend 1 sec
  leds.setColorRGB(0, 255, 255, 255); // On allume la LED en blanc
  delay(2000);                        // On attend 2 sec
}

void GenerationDonnees()
{
  climateSensor.takeForcedMeasurement();

  if (ParametresConfig[LUMIN_INDEX])
  {
    int Luminosite = analogRead(PIN_LUMIN);
    Affichage(String(Luminosite), false);
    PointVirgule();
  }
  else
  {
    Affichage(F("Capteur désactivé ; "), false);
  }

  float Temperature_Air = climateSensor.getTemperatureCelcius();
  if (ParametresConfig[TEMP_AIR_INDEX])
  {
    if (Temperature_Air >= ParametresConfig[MIN_TEMP_AIR_INDEX] && Temperature_Air <= ParametresConfig[MAX_TEMP_AIR_INDEX])
    {
      Affichage(String(Temperature_Air), false);
      PointVirgule();
    }
    else
    {
      erreur_donnees_incoherentes();
      Affichage(F("Hors intervalle ; "), false);
    }
  }
  else
  {
    Affichage(F("Capteur désactivé ; "), false);
  }

  if (ParametresConfig[HYGR_INDEX])
  {
    float Hygrometrie = climateSensor.getRelativeHumidity();
    if (Temperature_Air >= ParametresConfig[MIN_TEMP_AIR_INDEX] && Temperature_Air <= ParametresConfig[MAX_TEMP_AIR_INDEX])
    {
      Affichage(String(Hygrometrie), false);
      PointVirgule();
    }
    else
    {
      erreur_donnees_incoherentes();
      Affichage(F("Hors intervalle ; "), false);
    }
  }
  else
  {
    Affichage(F("Capteur désactivé ; "), false);
  }

  if (ParametresConfig[PRESSURE_INDEX])
  {
    float Pression = climateSensor.getPressure();
    if (Pression >= ParametresConfig[PRESSURE_MIN_INDEX] && Pression <= ParametresConfig[PRESSURE_MAX_INDEX])
    {
      Affichage(String(Pression), false);
      PointVirgule();
    }
    else
    {
      erreur_donnees_incoherentes();
      Affichage(F("Hors intervalle ; "), false);
    }
  }
  else
  {
    Affichage(F("Capteur désactivé ; "), false);
  }
}

void connexionSD()
{
  while (!SD.begin(PIN_SD))
  {
    Serial.println(F("Connexion à la carte SD impossible, veuillez verifier la connexion."));
    erreur_acces_ecriture();
  }
}

void ModificationConfig(int index)
{
  Serial.println(F("Modification effectuée avec succès."));
  EEPROM.put(index * sizeof(long), ParametresConfig[index]);
}

void ClearMoniteurSerie()
{
  for (int i = 0; i < 30; i++)
  {
    Serial.println();
  }
}

void LireEEPROM(int ParametresConfig[TAILLE_TABLEAU])
{
  for (int i = 0; i < TAILLE_TABLEAU; i++)
  {
    EEPROM.get(i * sizeof(long), ParametresConfig[i]);
  }
}

void DonneesGPS()
{
  String GPS = "";
  if (mode_actu == MODE_ECO){
    etatGPS = !etatGPS;
    GPS = F("Aucune mesure effectuée");
  }

  else{
    etatGPS = true;
  }

  if (SoftSerial.available() && (etatGPS))
  {
    GPS = F("");
    unsigned long StartGPS = millis();
    do
    {
      GPS = SoftSerial.readStringUntil('\n');
      if ((millis() - StartGPS) > 10000)
      {
        erreur_acces_GPS();
        Affichage(F("GPS Timeout"), true);
        StartGPS = millis();
        break;
      }
    } while (!GPS.startsWith(F("$GPGGA")));
    Affichage(GPS, true);
  }
}

void Affichage(String Donnees, bool ligne)
{
  if (mode_actu == MODE_MAINTENANCE)
  {
    if (ligne)
    {
      Serial.println(Donnees);
    }
    else
    {
      Serial.print(Donnees);
    }
  }
  else
  {
    Fichier.print(Donnees);
  }
}

void PointVirgule()
{
  Affichage(F(" ; "), false);
}

void SeparateurHorloge()
{
  Affichage(F(":"), false);
}

void Creation()
{
  DateTime Maintenant = rtc.now();
  Affichage(Maintenant.hour() > 9 ? String(Maintenant.hour()) : '0' + String(Maintenant.hour()), false);
  SeparateurHorloge();
  Affichage(Maintenant.minute() > 9 ? String(Maintenant.minute()) : '0' + String(Maintenant.minute()), false);
  SeparateurHorloge();
  Affichage(Maintenant.second() > 9 ? String(Maintenant.second()) : '0' + String(Maintenant.second()), false);
  PointVirgule();
  GenerationDonnees();
  DonneesGPS();
}

It seems to be some trash inside the rx-buffer.
Add a rx-buffer read until buffer is empty call to the setup() function.

How can i do that ?
Something like this in the void setup ?

void ClearSoftSerial() {
  while (SoftSerial.available() > 0) {
    SoftSerial.read(); 
  }
}

Because it doesn't seem to work

And for information this is my code :

#include <SoftwareSerial.h>
#include <Wire.h>
#include <RTClib.h>
#include <forcedClimate.h>
#include <ChainableLED.h>
#include <SdFat.h>
#include <EEPROM.h>

#define MODE_STANDARD 1
#define MODE_MAINTENANCE 2
#define MODE_ECO 3
#define MODE_CONFIGURATION 4

#define PIN_BOUTON_VERT 2
#define PIN_BOUTON_ROUGE 3
#define PIN_LUMIN A3
#define PIN_SD 4
#define TAILLE_TABLEAU 15
#define inactivite 30 

SdFat SD;
RTC_DS1307 rtc;
ForcedClimate climateSensor = ForcedClimate();
ChainableLED leds(8, 9, 1);

SoftwareSerial SoftSerial(6, 7);

int mode_actu = 0;
int mode_prec;
bool EtatBoutonVert = false;
unsigned long TempsBoutonVert;
bool EtatBoutonRouge = false;
unsigned long TempsBoutonRouge;
unsigned long TempsInactif;
int adresse = 0;
bool etatGPS = true;
unsigned long start_maintenance = 0;
bool initialisation_GPS_capteurs = true;

const int ParametresDefault[TAILLE_TABLEAU] =
    {
        10,   // LOG_INTERVAL,
        2048, // FILE_MAX_SIZE,
        30,   // TIMEOUT,
        1,    // LUMIN,
        255,  // LUMIN_LOW,
        768,  // LUMIN_HIGH,
        1,    // TEMP_AIR,
        -10,  // MIN_TEMP_AIR,
        60,   // MAX_TEMP_AIR,
        1,    // HYGR,
        0,    // HYGR_MINT,
        50,   // HYGR_MAXT,
        1,    // PRESSURE
        850,  // PRESSURE_MIN
        1080  // PRESSURE_MAX
};

int ParametresConfig[TAILLE_TABLEAU] =
    {
        10,   // LOG_INTERVAL,
        2048, // FILE_MAX_SIZE,
        30,   // TIMEOUT,
        1,    // LUMIN,
        255,  // LUMIN_LOW,
        768,  // LUMIN_HIGH,
        1,    // TEMP_AIR,
        -10,  // MIN_TEMP_AIR,
        60,   // MAX_TEMP_AIR,
        1,    // HYGR,
        0,    // HYGR_MINT,
        50,   // HYGR_MAXT,
        1,    // PRESSURE
        850,  // PRESSURE_MIN
        1080  // PRESSURE_MAX
};

#define LOG_INTERVAL_INDEX 0
#define FILE_MAX_SIZE_INDEX 1
#define TIMEOUT_INDEX 2
#define LUMIN_INDEX 3
#define LUMIN_LOW_INDEX 4
#define LUMIN_HIGH_INDEX 5
#define TEMP_AIR_INDEX 6
#define MIN_TEMP_AIR_INDEX 7
#define MAX_TEMP_AIR_INDEX 8
#define HYGR_INDEX 9
#define HYGR_MINT_INDEX 10
#define HYGR_MAXT_INDEX 11
#define PRESSURE_INDEX 12
#define PRESSURE_MIN_INDEX 13
#define PRESSURE_MAX_INDEX 14

File32 Fichier;

unsigned long TempsDerniereMesure = 0;
char RevisionFichier = '0';

bool VerificationEEPROM = false;
long LOG_INTERVAL = ParametresConfig[LOG_INTERVAL_INDEX];

void BoutonRougeInterruption(void);
void BoutonVertInterruption(void);

void Mode_standard();
void Mode_Maintenance();
void Mode_economique();
void Mode_config();
void LEDMode();
void Enregistrement_SD();
void ChangerHorloge(int annee, int mois, int jour, int heure, int minute, int seconde);

void GenerationDonnees();
void DonneesGPS();
void connexionSD();
void erreur_acces_horloge();
void erreur_acces_GPS();
void erreur_acces_donnees_capteurs();
void erreur_donnees_incoherentes();
void erreur_carte_SD_pleine();
void erreur_acces_ecriture();
void ModificationConfig(int index);
void Affichage(String Donnees, bool ligne);
void PointVirgule();
void SeparateurHorloge();
void Creation();

void ClearMoniteurSerie();

void LireEEPROM(int ParametresConfig[TAILLE_TABLEAU]);

void setup()
{
  Serial.begin(9600);
  SoftSerial.begin(9600);

  ClearMoniteurSerie();

  pinMode(PIN_BOUTON_VERT, INPUT);
  pinMode(PIN_BOUTON_ROUGE, INPUT);

  Wire.begin();
  leds.init();
  climateSensor.begin();

  connexionSD();
  Serial.println(F("Connexion à la carte SD réussie."));
  leds.setColorRGB(0, 255, 255, 255);

  while (!rtc.begin())
  {
    Serial.println(F("Module RTC pas trouvé"));
    erreur_acces_horloge();
  }

  rtc.adjust(DateTime((__DATE__), (__TIME__)));

  attachInterrupt(digitalPinToInterrupt(PIN_BOUTON_VERT), BoutonVertInterruption, CHANGE);
  attachInterrupt(digitalPinToInterrupt(PIN_BOUTON_ROUGE), BoutonRougeInterruption, CHANGE);

  LireEEPROM(ParametresConfig);

  for (int i = 0; i < TAILLE_TABLEAU; i++)
  {
    if (ParametresConfig[i] != ParametresDefault[i])
    {
      VerificationEEPROM = true;
      break;
    }
  }

  if (!VerificationEEPROM)
  {
    for (int i = 0; i < TAILLE_TABLEAU; i++)
    {
      EEPROM.put(i * sizeof(long), ParametresDefault[i]);
    }
  }

  if (digitalRead(PIN_BOUTON_ROUGE) == LOW)
  {
    mode_actu = MODE_CONFIGURATION;
  }

  else
  {
    mode_actu = MODE_STANDARD;
  }

  TempsDerniereMesure = millis();
}

void loop()
{
  switch (mode_actu)
  {
  case MODE_STANDARD:
    Mode_standard();
    break;
  case MODE_MAINTENANCE:
    Mode_Maintenance();
    break;
  case MODE_ECO:
    Mode_economique();
    break;
  case MODE_CONFIGURATION:
    Mode_config();
    break;
  }
}

void BoutonVertInterruption(void)
{
  if ((digitalRead(PIN_BOUTON_VERT) == LOW) && (!EtatBoutonVert))
  {
    EtatBoutonVert = true;
    TempsBoutonVert = millis();
  }
  else if ((digitalRead(PIN_BOUTON_VERT) == HIGH) && (EtatBoutonVert))
  {
    EtatBoutonVert = false;
    if ((millis() - TempsBoutonVert) >= (5000))
    {
      if (mode_actu == MODE_STANDARD)
      {
        mode_actu = MODE_ECO;
        LEDMode();
      }
      else if (mode_actu == MODE_ECO)
      {
        mode_actu = MODE_STANDARD;
        LEDMode();
      }
    }
  }
}

void BoutonRougeInterruption(void)
{
  if ((digitalRead(PIN_BOUTON_ROUGE) == LOW) && (!EtatBoutonRouge))
  {
    EtatBoutonRouge = true;
    TempsBoutonRouge = millis();
  }

  else if (digitalRead(PIN_BOUTON_ROUGE) == HIGH && (EtatBoutonRouge))
  {
    EtatBoutonRouge = false;
    if ((millis() - TempsBoutonRouge) >= 5000)
    {
      TempsBoutonRouge = millis();
      switch (mode_actu)
      {
      case MODE_CONFIGURATION:
        mode_actu = MODE_STANDARD;
        LEDMode();
        break;
      case MODE_STANDARD:
      case MODE_ECO:
        mode_prec = mode_actu;
        mode_actu = MODE_MAINTENANCE;
        LEDMode();
        break;
      case MODE_MAINTENANCE:
        mode_actu = mode_prec;
        mode_prec = 0;
        switch (mode_actu)
        {
        case MODE_STANDARD:
          LEDMode();
          break;
        case MODE_ECO:
          LEDMode();
          break;
        }
      }
    }
  }
}

void Mode_standard()
{
  LEDMode();
  connexionSD();
  if ((millis() - TempsDerniereMesure) >= (LOG_INTERVAL * 10000))// * 60000))
  {
    Enregistrement_SD();
    TempsDerniereMesure = millis();
    LEDMode();
  }
}

void Mode_Maintenance()
{
  LEDMode();
  if(millis() - start_maintenance < 10000)
    return;
  start_maintenance = millis();
  Serial.println();
  Serial.println(F("Horloge | Luminosité | Température (°C) | Hygrométrie (%) | Pression (HPa) | Données GPS"));
  Creation();
  LEDMode();
}

void Mode_economique()
{
  LEDMode();
  connexionSD();
  if ((millis() - TempsDerniereMesure) >= (LOG_INTERVAL)) //* 1200000))
  {
    Enregistrement_SD();
    TempsDerniereMesure = millis();
    LEDMode();
  }
}


void Mode_config()
{
  LEDMode();
  if ((millis() - TempsInactif) > (inactivite * 1000)) // A changer pour test soutenance (inactivite * 60000)
  {
  Serial.println(F("Fin de la configuration. Retour au mode standard."));
  mode_actu = MODE_STANDARD;
  return;
  }

    if (Serial.available() > 0)
    {
      TempsInactif = millis();
      String commande = Serial.readStringUntil('\n');
      int IndexEgal = commande.indexOf('=');

      if(IndexEgal < 0)
      {
        if (commande == F("RESET"))
        {
        for (int i = 0; i < TAILLE_TABLEAU; i++)
        {
          ParametresConfig[i] = ParametresDefault[i];
          EEPROM.put(i * sizeof(long), ParametresConfig[i]);
        }
        Serial.println(F("Reset des paramètres effectué."));
        }
      else if (commande == F("VERSION"))
        {
        Serial.println(F("Version du programme : 1.0"));
        Serial.println(F("Numéro de lot : 1"));
        }
      else 
        {
        Serial.println(F("Commande inexistante."));
        }
      return;
      }

      String nomCommande = commande.substring(0, IndexEgal);
      long Valeur = commande.substring(IndexEgal + 1).toInt();

      if (nomCommande == F("LOG_INTERVAL"))
      {
        ParametresConfig[LOG_INTERVAL_INDEX] = Valeur;
        ModificationConfig(LOG_INTERVAL_INDEX);
      }
      else if (nomCommande == F("FILE_MAX_SIZE"))
      {
        ParametresConfig[FILE_MAX_SIZE_INDEX] = Valeur;
        ModificationConfig(FILE_MAX_SIZE_INDEX);
      }
      else if (nomCommande == F("TIMEOUT"))
      {
        ParametresConfig[TIMEOUT_INDEX] = Valeur;
        ModificationConfig(TIMEOUT_INDEX);
      }
      else if (nomCommande == F("LUMIN"))
      {
        ParametresConfig[LUMIN_INDEX] = Valeur;
        ModificationConfig(LUMIN_INDEX);
      }
      else if (nomCommande == F("LUMIN_LOW"))
      {
        ParametresConfig[LUMIN_LOW_INDEX] = Valeur;
        ModificationConfig(LUMIN_LOW_INDEX);
      }
      else if (nomCommande == F("LUMIN_HIGH"))
      {
        ParametresConfig[LUMIN_HIGH_INDEX] = Valeur;
        ModificationConfig(LUMIN_HIGH_INDEX);
      }
      else if (nomCommande == F("TEMP_AIR"))
      {
        ParametresConfig[TEMP_AIR_INDEX] = Valeur;
        ModificationConfig(TEMP_AIR_INDEX);
      }
      else if (nomCommande == F("MIN_TEMP_AIR"))
      {
        ParametresConfig[MIN_TEMP_AIR_INDEX] = Valeur;
        ModificationConfig(MIN_TEMP_AIR_INDEX);
      }
      else if (nomCommande == F("MAX_TEMP_AIR"))
      {
        ParametresConfig[MAX_TEMP_AIR_INDEX] = Valeur;
        ModificationConfig(MAX_TEMP_AIR_INDEX);
      }
      else if (nomCommande == F("HYGR"))
      {
        ParametresConfig[HYGR_INDEX] = Valeur;
        ModificationConfig(HYGR_INDEX);
      }
      else if (nomCommande == F("HYGR_MINT"))
      {
        ParametresConfig[HYGR_MINT_INDEX] = Valeur;
        ModificationConfig(HYGR_MINT_INDEX);
      }
      else if (nomCommande == F("HYGR_MAXT"))
      {
        ParametresConfig[HYGR_MAXT_INDEX] = Valeur;
        ModificationConfig(HYGR_MAXT_INDEX);
      }
      else if (nomCommande == F("PRESSURE"))
      {
        ParametresConfig[PRESSURE_INDEX] = Valeur;
        ModificationConfig(PRESSURE_INDEX);
      }
      else if (nomCommande == F("PRESSURE_MIN"))
      {
        ParametresConfig[PRESSURE_MIN_INDEX] = Valeur;
        ModificationConfig(PRESSURE_MIN_INDEX);
      }
      else if (nomCommande == F("PRESSURE_MAX"))
      {
        ParametresConfig[PRESSURE_MAX_INDEX] = Valeur;
        ModificationConfig(PRESSURE_MAX_INDEX);
      }
      else if (nomCommande == F("CLOCK"))
      {
        String Horloge = commande.substring(6);
        int annee = Horloge.substring(0, 4).toInt();
        int mois = Horloge.substring(5, 7).toInt();
        int jour = Horloge.substring(8, 10).toInt();
        int heure = Horloge.substring(11, 13).toInt();
        int minute = Horloge.substring(14, 16).toInt();
        int seconde = Horloge.substring(17, 19).toInt();
        ChangerHorloge(annee, mois, jour, heure, minute, seconde);
      }
      else
      {
        Serial.println(F("Commande inexistante."));
      }
  }
}

void Enregistrement_SD()
{
    DateTime Maintenant = rtc.now();
    String NomFichier;
    GenerationDonnees();
    // Si le fichier s'est bien ouvert
    if (Fichier) 
    {
        // Vérifier si la taille du fichier dépasse la taille maximale
        if (Fichier.size() > ParametresConfig[1])
        {
            // Fermer le fichier actuel
            Fichier.close();

            // Incrémenter le caractère de révision du fichier
            RevisionFichier++;

            // Former un nouveau nom de fichier avec la date et heure actuelles
            NomFichier = String(Maintenant.year() % 100) + String(Maintenant.month()) + String(Maintenant.day()) + '_' + String(Maintenant.hour()) + String(Maintenant.minute()) + String(Maintenant.second()) + F(".LOG");

            // Tenter d'ouvrir le nouveau fichier pour écriture
            Fichier = SD.open(NomFichier.c_str(), FILE_WRITE);

            if (!Fichier) 
            {
                // Si l'ouverture du nouveau fichier échoue, cela pourrait signifier que la carte SD est pleine
                Serial.println(F("Erreur lors de la création du nouveau fichier."));
                erreur_carte_SD_pleine();
            }
        }
    } 
    else 
    {
        // Si aucun fichier n'est ouvert
        if (!Fichier) {
             NomFichier = String(Maintenant.year() % 100) + String(Maintenant.month()) + String(Maintenant.day()) + '_' + String(Maintenant.hour()) + String(Maintenant.minute()) + String(Maintenant.second()) + F(".LOG");

            // Tenter d'ouvrir le nouveau fichier pour écriture
            Fichier = SD.open(NomFichier.c_str(), FILE_WRITE);

            if (!Fichier) 
            {
                // Si l'ouverture du nouveau fichier échoue, cela pourrait signifier que la carte SD est pleine
                Serial.println(F("Erreur lors de la création du nouveau fichier."));
                erreur_carte_SD_pleine();
            }
        }
    }
}

void ChangerHorloge(int annee, int mois, int jour, int heure, int minute, int seconde)
{
  DateTime NouvelleHorloge(annee, mois, jour, heure, minute, seconde); // Année, mois, jour, heure, minute, seconde
  rtc.adjust(NouvelleHorloge);
  Serial.println(F("Horloge changée avec succès."));
}

void LEDMode()
{
  switch (mode_actu)
  {
  case MODE_STANDARD:
    leds.setColorRGB(0, 0, 255, 0);
    break;
  case MODE_MAINTENANCE:
    leds.setColorRGB(0, 255, 155, 0);
    break;
  case MODE_ECO:
    leds.setColorRGB(0, 0, 0, 255);
    break;
  case MODE_CONFIGURATION:
    leds.setColorRGB(0, 255, 0, 0);
    break;
  default:
    break;
  }
}

void erreur_acces_horloge()
{                                 // Si erreur d'accès à l'horloge
  leds.setColorRGB(0, 255, 0, 0); // Allume la LED en rouge
  delay(1000);                    // On attend 1 sec
  leds.setColorRGB(0, 0, 0, 255); // Allume la LED en bleu
  delay(1000);                    // On attend 1 sec
}

void erreur_acces_GPS()
{                                   // Si erreur d'accès au GPS
  leds.setColorRGB(0, 255, 0, 0);   // Allume la LED en rouge
  delay(1000);                      // On attend 1 sec
  leds.setColorRGB(0, 255, 255, 0); // Allume la LED en jaune
  delay(1000);                      // On attend 1 sec
}

void erreur_acces_donnees_capteurs()
{                                 // Si erreur d'accès aux données d'un capteur
  leds.setColorRGB(0, 255, 0, 0); // Allume la LED en rouge
  delay(1000);                    // On attend 1 sec
  leds.setColorRGB(0, 0, 255, 0); // Allume la LED en verte
  delay(1000);                    // On attend 1 sec
}

void erreur_donnees_incoherentes()
{                                 // Si données incohérentes
  leds.setColorRGB(0, 255, 0, 0); // Allume la LED en rouge
  delay(1000);                    // On attend 1 sec
  leds.setColorRGB(0, 0, 255, 0); // Allume la LED en vert
  delay(2000);                    // On attend 2 sec
}

void erreur_carte_SD_pleine()
{                                     // Si erreur de carte SD pleine
  leds.setColorRGB(0, 255, 0, 0);     // Allume la LED en rouge
  delay(1000);                        // On attend 1 sec
  leds.setColorRGB(0, 255, 255, 255); // Allume la LED en blanc
  delay(1000);                        // On attend 1 sec
}

void erreur_acces_ecriture()
{                                     // Si erreur d'accès et d'écriture sur la carte SD
  leds.setColorRGB(0, 255, 0, 0);     // On allume la LED en rouge
  delay(1000);                        // On attend 1 sec
  leds.setColorRGB(0, 255, 255, 255); // On allume la LED en blanc
  delay(2000);                        // On attend 2 sec
}

void GenerationDonnees()
{
  climateSensor.takeForcedMeasurement();

  if (ParametresConfig[LUMIN_INDEX])
  {
    int Luminosite = analogRead(PIN_LUMIN);
    Affichage(String(Luminosite), false);
    PointVirgule();
  }
  else
  {
    Affichage(F("Capteur désactivé ; "), false);
  }

  float Temperature_Air = climateSensor.getTemperatureCelcius();
  if (ParametresConfig[TEMP_AIR_INDEX])
  {
    if (Temperature_Air >= ParametresConfig[MIN_TEMP_AIR_INDEX] && Temperature_Air <= ParametresConfig[MAX_TEMP_AIR_INDEX])
    {
      Affichage(String(Temperature_Air), false);
      PointVirgule();
    }
    else
    {
      erreur_donnees_incoherentes();
      Affichage(F("Hors intervalle ; "), false);
    }
  }
  else
  {
    Affichage(F("Capteur désactivé ; "), false);
  }

  if (ParametresConfig[HYGR_INDEX])
  {
    float Hygrometrie = climateSensor.getRelativeHumidity();
    if (Temperature_Air >= ParametresConfig[MIN_TEMP_AIR_INDEX] && Temperature_Air <= ParametresConfig[MAX_TEMP_AIR_INDEX])
    {
      Affichage(String(Hygrometrie), false);
      PointVirgule();
    }
    else
    {
      erreur_donnees_incoherentes();
      Affichage(F("Hors intervalle ; "), false);
    }
  }
  else
  {
    Affichage(F("Capteur désactivé ; "), false);
  }

  if (ParametresConfig[PRESSURE_INDEX])
  {
    float Pression = climateSensor.getPressure();
    if (Pression >= ParametresConfig[PRESSURE_MIN_INDEX] && Pression <= ParametresConfig[PRESSURE_MAX_INDEX])
    {
      Affichage(String(Pression), false);
      PointVirgule();
    }
    else
    {
      erreur_donnees_incoherentes();
      Affichage(F("Hors intervalle ; "), false);
    }
  }
  else
  {
    Affichage(F("Capteur désactivé ; "), false);
  }
}

void connexionSD()
{
  while (!SD.begin(PIN_SD))
  {
    Serial.println(F("Connexion à la carte SD impossible, veuillez verifier la connexion."));
    erreur_acces_ecriture();
  }
}

void ModificationConfig(int index)
{
  Serial.println(F("Modification effectuée avec succès."));
  EEPROM.put(index * sizeof(long), ParametresConfig[index]);
}

void ClearMoniteurSerie()
{
  for (int i = 0; i < 30; i++)
  {
    Serial.println();
  }
}

void LireEEPROM(int ParametresConfig[TAILLE_TABLEAU])
{
  for (int i = 0; i < TAILLE_TABLEAU; i++)
  {
    EEPROM.get(i * sizeof(long), ParametresConfig[i]);
  }
}

void DonneesGPS()
{
  String GPS = "";
  if (mode_actu == MODE_ECO){
    etatGPS = !etatGPS;
    GPS = F("Aucune mesure effectuée");
  }

  else{
    etatGPS = true;
  }

  if ((SoftSerial.available() > 0) && (etatGPS))
  {
    GPS = F("");
    unsigned long StartGPS = millis();
    do
    {
      GPS = SoftSerial.readStringUntil('\n');
      if ((millis() - StartGPS) > 10000)
      {
        erreur_acces_GPS();
        Affichage(F("GPS Timeout"), true);
        StartGPS = millis();
        break;
      }
    } while (!GPS.startsWith(F("$GPGGA")));
    Affichage(GPS, true);
  }
}

void Affichage(String Donnees, bool ligne)
{
  if (mode_actu == MODE_MAINTENANCE)
  {
    if (ligne)
    {
      Serial.println(Donnees);
    }
    else
    {
      Serial.print(Donnees);
    }
  }
  else
  {
    Fichier.print(Donnees);
  }
}

void PointVirgule()
{
  Affichage(F(" ; "), false);
}

void SeparateurHorloge()
{
  Affichage(F(":"), false);
}

void Creation()
{
  DateTime Maintenant = rtc.now();
  Affichage(Maintenant.hour() > 9 ? String(Maintenant.hour()) : '0' + String(Maintenant.hour()), false);
  SeparateurHorloge();
  Affichage(Maintenant.minute() > 9 ? String(Maintenant.minute()) : '0' + String(Maintenant.minute()), false);
  SeparateurHorloge();
  Affichage(Maintenant.second() > 9 ? String(Maintenant.second()) : '0' + String(Maintenant.second()), false);
  PointVirgule();
  GenerationDonnees();
  DonneesGPS();
}

I have no other idea, except that you could also take a GPS library for this.

Looks to me like each GPS response string starts with $, so could you not simply, in loop(), discard every character received until $, then process what you get until the next $?

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