Bonjour à toutes et à tous,
Dans mon projet de routeur photovoltaïque, j'ai une variable energQuot qui se réinitialise toute seule, à des moments qui ne me semblent pas en rapport avec un évènement dans cette boucle de calcul.
Cette variable représente l'énergie consommée. Elle est mise à jour toutes les secondes et normalement remise à zéro au passage au jour suivant. Cela se situe dans void loop(){...}. Voilà le morceau de code concerné :
void loop() {
ArduinoOTA.handle();
etatNouv = digitalRead(pin_DetSinus);
if (etatNouv == HIGH && etatPrec == LOW) { // Il n'y a changement d'état que si le réseau est présent
t1 = 0; // Réinitialisation du compteur de défaut
pb = false; // Si on passe dans cette boucle, c'est que le réseau est présent
statut0 = "Normal";
digitalWrite(ledPB, LOW); // on éteint la LED de défaut
noMesure ++;
if (noMesure >= nbP50Hz) {
noMesure = 0;
}
pAonde = Infos_UIP(pin_Commun, pin_Tension, pin_Courant, 0.784, 0.06, nbPt, ptsV, ptsI, &vRMS, &iRMS); // Mesure toutes les 20 mS
sumPA += pAonde;
if (noMesure == 0) { // Commencement de la série de nbP50Hz mesures
infUIoK = false;
pActif = sumPA/nbP50Hz;
energQuot += pActif*jTokWh;
infUI = "";
for (uint8_t i = 0; i < nbPt; i++) {
infUI += String(ptsV[i])+","+String(ptsI[i])+"\n";
ptsV[i] = 0;
ptsI[i] = 0;
}
infUIoK = true;
Vu = !Vu;
digitalWrite(ledOK, Vu);
if (Vu)
teta0 = sensors.getTempC(sonde0, 0); // Comme la mesure prend 12 ms, on alterne la mesure entre les deux sondes
else
teta1 = sensors.getTempC(sonde1, 0); // Comme la mesure prend 12 ms, on alterne la mesure entre les deux sondes
forceWiFi = String(WiFi.RSSI());
getLocalTime(&timeinfo);
strftime(info_DH, 24, "%d/%m/%Y %H:%M:%S,", &timeinfo); // Mise en forme de la date : JJ/MM/AAA HH:MM:SS
sprintf(info_UIP, "%.1f,%.1f,%.1f,%.4f\n", pActif, vRMS, iRMS, energQuot); // Représente 28 octets au maximum
if (timeinfo.tm_sec % 30 == 0) { // Enregistrement toutes les 30 secondes
appendFile2(LittleFS, fchHisto, info_DH, info_UIP, 115200); // Enregistrement d'une nouvelle ligne de données
affOLED(0);
if(timeinfo.tm_yday != jourPrec) { // MàJ de l'heure à chaque changement de jour et ...
configTime(gmtOffset_sec, daylightOffset_sec, ntpServer); // On configure le seveur NTP
energQuot = 0; // Remise à zéro du cumul de l'énergie quotidienne
fchHisto = remplaceFchHisto(); // ... remplace l'ancien fichier "fchHisto" portant sur le même jour de la semaine
jourPrec = timeinfo.tm_yday;
}
}
if (pActif < 0) // Si il y a surplus de production
nbP_CmdTriac += 1+50*pActif/pMaxSurplus;
else
nbP_CmdTriac -= 1+50*pActif/pMaxSurplus;
nbP_CmdTriac = constrain(nbP_CmdTriac, 0, 49);
sumPA = 0; // Remise à zéro de la puissance moyenne toutes les nbP50Hz périodes
if (nbP_CmdTriac == 0)
digitalWrite(pin_CmdTriac, LOW);
else
digitalWrite(pin_CmdTriac, HIGH);
modeFonctionnement(); // Modifie la gestion du surplus de production. Fonction vide pour l'instant
sensors.requestTemperatures(); // Initialisation de la mesure sur toutes les sondes de température DS18B20
Serial.print("Nb = "+String(nbP_CmdTriac)+" ");
Serial.print(info_DH);
Serial.print(" ");
Serial.print(info_UIP);
}
}
if (nbP_CmdTriac < noMesure) // Remise à zéro de la commande du triac
digitalWrite(pin_CmdTriac, LOW); // Attention, cette commande doit arriver avant le front montant de la tension EDF
etatPrec = etatNouv;
t1++;
pb = statut();
}
Quelques variables concernées :
const uint8_t nbP50Hz = 50; // Intervalle de temps entre chaque mesure en nombre de périodes de 50 Hz
char nom_Fch[24]; // Chaîne de caractères pour le nom du fichier de données historiques
char info_DH[24]; // Chaîne de caractères pour l'écriture de la date-heure
float pAonde; // Valeur de la puissance active sur une période de 50 Hz
float sumPA; // Somme partielle de pAonde
float vRMS, iRMS; // Valeur efficace pour la tension et le courant
float energQuot; // valeur du cumul de l'énergie quotidienne
char info_UIP[32]; // Chaîne de caractères pour l'écriture des données
La requête faite par le client :
server.on("/histoUIP", HTTP_GET, [](AsyncWebServerRequest *request) { // Envoi du fichier d'historique pour affichage
uint32_t ti = millis();
while (infUIoK == false && millis()-ti < 3000) {}
request->send(LittleFS, fchHisto, String(), false);
});
Le résultat de compilation :
Le croquis utilise 1159981 octets (88%) de l'espace de stockage de programmes. Le maximum est de 1310720 octets.
Les variables globales utilisent 52424 octets (15%) de mémoire dynamique, ce qui laisse 275256 octets pour les variables locales. Le maximum est de 327680 octets.
Le fichier transmis fait 100 ko au maximum. La réinitialisation de la variable se passe parfois alors que le fichier fait à peine 20 ko.
Si vous avez une idée, une piste de ce qui peut perturber cette variable.
Cordialement.
Pierre.