#include #include /*Déclaration port série pour connexion au GPS*/ #define RX 2 // Port software RX #define TX 3 // Port software TX SoftwareSerial ss(RX, TX); /*Déclaration écran LCD*/ #define LCDADDR 0x20 LiquidCrystal_I2C lcd(LCDADDR, 16,2); /*Déclaration Ports reliés au Relais, Fuseau horaire et lecteur de carte*/ #define PINRELAIS 4 #define PINSDCARDCS 10 #define TIMEZONE 2 //GMT +2:00 /*Déclaration pour messages GPS*/ #define MAX_MESSAGE 80 char message[MAX_MESSAGE]; int nbsat = 0; float alt = 0; float corralt = 0; long hms = 0; long dat = 0; float lat = 0; float lon = 0; float spd = 0; int counter = 0; int fix = 0; String DataFileName; unsigned long currentmillis,previousmillis; const byte speedmini = 1; byte posrelais=0; bool SDCARD_present=true; /* Librairie carte SD*/ #include #include /***************************************************************************/ /* Lors de la création d'un fichier sur la carte, faire en sorte qu'il ait */ /* la bonne date-heure de création */ /***************************************************************************/ void FDateTime(uint16_t* date, uint16_t* time) { int d,m,y,hr,mn,sec; y=(dat%100); m=(((dat-y)/100)%100); d=((dat-y-100*m)/10000); y=y+2000; sec=(hms%100); mn=(((hms-sec)/100)%100); hr=((hms-sec-100*mn)/10000); *date = FAT_DATE(y, m, d); *time = FAT_TIME(hr, mn, sec); } /***********************************************************************************/ /*Initialisation et vérification SDCARD, fournit SDCARD_present : variable globale */ /***********************************************************************************/ bool InitSDCard() { //Serial.println(F("Init SDCard")); clearLCD(1,0,15); lcd.setCursor (0, 1); lcd.print(F("Init SDCard")); if (!SD.begin(PINSDCARDCS)) { delay(1000); if (!SD.begin(PINSDCARDCS)) { //Serial.println(F("Check SD Format ")); SDCARD_present = false; } } if (!SDCARD_present) { lcd.setCursor (12, 1); lcd.print(F("Fail")); } else { lcd.setCursor (14, 1); lcd.print(F("Ok")); } } /**************************************************************************/ /*Effacer une ligne de l'écran LCD de la position deb à la position fin */ /**************************************************************************/ void clearLCD(byte line,byte deb,byte fin) { lcd.setCursor(deb ,line); for(int n = deb; n <= fin; n++) // 20 indicates symbols in line. For 2x16 LCD write - 16 { lcd.print(F(" ")); } } /*********************************************/ /* date et heure UTC en local (+2) */ /*********************************************/ String formatdatetime(long ldat,long lhms, String format) { char buff[19]; int d2,m2,y2,hr2,mn2,sec2; bool bissextile; byte lastday; y2=(ldat%100); m2=(((ldat-y2)/100)%100); d2=((ldat-y2-100*m2)/10000); y2=y2+2000; sec2=(lhms%100); mn2=(((lhms-sec2)/100)%100); hr2=TIMEZONE+((lhms-sec2-100*mn2)/10000); /* Serial.print("ldat:"); Serial.print(ldat); Serial.print(" d2:"); Serial.print(d2); Serial.print(" m2:"); Serial.print(m2); Serial.print(" y2:"); Serial.println(y2); Serial.print("lhms:"); Serial.print(lhms); Serial.print(" hr2:"); Serial.print(hr2); Serial.print(" mn2:"); Serial.print(mn2); Serial.print(" sec2:"); Serial.println(sec2); */ while (hr2>=24) { d2=d2+1; hr2=hr2-24; } bissextile=false; if (y2%400==0) { bissextile=true; } else { if (y2%4==0 && y2%100!=0) { bissextile=true; } } lastday=28; if ( bissextile == true && m2 == 2 ) { lastday = 29; } if ( m2 == 4 || m2 == 6 || m2 == 9 || m2 == 11 ) { lastday = 30; } if ( m2 == 1 || m2 == 3 || m2 == 5 || m2 == 7 || m2 == 8 || m2 == 10 || m2 == 12 ) { lastday = 31; } if (d2>lastday) { d2=d2-lastday; m2=m2+1; } if (m2>12) { y2=y2+1; m2=m2-12; } if (format=="SSAAMMJJHRMNSEC") { sprintf(buff, "%04d%02d%02d%02d%02d%02d",y2,m2,d2,hr2,mn2,sec2); } else if (format=="JJHRMNSEC") { sprintf(buff, "%02d%02d%02d%02d",d2,hr2,mn2,sec2); } else if (format=="JJ/MM/SSAA HR:MN:SEC") { sprintf(buff, "%02d/%02d/%04d %02d:%02d:%02d",d2,m2,y2,hr2,mn2,sec2); } else if (format=="JJ/MM/SSAA HR:MN") { sprintf(buff, "%02d/%02d/%04d %02d:%02d",d2,m2,y2,hr2,mn2); } /* Serial.print("dat:"); Serial.print(dat); Serial.print(" d2:"); Serial.print(d2); Serial.print(" m2:"); Serial.print(m2); Serial.print(" y2:"); Serial.println(y2); Serial.print("hrms:"); Serial.print(hrms); Serial.print(" hr2:"); Serial.print(hr2); Serial.print(" mn2:"); Serial.print(mn2); Serial.print(" sec2:"); Serial.println(sec2); */ return String(buff); } /************************************************/ /** Affichage LCD données invalides **/ /************************************************/ void DataInvalid() { lcd.setCursor(0,0); lcd.print(F("Christophe's GPS ")); lcd.setCursor(0,1); lcd.print(F("GPS DATA INVALID")); } /************************************************/ /** Affichage LCD données Alt et Speed **/ /************************************************/ void Aff_Alt_Speed(){ lcd.setCursor(0,0); lcd.print(F("Speed: ")); clearLCD(0,7,11); lcd.setCursor(7,0); if (spd<100) { lcd.print(F("0")); } if (spd<10) { lcd.print(F("0")); } lcd.print(spd,1); lcd.print(F(" Kts")); lcd.setCursor(0,1); lcd.print(F("Alt : ")); clearLCD(1,7,15); lcd.setCursor(7,1); if (alt<10000) { lcd.print(F("0")); } if (alt<1000) { lcd.print(F("0")); } if (alt<100) { lcd.print(F("0")); } if (alt<10) { lcd.print(F("0")); } lcd.print(alt,1); lcd.print(F(" m")); } /************************************************/ /** Affichage LCD coordonnées **/ /************************************************/ void Aff_COORD(){ lcd.setCursor(0,0); lcd.print(F("Lat : ")); clearLCD(0,6,15); lcd.setCursor(6,0); if (lat<0) { lcd.print(F("S ")); } else { lcd.print(F("N ")); } if (abs(lat)<100) { lcd.print(F("0")); } if (abs(lat)<10) { lcd.print(F("0")); } lcd.print(abs(lat),4); lcd.setCursor(0,1); lcd.print(F("Long: ")); clearLCD(1,6,15); lcd.setCursor(6,1); if (lon<0) { lcd.print(F("W ")); } else { lcd.print(F("E ")); } if (abs(lon)<100) { lcd.print(F("0")); } if (abs(lon)<10) { lcd.print(F("0")); } lcd.print(abs(lon),4); } /************************************************/ /** Affichage LCD Date/Heure et Sat **/ /************************************************/ void Aff_DateTime_Sat() { lcd.setCursor(0,0); lcd.print(formatdatetime(dat,hms,"JJ/MM/SSAA HR:MN")); lcd.setCursor(0,1); lcd.print(F("Satellites: ")); clearLCD(1,12,15); lcd.setCursor(12,1); lcd.print(nbsat); } /***************************************************/ /* Ecire les trrames NMEA */ /***************************************************/ bool EcrireData(byte nbe) { if (DataFileName=="" ||posrelais==0) { return true; } //on prend 12 trames successives de GPS et on se pose if (counter%nbe>24) { return true; } if (!SDCARD_present) { Serial.println(F("SDCard absente")); return true; } //Serial.println(F("------------ECRIRE DATA-------------------")); File datafile = SD.open(DataFileName, O_CREAT | O_WRITE); //delay(50); if (!datafile) { lcd.setCursor(0,1); lcd.print(F("SDCARD LOG ERR D")); delay(250); lcd.setCursor(0,1); lcd.print(F("ON ")); lcd.print(DataFileName); delay(250); return false; } else { //Serial.println(F("WRITING DATA")); datafile.println(message); datafile.close(); } return true; } void setup() { Serial.begin(115200); ss.begin(9600); lcd.init(); lcd.backlight(); lcd.setCursor(0,0); lcd.print(F("Christophe's GPS")); lcd.setCursor(0,1); lcd.print(F("Aero Info - 2021")); counter = -1; pinMode(PINRELAIS, OUTPUT); digitalWrite(PINRELAIS,LOW); InitSDCard(); delay(1000); } void loop() { /*********************************************/ /* Lecture d'une ligne complère de trame GPS */ /*********************************************/ byte bcar = 0; int index = 0; // boucle qui attends un \n pour valider la trame et la décoder (/!\ Passer l'option en bas à droite du moniteur série en "Nouvelle ligne") while (bcar!=10) { // si un caractère est présent sur la liaison if(ss.available()) { // lecture d'un caractère bcar = ss.read(); // concaténation du caractère au message if (bcar!=10 && bcar!=13 && index < MAX_MESSAGE - 10 ) { //Serial.print("Concate "); Serial.println (index); message[index]=(char) bcar; index++; message[index]=0; //Serial.println ((char) bcar); } } } //Serial.println (message); /*Copier Message, qui restera inchangé, à copier intégralement dans le fichier data */ /*dans un buffer buff qui lui va varier pour analyser la trame */ char buff[MAX_MESSAGE]; strcpy(buff,message); strtok(buff,","); /*variable temporaire*/ char *p; if (strcmp(buff,"$GPGGA")==0) { strtok(NULL,","); //heure acquisistion fix strtok(NULL,","); //Latitude (encore) strtok(NULL,","); //Latitude (sens encore) strtok(NULL,","); //Longitude (encore) strtok(NULL,","); //Longitude (sens encore) fix=atoi(strtok(NULL,",")); //Fix : si >0 alors OK nbsat=atoi(strtok(NULL,",")); //nbsat (meme si data invalid) //Serial.print ("--------nbsat "); Serial.println (nbsat); if (fix==0) { Serial.println ("Data Invalid"); } else { strtok(NULL,","); //Dilution horizontale alt=atof(strtok(NULL,",")); //Altitude en mettre strtok(NULL,","); //unite corralt=atof(strtok(NULL,",")); //Altitude en mettre : correction strtok(NULL,","); //unite /* Serial.print ("fix:"); Serial.print (fix); Serial.print (" nbsat:"); Serial.print (nbsat); Serial.print (" alt:"); Serial.print (alt); Serial.print (" corralt:");Serial.print (corralt); Serial.println(); */ } } else if (strcmp(buff,"$GPRMC")==0) { hms=atol(strtok(NULL,",")); p=strtok(NULL,","); char fstatus=*p; //A : data valid, V : data invalid //Serial.print ("fstatus:"); Serial.println (fstatus); if (strcmp(p,"A")!=0) { fix=0; Serial.println ("Data Invalid"); } else { fix=1; lat=atof(strtok(NULL,","))/100; p=strtok(NULL,","); if (strcmp(p,"S")==0) {lat=-1*lat;} lon=atof(strtok(NULL,","))/100; p=strtok(NULL,","); if (strcmp(p,"W")==0) {lon=-1*lon;} spd=atof(strtok(NULL,",")); dat=atol(strtok(NULL,",")); /* Serial.print ("hms:"); Serial.print (hms); Serial.print (" lat:"); Serial.print (lat,4); Serial.print (" long:"); Serial.print (lon,4); Serial.print (" speed:"); Serial.print (spd,2); Serial.print (" dt:"); Serial.print (dat); Serial.println(); */ } } counter++; /************************************************/ //Serial.print ("counter:"); Serial.println (counter); if (fix==0) { if (counter%20==0) { DataInvalid(); } } if (!SDCARD_present && counter>0 && counter%50==0) { InitSDCard(); } if (spd=speedmini) { /*Initialisation*/ SdFile::dateTimeCallback(FDateTime); posrelais = 1; digitalWrite(PINRELAIS,HIGH); //Si carte SD ok, maintenant que j'ai une date gps, je peux enfin initialiser ce lecteur avec la date et l'heure GPS if (SDCARD_present) { DataFileName=formatdatetime(dat,hms,"JJHRMNSEC")+".CSV"; //Serial.print(F("DataFileName : ")); //Serial.println(DataFileName); currentmillis=millis(); } } //Mise à jour fichier compteur et Sauvegarde trame dans fichier des data if (posrelais>0) { EcrireData(50); } //Affichage if (counter >= 0 && counter <=100 && counter%10==0) { //Serial.println (F("-------------DATE-HEURE----------------")); Aff_DateTime_Sat(); } if (counter >= 101 && counter <=200 && counter%10==0) { //Serial.println (F("-------------COORD------------------")); Aff_COORD(); } if (counter >= 201 && counter <=300 && counter%10==0) { //Serial.println (F("-------------ALTSPEED------------------")); Aff_Alt_Speed(); } } if (counter > 300) { counter = 0; } }