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();
}