#include <SD.h>
#define CS_PIN 5
// Variable des repertoires et nom fichier pour log data carte SD
char Repertoire[6] = "/data"; // 5 +1
char lastfile[19] = "/data/lastfile.txt"; // 18 +1
char Year[19]; // /data/2023 -> 10 +1
char YearMonth[31]; // /data/2023/08 -> 13 +1
char YearMonthDayFile[47]; // /data/2023/08/06.txt -> 20 +1
char DateHour[73]; // 2021-05-20T22:30:00 -> 19 +1
void setup() {
Serial.begin(115200);
Serial.print("Initializing SD card... ");
if (!SD.begin(CS_PIN)) {
Serial.println("Card initialization failed!");
while (true);
}
Serial.println("initialization done.");
}
void loop() {
time_t now = time(nullptr);
struct tm * timeinfo;
timeinfo = localtime(&now);
//if ((timeinfo->tm_min % 1) == 0) { // toutes les 5 min (timeinfo->tm_min % 5) == 0) -> Enregistrement carte SD
printLocalTime(timeinfo);
createfileSD();
//}
if (readlastcaract(SD, lastfile) == '}') {
Serial.print("last char : ");
Serial.println(readlastcaract(SD, YearMonthDayFile));
}
else {
Serial.print("last char : ");
Serial.println(readlastcaract(SD, lastfile));
}
delay(2000);
//readlastcaract(SD, lastfile);
String prevFile;
prevFile = readlastFile(SD, lastfile);
Serial.print("prevFile : ");
Serial.println(prevFile);
delay(2000);
}
// Lecture last file SD CARD:
char readlastcaract(fs::FS &fs, const char * path) {
File file = fs.open(path);
file.seek(file.size()-1);
char last;
while (file.available()) {
last = file.read(); // (char)
}
file.close();
return (char)last; // autre
}
// cloture le fichier precedent J-1 ou J-10, et met a jour le fichier /data/lastfile.txt avec le nom du fichier du jour
void closelastfile() {
Serial.println("Je passe ici closelastfile debut");
//String closeMessage;
String prevFile;
if (SD.exists(lastfile)) {
prevFile = readlastFile(SD, lastfile); // lit le nom du dernier fichier (/data/lastfile.txt)
if (prevFile != YearMonthDayFile) { // si different de la date du jour
if (SD.exists(prevFile.c_str())) {
//closeMessage = "\r\n]";
appendFile(SD, prevFile.c_str(), (char*)"\r\n]"); // on cloture le fichier du jour precedent J-1 ou J-10
//appendFile(SD, prevFile.c_str(), closeMessage.c_str()); // on cloture le fichier du jour precedent J-1 ou J-10
}
}
}
writeFile(SD, lastfile, YearMonthDayFile); // remplace le fichier lastFile avec date du jour (creer un nouveau fichier a chaque fois)
Serial.println("Je passe ici write lastfile");
}
// Lecture last file SD CARD:
String readlastFile(fs::FS &fs, const char * path) {
//if (serialDebug) Serial.printf("Reading lastFile: %s\n", path);
File file = fs.open(path);
String value;
//char fileData[21]; // /data/2023/08/06.txt -> 20 +1
//int8_t index = 0;
while (file.available()) { // If the file is present execute loop until done.
//fileData[index] = (char)file.read();
value += (char)file.read();
//index++;
}
/*
if (serialDebug) {
Serial.print("Read from lastFile: ");
Serial.println(value);
}
*/
file.close();
Serial.print("value : ");
Serial.println(value);
return String(value);
}
// Creation repertoire SD CARD:
void createDir(fs::FS &fs, const char * path) {
//if (serialDebug) Serial.printf("Creating Dir: %s\n", path);
if (fs.mkdir(path)) {
//if (serialDebug) Serial.println("Dir created");
}
//else {
// //if (serialDebug) Serial.println("mkdir failed");
//}
}
// Ecriture fichier SD CARD: (Ecrase contenu fichier si existe ecriture NOUVEAU FICHIER)
void writeFile(fs::FS &fs, const char * path, const char * message) {
//if (serialDebug) Serial.printf("Writing file: %s\n", path);
File file = fs.open(path, FILE_WRITE);
if (!file) {
//if (serialDebug) Serial.println("Failed to open file for writing");
return;
}
if (file.print(message)) {
//if (serialDebug) Serial.println("File written");
}
//else {
// //if (serialDebug) Serial.println("Write failed");
//}
file.close();
}
// Ecriture a la suite du fichier SD CARD: (ajoute contenu fichier existant)
void appendFile(fs::FS &fs, const char * path, const char * message) {
//if (serialDebug) Serial.printf("Appending to file: %s\n", path);
File file = fs.open(path, FILE_APPEND);
if (!file) {
//if (serialDebug) Serial.println("Failed to open file for appending");
return;
}
if (file.print(message)) {
//if (serialDebug) Serial.println("Message appended");
}
//else {
// //if (serialDebug) Serial.println("Append failed");
//}
file.close();
}
// creation variable repertoire et nom fichier avec parametre serveur NTP
void printLocalTime(struct tm * timeinfo) {
//Format "%d/%m/%Y - %H:%M:%S" (-> 19/01/2024 - 04:15:00 (21+1 char))
//char dateTime[22];
//snprintf(dateTime, 22, "%02d/%02d/%04d - %02d:%02d:%02d", timeinfo->tm_mday, timeinfo->tm_mon + 1, timeinfo->tm_year + 1900, timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
//Serial.println(dateTime);
// Format "%Y-%m-%dT%H:%M:%S" // Date + heure dans fichier (-> 2024-01-19T04:15:00)
snprintf(DateHour, 73, "%04d-%02d-%02dT%02d:%02d:%02d", timeinfo->tm_year + 1900, timeinfo->tm_mon + 1, timeinfo->tm_mday, timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);
//Serial.println(DateHour);
// Format "/data/%Y/%m/%d.txt" // Repertoire Année + Mois + nom fichier jour.txt (-> /data/2024/01/19.txt)
snprintf(YearMonthDayFile, 47, "/data/%04d/%02d/%02d.txt", timeinfo->tm_year + 1900, timeinfo->tm_mon + 1, timeinfo->tm_mday);
//Serial.println(YearMonthDayFile);
// Format "/data/%Y/%m" // Repertoire Année + Mois (-> /data/2024/01)
snprintf(YearMonth, 31, "/data/%04d/%02d", timeinfo->tm_year + 1900, timeinfo->tm_mon + 1);
//Serial.println(YearMonth);
// Format "/data/%Y" // Repertoire Année (-> /data/2024)
snprintf(Year, 19, "/data/%04d", timeinfo->tm_year + 1900);
//Serial.println(Year);
}
//Ecriture des données sur la carte SD (creation repertoire fichier et fermeture fichier J-1)
void createfileSD() {
// Message a ecrire dans le fichier du jour carte SD
String dataMessage;
String appendMessage;
String headerMessage;
String modeIris;
String etatPID;
String modeVentiloStatus;
dataMessage = "{ 'Date': '"; // Ouverture dataMessage
dataMessage += DateHour;
dataMessage += "', 'SONDES': {";
dataMessage += " '";
dataMessage += "SondeNom[3]";
dataMessage += "': ";
dataMessage += "-10"; // Sonde Exterieure
dataMessage += ", '";
dataMessage += "SondeNom[0]";
dataMessage += "': ";
dataMessage += "37"; // Sonde Moteur
dataMessage += ", '";
dataMessage += "SondeNom[1]";
dataMessage += "': ";
dataMessage += "30"; // Sonde Chaud
dataMessage += ", '";
dataMessage += "SondeNom[2]";
dataMessage += "': ";
dataMessage += "20"; // Sonde Froid
dataMessage += "}";
dataMessage += ", 'IRIS': {";
dataMessage += " 'Mode': '";
dataMessage += "modeIris";
dataMessage += "'";
dataMessage += ", 'Position': ";
dataMessage += "200";
dataMessage += "}";
dataMessage += ", 'VENTILATEUR': {";
dataMessage += " 'Mode': '";
dataMessage += "modeVentiloStatus";
dataMessage += "'";
dataMessage += ", 'Etat': '";
dataMessage += "etatVentilo";
dataMessage += "'";
dataMessage += ", 'RPM': ";
dataMessage += "rpm";
dataMessage += ", 'PWM': ";
dataMessage += "pwm";
dataMessage += ", 'CorrPWM': ";
dataMessage += "50";
dataMessage += ", 'Temp_ON_Min': ";
dataMessage += "50";
dataMessage += ", 'Temp_OFF_Max': ";
dataMessage += "50";
dataMessage += " }";
dataMessage += ", 'PID': {";
dataMessage += " 'Etat': '";
dataMessage += "etatPID";
dataMessage += "'";
dataMessage += ", 'Mode': '";
dataMessage += "PidMod";
dataMessage += "'";
dataMessage += ", 'Consigne': ";
dataMessage += "50";
dataMessage += " }";
dataMessage += " }"; // Fermeture dataMessage
/*
{ 'Date': '2023-12-09T00:30:00',
'SONDES': { 'Sext': -22,00, 'Smoteur': 22,00, 'Schaud': 19,44, 'Sfroid': 22,06},
'IRIS': { 'Mode': 'Auto', 'Position': 125},
'VENTILATEUR': { 'Mode': 'Auto', 'Etat': 'Arret', 'RPM': 0, 'PWM': 0, 'Temp_ON_Min': 25,0, 'Temp_OFF_Max': 55,0 },
'PID': { 'Etat': 'Inactif', 'Mode': '', 'Consigne': 30,0 }
}
*/
if (SD.exists(YearMonthDayFile)) { // Si le fichier du jour existe deja on continu a ecrire a la suite
appendMessage = ",\r\n"; //retour a la ligne avant message
appendMessage += dataMessage;
appendFile(SD, YearMonthDayFile, appendMessage.c_str());
}
else { // Le fichier du jour existe pas
headerMessage = "data = [\r\n";
headerMessage += dataMessage;
if (SD.exists(Repertoire)) { // si data existe
if (SD.exists(Year)) { // Si l'annee existe
if(!SD.exists(YearMonth)) { // Si le mois existe pas
createDir(SD, YearMonth); // on cree mois
}
}
else { // Sinon on cree annee + mois
createDir(SD, Year);
createDir(SD, YearMonth);
}
}
else { // Sinon on cree data + annee + mois
createDir(SD, Repertoire);
createDir(SD, Year);
createDir(SD, YearMonth);
}
writeFile(SD, YearMonthDayFile, headerMessage.c_str()); // On cree le fichier du jour
closelastfile(); // on cloture le fichier du jour precedent
}
///*if (serialDebug) */Serial.println(dataMessage); // Affiche la ligne que l'on vient d'enregistrer dans le fichier
}