Exception (29) sur esp 8266

Bonjour, je travaille toujours sur mon projet de station météo, et je remarque que mon wemos d1 mini redémarre de façon aléatoire (de qqes minutes à qqes heures) avec ce message Exception (29).

Après des recherches sur google il semblerait que le module essaye d'écrire dans une zone interdite mais je ne vois pas où dans mon sketch, voici le code principal :

/*
  Station météo à base d'un ESP8266, et envoi des données
  vers Influxdb, Weathercloud et Wunderground.
  Création Dominique PAUL.

  Adaptée par Anthony&Philippe

  Version 3_2 : ajout de l'envoi de l'angle de direction du vent dans influxdb
             envoi des données pluie valeur = 0 pour avoir prévision météo dans Weathercloud

  Version 3_3 : correction de bugs dans weathercloud ex wchill et heat en cas de non vent ou de chaleur
              envoi des données vers wunderground

  Version 3_4 : correction du bug sur wunderground pour dew
              envoi du RSSI wifi sur Influxdb

  Version 3_5 : séparation de Weathercloud et wunderground pour des envois séparés.
              affichage du Rssi Wifi dans le voltage weathercloud et Influxdb.

  Version 3_5_5 : ajout d'un pluviomètre et envoi des données sur WC, WU et Influxdb
                mise en eeprom de la valeur pluieJour en cas de panne de courant ou redémarrage
                réglage heure hiver et été dans wifi.cpp

  Version 3_5_6 : essai d'envoi des données du pluvio toutes les 6 minutes au lieu de 2
               pour economiser de l'eeprom
        3_5_61 : suppression du fifo dans pluvio.cpp

  Version 3_5_7 : essai d'une autre librairie pour OTA et avoir un serveur web
                incrémentation du nombre de lecture eeprom pour debug
                ajout de conditions pour remise à zéro de pluieJour dans pluvio.cpp
                essai de calibration du pluvio avec un godet à 0,0931

  Version 3_5_71 : essai de raincount24h++ pour la valeur de pluieJour et suppression des écritures dans eeprom
		              ajout d'un module horloge et sd card DS1307 pour obtenir date et heure sans NTP, sans Wifi et en cas de
		              coupure de courant et écriture valeur pluieJour sur carte SD.
                 ajout d'une page web pour redémarrer 192.168.1.../restart.
                 ajout d'une page web pour réinitialiser le BME280 192.168.1.xxx/bmereset
                 ajout de myTime dans vent.cpp pour duree de connexion de la station sur influxdb

  Version 3_5_72_2209_2023 : ajout d'un capteur UV VEML6075
			     essai envois d'email.

  Version 3_7 : utilisation de la nvram du ds1307 pour enregistrer valeurs pluieJour et jourCourant, et rafaleMaxi et suppression du module carte SD.


  Dépot Github : https://github.com/DomoticDIY/.........
  Chaine YouTube du Tuto Vidéo : https://www.youtube.com/c/DomoticDIY

  Bibliothéques nécessaires, et version utilisées :
  - pubsubclient v2.7.0 : https://github.com/knolleary/pubsubclient
  - ArduinoJson v6.15.0 : https://github.com/bblanchon/ArduinoJson
  - ESP8266Wifi v1.0.0
  - Adafruit unified sensor v 1.1.2
  - Adafruit BME280 v2.0.2
  - Sparkfun VEML6075 library v2.2.0
  - NTPClient by Fabrice Weinberg v3.2.0
  - CircularBuffer by AgileWare v1.3.3

  Connexions sur Wemos D1 mini :
  - pluviomètre sur D5
  - anemomètre sur D6
  - girouette  sur A0
  - carte LEXTRONIC 3V sur 3V3
  - carte LEXTRONIC GND sur G
  - bme 280 SDA sur D2
  - bme 280 SCL sur D1
  - bme 280 GND sur GND LEXTRONIC
  - bme 280 3V3 sur 3V3 LEXTRONIC
  - veml6075 SDA sur D2
  - veml6075 SCL sur D1
  - veml6075 GND sur GND LEXTRONIC
  - veml6075 3V3 sur 3V3 LEXTRONIC
  - DS1307 SDA sur D2 Horloge
  - DS1307 SCL sur D1 Horloge
  - DS1307 GND sur... Horloge
  - DS1307 3V3 sur .... Horloge


  Gestionnaire de carte ESP8266 version 3.1.2
  Type de carte : generic ESP8266 module
  Flash mode 'DOUT' 
  Flash size : 4MB (FS: none)(OTA :1019 kb)
*/

#include "connect.h"
#include "wifi.h"
#include "bme280.h"
#include "vent.h"
#include "pluvio.h"
#include "veml6075.h"

#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <ESP_Mail_Client.h>

#include <AsyncElegantOTA.h>
#include <SPI.h>
#include <Wire.h>   // I2C library
#include "I2Cbus.h" // I2Cbus library
#include <RTClib.h>



// Variables et constantes utilisateur :

#define INTERO_CAPTEURS 300                // 5m (300s) : Valeur de l'intervalle en secondes entre 2 relevés des capteurs (BME280 et VEML6075)et envoi sur Influxdb.

unsigned long t_lastActionPluvio = 0;      // enregistre le Time de la dernière intérogation des capteurs Pluviomètrie.
#define INTERO_PLUVIO 300                   // Valeur de l'intervale (300 ou 5 mn) en secondes entre 2 relevés des capteurs Pluviomètrie.

#define INTERO_VENT 30                     // 1/2 min (30s) Valeur de l'intervalle en secondes entre 2 relevés des capteurs Vent et envoi sur Influxdb.

unsigned long t_lastWeatherCloud = 0;
#define INTERVAL_WEATHERCLOUD  300         // 5 min (300s) d'intervalle pour les requêtes à WeatherCloud 

unsigned long t_lastWunderGround = 0;
#define INTERVAL_WUNDERGROUND  30          // 1/2 min (30s) d'intervalle pour les requêtes à Wunderground

unsigned long t_lastActionCapteur = 0;     // enregistre le Time de la dernière intérogation des capteurs.
unsigned long t_lastActionVent = 0;        // enregistre le Time de la dernière intérogation des capteurs vent.
unsigned long t_lastRafaleVent  = 0;       // Enregistre le Time du dernier relevé de Rafale de vent.

int i2cbusstatus;

AsyncWebServer server3(80);
SMTPSession smtp;

void setup() {

  pinMode(LED_BUILTIN, OUTPUT); // Initialize the LED_BUILTIN

  Serial.begin(115200);  // On initialise la vitesse de transmission de la console.
  delay(500);

 

  setup_wifi();                                   // Connexion au Wifi
 
  init_capteurs();                                // Initialisation des Capteurs de relevés


  //------------------------------------------------------------------------//
  server3.on("/", HTTP_GET, [](AsyncWebServerRequest * request) {
    request->send(200, "text/plain", "HTTP serveur OTA Station Essai  version 3_7_06112023.");
  });
  //-------------------------------------------------------------------------//
  server3.on("/heurehiver", HTTP_GET, [](AsyncWebServerRequest * request) {
    RTC_DS1307 rtc;
    rtc.begin();
    DateTime now = rtc.now();
    Serial.println(F("Le module RTC est actif !"));
    /*int hour = now.hour();
      hour = hour - 1;
      Serial.print("Nouvelle heure d'hiver:");
      Serial.println(hour);*/
    //rtc.adjust(DateTime(2023, 6, 18, 13, 59, 0));
    rtc.adjust(DateTime(now.year(), now.month(), now.day(), (now.hour() - 1), now.minute(), now.second()));
    request->send(200, "text/plain", "Heure modifiee -1H Hiver.");
    delay(1000);
  });
  //---------------------------------------------------------------------------//
  server3.on("/heurete", HTTP_GET, [](AsyncWebServerRequest * request) {

    RTC_DS1307 rtc;
    rtc.begin();
    DateTime now = rtc.now();
    Serial.println(F("Le module RTC est actif !"));
    /*int hour = now.hour();
      hour = hour + 1;
      Serial.print("Nouvelle heure d'été:");
      Serial.println(hour);*/
    //rtc.adjust(DateTime(2023, 6, 18, 13, 59, 0));
    rtc.adjust(DateTime(now.year(), now.month(), now.day(), (now.hour() + 1), now.minute(), now.second()));
    request->send(200, "text/plain", "Heure modifiee +1H Ete.");
    delay(1000);

  });
  //-----------------------------------------------------------------------//
  server3.on("/rtcajust", HTTP_GET, [](AsyncWebServerRequest * request) {

    RTC_DS1307 rtc;
    rtc.begin();
    DateTime now = rtc.now();
    Serial.println(F("L'horloge du module RTC est active !"));
    //rtc.adjust(DateTime(2023, 6, 18, 13, 59, 0));
    rtc.adjust(DateTime(now.year(), now.month(), now.day(), now.hour(), 0, 0));
    request->send(200, "text/plain", "RTC mise à la minute !");
    delay(1000);

  });
  //-----------------------------------------------------------------------//
  server3.on("/i2creset", HTTP_GET, [](AsyncWebServerRequest * request) {
    request->send(200, "text/plain", "Réinitialisation du bus I2C !");
    Serial.println("Réinitialisation du bus I2C");
    //init_bme();             // Initialisation de BME280.
    // Clear bus before Wire.begin()
    i2cbusstatus = I2Cbus_clear(SDA, SCL);
    Serial.println( I2Cbus_statusstr(i2cbusstatus) );

    // Enable I2C
    Wire.begin(SDA, SCL); // For ESP8266 NodeMCU boards [VDD to 3V3, GND to GND, SDA to D2, SCL to D1]
    //Wire.begin(); // Arduino pro mini or Nano [VDD to VCC/3V3, GND to GND, SDA to A4, SCL to A5]

    Serial.println("Effectué !");
    init_capteurs();                                // Réinitialisation des Capteurs de relevés

  });
  //----------------------------------------------------------------------//
  server3.on("/restart", HTTP_GET, [](AsyncWebServerRequest * request) {
    AsyncResponseStream *response = request->beginResponseStream("text/html");

    response->addHeader("Server", "ESP Async Web Server");

    response->printf("<!DOCTYPE html><html lang='en'>");
    response->printf("<head>");
    response->printf("<meta charset='UTF-8'>");
    response->printf("<title>Restart</title>");
    response->printf("<script> function confirmRestart() {const req = new XMLHttpRequest();req.open('GET', '/confirmRestart');req.send();}</script>");
    response->printf("</head>");
    response->printf("<body><button onclick='confirmRestart()'>Confirm restart</button></body>");
    response->printf("</html>");

    request->send(response);
  });

  server3.on("/confirmRestart", HTTP_GET, [](AsyncWebServerRequest * request) {
    request->send(200, "text/plain", "RESTART OK");
    delay(1000);
    ESP.reset();
  });
  //-----------------------------------------------------------------------------//


  AsyncElegantOTA.begin(&server3);    // Start ElegantOTA
  server3.begin();
  Serial.println("HTTP serveur OTA démarré version 3_7_06112023");
  Serial.print("Addresse IP : ");
  Serial.println(WiFi.localIP());

  Serial.println("Waiting for NTP server time reading");
  //  configTime(2 * 3600, 0, "pool.ntp.org", "time.nist.gov"); // heure été
  configTime(1 * 3600, 0, "pool.ntp.org", "time.nist.gov"); // heure hiver
  while (time(nullptr) < ESP_MAIL_CLIENT_VALID_TS)
  {
    delay(100);
  }

  MailClient.networkReconnect(true);

  Session_Config config;

  config.server.host_name = SMTP_HOST;
  config.server.port = SMTP_PORT;
  config.login.email = AUTHOR_EMAIL;
  config.login.password = AUTHOR_PASSWORD;
  config.login.user_domain = F("127.0.0.1");

  SMTP_Message message;

  // Set the message headers

  message.sender.name = F("Station Météo Lamartine");
  message.sender.email = AUTHOR_EMAIL;
  message.addRecipient(F("Someone"), RECIPIENT_EMAIL);

  // The time format of timestamp to inject into subject or content as using in strftime C++ function
  message.timestamp.tag = "#esp_mail_current_time";

  // The tag that will be replaced with current timestamp

  message.timestamp.format = "%B %d, %Y %H:%M:%S";

         message.subject = F("Test sending plain text Email (#esp_mail_current_time)");
 // message.subject = F("Démarrage ou Redémarrage Station Météo3  Email (#esp_mail_current_time)");
  
  message.text.content = "La Station Météo3 vient de re(démarrer) ! !\n\nEnvoyé le : #esp_mail_current_time";
  // message.text.content = "La Station Météo vient de re(démarrer) !";

  if (!smtp.connect(&config))
  {
    MailClient.printf("Connection erreur, Status Code: %d, Erreur Code: %d, Raison: %s\n", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str());
    return;
  }

  if (!smtp.isLoggedIn())
  {
    Serial.println("Pas connecté au serveur SMTP.");
  }
  else
  {
    if (smtp.isAuthenticated())
      Serial.println("Authentification réussie.");
    else
      Serial.println("Connecté sans autorisation.");
  }

  if (!MailClient.sendMail(&smtp, &message)) {
    MailClient.printf("Erreur, Status Code: %d, Erreur Code: %d, Raison: %s\n", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str());
  } else
  {
    Serial.println("Message bien envoyé !");
  }


}

void loop() {



  unsigned long currentMillis = millis();         // On enregistre le Time courant

  if ((WiFi.status() != WL_CONNECTED) && (currentMillis > 300000)) {
    Serial.println("Essai de reconnexion wifi ..redémarrage du Wemos !");
    ESP.restart();
  }


  //----------------------------------------------------------------------------------//
  // On vérifie si l'intervale d'envoi des informations "Vent" sont atteintes. (120s) //
  //----------------------------------------------------------------------------------//

  if (currentMillis - t_lastActionVent >= INTERO_VENT * 1000) {
    t_lastActionVent = currentMillis; // On met à jour la valeur du dernier traitement à maintenant.
    // Si il est actif, on envoi les info de vent.
#ifdef VENT_H
    setInfo_vent();    // Envoi des données de vent à Influxdb
#endif
  }

  // On reléve la rafale de vent des 5 dernières secondes.
  if (millis() - t_lastRafaleVent >= (5 * 1000)) {
    // On met à jour la valeur du dernier traitement de Rafale de vent à maintenant.
    t_lastRafaleVent = millis();

    // S'il est actif, On a atteint l'interval souhaité, on exécute le traitement Vent.
#ifdef VENT_H
    getRafale();
#endif
  }
  
  //--------------------------------------------------------------------------------//
  // On vérifie si l'intervale d'envoi des informations pluie sont atteintes. (120s)//
  //--------------------------------------------------------------------------------//
  
  if (currentMillis - t_lastActionPluvio >= INTERO_PLUVIO * 1000) {
    // On met à jour la valeur du dernier traitement à maintenant.
    t_lastActionPluvio = currentMillis;

    // Si il est actif, on envoi les info de pluviometre.
#ifdef PLUVIO_H
    getDataPluvio();    // Envoi des données de pluviomètrie à InfluxDb
#endif
  }

  //---------------------------------------------------------------------//
  // On vérifie si l'intervale de relevé des capteurs est atteint. (60s)-//
  //---------------------------------------------------------------------//

  if (currentMillis - t_lastActionCapteur >= INTERO_CAPTEURS * 1000) {
    // On met à jour la valeur du dernier traitement à maintenant.
    t_lastActionCapteur = currentMillis;

#ifdef BME280_H
    sendDataBME280(getWindSpeed());    // Relevé des données du BME280, et envoi à Influxdb
#endif

#ifdef VEML6075_H
    getDataVEML6075();  // Relevé des données du VEML6075, et envoi.
#endif
  }

  if (currentMillis - t_lastWunderGround >= INTERVAL_WUNDERGROUND * 1000) {
    // On met à jour la valeur du dernier traitement à maintenant.
    t_lastWunderGround = currentMillis;

#if defined(VENT_H) && defined(BME280_H)
    sendDataToWunderground();
#endif
  }

  if (currentMillis - t_lastWeatherCloud >= INTERVAL_WEATHERCLOUD * 1000) {
    // On met à jour la valeur du dernier traitement à maintenant.
    t_lastWeatherCloud = currentMillis;

#if defined(VENT_H) && defined(BME280_H)
    sendDataToWeatherCloud();
#endif
  }

  //ESP.wdtFeed();
  //delay(2000);

}  // fin de loop


//******************************//
// INITIALISATION des Capteurs  //
// *****************************//

void init_capteurs() {

#ifdef BME280_H
  init_bme();             // Initialisation de BME280.
#endif

#ifdef VEML6075_H
  init_veml();            // Initialisation du VEML6075.
#endif

#ifdef PLUVIO_H
  init_pluvio();          // Initialisation de l'interruption du capteur de pluviomètrie.
#endif

#ifdef VENT_H
  init_vent();            // Initialisation Girouette et anémomêtre.
#endif

}


//*********************************//
// ENVOI des infos à WeatherCloud  //
//*********************************//
void sendDataToWeatherCloud() {

  digitalWrite(LED_BUILTIN, LOW); // Turn the LED on

  float temp = getTemperature() - 2; // Attention correction température
  float hum = getHumidity();
  float bar = getPressure();

  float windSpeed = getWindSpeed();
  int windDirAngle = getWindDir();
  float windRafale = getWindRafale();

  float total_h = getPluieHeure();
  float total_j = getPluieJour();
  Serial.print("pluie heure debut WC:");
  Serial.println(total_h);
  Serial.print("pluie jour debut WC:");
  Serial.println(total_j);


  float heatIndex;
  int heat, dew;

  //-----------------------------------------------------------------------------------------------//
  //-------------- CALCUL DU POINT DE ROSEE -(formule de Heinrich Gustav Magnus-Tetens)------------//
  //-----------------------------------------------------------------------------------------------//

  double gamma = log(hum / 100) + ((17.62 * temp) / (243.5 + temp));
  double dewPoint = (243.5 * gamma / (17.62 - gamma));
  dew = int(dewPoint * 10);

  //-------------------------------------------------------------//
  //--------------- CALCUL DE L'INDEX DE CHALEUR ----------------//
  //-------------------------------------------------------------//

#define c1 -8.78469475556
#define c2 1.61139411
#define c3 2.33854883889
#define c4 -0.14611605
#define c5 -0.012308094
#define c6 -0.0164248277778
#define c7 0.002211732
#define c8 0.00072546
#define c9 -0.000003582

  heatIndex = c1 + (c2 * temp) + (c3 * hum) + (c4 * temp * hum) + (c5 * sq(temp)) + (c6 * sq(hum)) + (c7 * sq(temp) * hum) + (c8 * temp * sq(hum)) + (c9 * sq(temp) * sq(hum));
  heat = int(heatIndex * 10);

  if (temp < 27) heat = temp * 10;

  //----------------------------------------------------------------------//
  //-------------------- CALCUL DE LA TEMPERATURE RESSENTIE --------------//
  //----------------------------------------------------------------------//

  float kph, windChill;
  int wchill;
  kph = windSpeed;

  Serial.println("Wind speed measurement complete.\n");
  Serial.println(kph);


  //R = 13,12 + 0,6215 T + (0,3965 T - 11,37) V16 où T est température ambiante exprimée en °C et V est la vitesse du vent exprimée en km/h.
  windChill = (13.12 + (0.62 * temp) - (11.37 * (pow(kph, 0.16))) + (0.39 * temp * (pow(kph, 0.16))));
  wchill = int(windChill * 10);
  if (kph < 4.8) wchill = temp * 10;
  if (temp > 27) wchill = temp * 10;

  //*

  //-------------ENVOI SUR WEATHERCLOUD-----------------------------------//

  WiFiClient client;
  Serial.println("Initializing data push to Weathercloud.");

  if (!client.connect(server, 80)) {
    Serial.println("Connecting to Weatherloud failed.\n");
    return;
  }

  client.print("GET /v01/set");
  client.print("/wid/"); client.print(ID);
  client.print("/key/"); client.print(Key);

  client.print("/softwareid/"); client.print("d50a5c965d45");

  client.print("/temp/"); client.print(temp * 10);
  client.print("/hum/"); client.print(hum);
  client.print("/bar/"); client.print(bar * 10);

  client.print("/dew/"); client.print(dew);
  Serial.println(dew);
  client.print("/heat/"); client.print(heat);
  Serial.println(heat);

  int dBm2 = 0;
  dBm2 = abs(WiFi.RSSI() * 10);
  Serial.print("Valeur du RSSI en dB-2: ");
  client.print("/et/"); client.print(dBm2);
  client.print("/battery/"); client.print(dBm2 / 10);
  Serial.println(dBm2);

  //int rain = 0;
  //int rainrate = 0;
  client.print("/rain/"); client.print(total_j * 10); // quantité de pluie dans une journée
  client.print("/rainrate/"); client.print(total_h * 10); // quantité de pluie dans une heure
  Serial.print("Valeur de pluie heure envoyee a WC :");
  Serial.println(total_h * 10);
  Serial.print("Valeur de pluie jour envoyee a WC :");
  Serial.println(total_j * 10);

  client.print("/chill/"); client.print(wchill);
  Serial.println(wchill);

  client.print("/wspd/"); client.print(metersPerSecond(windSpeed) * 10);
  client.print("/wdir/"); client.print(windDirAngle);
  client.print("/wspdhi/"); client.print(metersPerSecond(windRafale) * 10);

  float uv = getIndexUv();
  Serial.print("Index UV envoyé à WC");
  Serial.println (uv);
  float solarrad = getRaySolar();
  Serial.print("Rayonnement envoyé à WC");
  Serial.println(solarrad);

  client.print("/uvi/"); client.print(uv * 10);        // index uv x10 [0,160] 8.0->80
  client.print("/solarrad/"); client.print(solarrad);  // watts/m2 x10 [0,20000] 1050.0->10500

  client.println("/ HTTP/1.1");
  client.println("Host: 188.164.196.110");
  client.println("Connection: close");
  client.println();
  Serial.println("Données envoyées vers Weathercloud avec succès.\n");

  digitalWrite(LED_BUILTIN, HIGH); // Turn the LED off
  
}
//---------------------------------------------------------------------//
//------------------ Envoi des données sur Wunderground ---------------//
//---------------------------------------------------------------------//

void sendDataToWunderground() {

  digitalWrite(LED_BUILTIN, LOW); // Turn the LED on

  float temp2 = getTemperature() - 2; // Attention correction température
  float hum2 = getHumidity();
  float bar2 = getPressure();

  float windSpeed2 = getWindSpeed();
  int windDirAngle2 = getWindDir();
  float windRafale2 = getWindRafale();

  float total_h2 = getPluieHeure();
  //float total_h2 = 10;
  float total_j2 = getPluieJour();
  //float total_j2 = 20;

  //-----------------------------------------------------------------------------------------------//
  //-------------- CALCUL DU POINT DE ROSEE -(formule de Heinrich Gustav Magnus-Tetens)------------//
  //-----------------------------------------------------------------------------------------------//
  int dew2;
  double gamma = log(hum2 / 100) + ((17.62 * temp2) / (243.5 + temp2));
  double dewPoint2 = (243.5 * gamma / (17.62 - gamma));
  dew2 = int(dewPoint2 * 10);


  Serial.print("Connecting to ");
  Serial.println(server2);
  WiFiClient client;
  if (client.connect(server2, 80)) {
    Serial.print("connected to ");
    Serial.println(client.remoteIP());
    delay(1000);
  } else {
    Serial.println("connection failed");
  }
  client.print(WEBPAGE);
  client.print("ID=");
  client.print(ID2);
  client.print("&PASSWORD=");
  client.print(Key2);
  client.print("&dateutc=now");
  //  client.print(CalDirection);

  client.print("&tempf=");
  //temp2 = 4;
  client.print((temp2 * 9 / 5) + 32);

  client.print("&dewptf=");
  //dew2 = 1;
  client.print(((dew2 / 10) * 9 / 5) + 32);

  client.print("&winddir=");
  //windDirAngle2 = 270;
  client.print(windDirAngle2);


  client.print("&windspeedmph=");
  //windSpeed2 = 10;
  client.print(windSpeed2 * 0.621371);

  client.print("&windgustmph=");
  //windRafale2 = 15;
  client.print(windRafale2 * 0.621371);

  float uv2 = getIndexUv();
  float solarrad2 = getRaySolar();

  client.print("&rainin=");
  client.print (total_h2 / 25.4);     // attention à mettre en pouces (inches) !
  client.print("&dailyrainin=");
  client.print (total_j2 / 25.4);      // attention à mettre en pouces (inches) !
  client.print("&UV=");
  client.print (uv2);
  client.print("&solarradiation=");
  client.print (solarrad2 / 10);


  client.print("&humidity=");
  //hum2 = 98;
  client.print(hum2);
  client.print("&baromin=");
  //bar2 = 1004;
  client.print(bar2 / 33.863);


  client.print("&softwaretype=Wemos_D1_Mini_V3_7_06112023&action=updateraw&realtime=1&rtfreq=30");
  client.print("/ HTTP/1.1\r\nHost: rtupdate.wunderground.com:80\r\nConnection: close\r\n\r\n");
  Serial.println(" ");
  delay(1000);

  digitalWrite(LED_BUILTIN, HIGH); // Turn the LED off
  
}


float metersPerSecond(float kilometersPerHour) {
  return round((kilometersPerHour * 1000 / 3600) * 10) / 10; // arrondi à 1 décimale
}
   

Je ne sais pas comment orienter mes recherches, merci de vos réponses par avance.
Bien cordialement
Philippe

passez la partie concernant l'exception (après le CUT HERE FOR EXCEPTION DECODER) dans GitHub - me-no-dev/EspExceptionDecoder: Exception Stack Trace Decoder for ESP8266 and ESP32

(évitez de poster des images d'un texte... SVP)

vous devriez faire cela qu'une seule fois et avoir une instance globale pour for RTC

@J-M-L merci pour votre réactivité, j'ai installé le decodeur d'exceptions comme indiqué, j'attends maintenant le premier redémarrage pour vous indiquer le résultat.

@J-M-L j'ai installé ce debugger mais lorsque je clique pour l'ouvrir depuis l'IDE arduino, j'obtiens ce message :+1:
gdbPath: C:\Users\pg886\AppData\Local\Arduino15\packages\esp32\tools\xtensa-esp-elf-gdb\11.2_20220823/bin/xtensa-lx106-elf-gdb.exe

ERROR: xtensa-lx106-elf-gdb.exe not found!
gdbPath: C:\Users\pg886\AppData\Local\Arduino15\packages\esp32\tools\xtensa-esp-elf-gdb\11.2_20220823/bin/xtensa-lx106-elf-gdb.exe

ERROR: xtensa-lx106-elf-gdb.exe not found !

une idée pour solutionner çà sinon voici ce que j'ai eu dans le serial monitor concernant l'exception 29 :
18:22:15.110 ->
18:22:15.110 -> ctx: sys
18:22:15.110 -> sp: 3ffffcb0 end: 3fffffb0 offset: 0150
18:22:15.143 -> 3ffffe00: 4026a207 3fff0380 00000002 4026a19c
18:22:15.143 -> 3ffffe10: 00000002 4026a143 00000002 40269298
18:22:15.143 -> 3ffffe20: 402692c1 3ffffed0 3fff0380 00000016
18:22:15.143 -> 3ffffe30: 40266d18 3ffffed0 3fff0228 3ffefc2c
18:22:15.143 -> 3ffffe40: 3ffed438 3ffffed0 3ffffed0 00000100
18:22:15.143 -> 3ffffe50: 6576694c 2d786f62 38413630 00000000
18:22:15.143 -> 3ffffe60: 00000001 00000080 3fffb54c 40245aad
18:22:15.176 -> 3ffffe70: 40263071 00000860 3ffe8d18 2ba2c721
18:22:15.176 -> 3ffffe80: ffffffc4 3ffefd3c 3ffed448 3fff0380
18:22:15.176 -> 3ffffe90: 3ffef2d0 00000024 00000000 40267a13
18:22:15.176 -> 3ffffea0: 00000000 3fff314c ffffffc4 00000000
18:22:15.176 -> 3ffffeb0: 00000000 3fff0380 1e310dfa 0000000f
18:22:15.176 -> 3ffffec0: 00000000 00000000 84e5e162 fffffffe
18:22:15.176 -> 3ffffed0: 00000000 11110b0b 00640104 0000004b
18:22:15.209 -> 3ffffee0: 3ffed45c 00000108 3ffed477 3ffed450
18:22:15.209 -> 3ffffef0: 3ffed47d 3ffed45c 3ffed46a 3ffed48f
18:22:15.209 -> 3fffff00: 00000000 00000000 3ffed495 3ffed54a
18:22:15.209 -> 3fffff10: 3ffed4bd 3ffed4d9 00000000 3ffed4fb
18:22:15.209 -> 3fffff20: 00000000 00000000 00000024 00000000
18:22:15.209 -> 3fffff30: 3fff3514 40267482 3ffef2d0 3fff314c
18:22:15.209 -> 3fffff40: 00000000 3fff0380 3ffef2d0 3ffed438
18:22:15.209 -> 3fffff50: 3ffed438 00000130 00000000 00000024
18:22:15.243 -> 3fffff60: 00000000 3ffed442 4027abb3 3ffef2d0
18:22:15.243 -> 3fffff70: 3ffed42c 3fffdcc0 3ffeb9d0 3ffeb9d0
18:22:15.243 -> 3fffff80: 00000080 3ffef2d0 3fffdab0 3fffdab0
18:22:15.243 -> 3fffff90: 4027a477 3fffdab0 00000000 4022edae
18:22:15.243 -> 3fffffa0: 3ffeb9d0 40000f49 ffffff00 40000f49
18:22:15.243 -> <<<stack<<<
18:22:15.243 -

vous pouvez peut être le décoder directement ? merci

Vous êtes sûr d’avoir bien installé l’outil?

@J-M-L

oui bien sur, je le trouve bien dans le menu outils de l'IDE, j'ai progressé depuis hier soir, en téléchargeant le fichier manquant et en le copiant dans le chemin indiqué indiqué dans la fenêtre de l'IDE.
Je n'ai plus ce message d'erreur mais cela m'ouvre une fenêtre me demandant de choisir un fichier elf :+1:
image

je ne sais pas ou chercher ce fichier elf ? une idée ?

voici ce que j'obtiens

Vous avez quelle version de l’IDE? Sur 1.8.x vous avez plus d’infos (en tout cas sur mon mac) avec les lignes de codes correspondantes

Ne postez pas de photo de texte - c’est illisible sur petit écran (je suis sur mon iPhone), ça mange de la bande passante, de la mémoire et on ne peut rien en faire - copiez et coller juste le texte dans des balises de code

version de l'IDE : 1.8.13.

Désolé pour les photos, je pensais que çà parlait plus qu'un long texte, mais sur téléphone portable effectivement je comprends.

vous n'avez rien sous "decoding stacks results" ?

le sketch est il ouvert, et compilé avant d'appeler (plus tard quand ça plante) l'analyseur ?

de mémoire l'outil retrouve le ELF tout seul et fait la correspondance avec le code

c'est ce que vous voyez dans le GitHub

Non je n'ai rien sous la ligne decoding stacks results.
Et non je n'ai pas le sketch ouvert et compilé avant d'appeler l'analyseur alors je vais refaire
et attendre la prochaine exception pour voir si cela change le résultat.

c'est sans doute pour cela qu'il ne trouvait pas le .elf tout seul

votre texte est tronqué


ça disait quoi exactement ?

tentative d'écriture à un endroit impossible?

dans le code il y a plusieurs endroits avec des pointeurs vers du texte constant (const char * ou en flash) ou transitoire (le pointeur a une portée limitée à la fonction)

  config.login.user_domain = F("127.0.0.1");
  message.timestamp.tag = "#esp_mail_current_time";
  message.timestamp.format = "%B %d, %Y %H:%M:%S";
  message.subject = F("Test sending plain text Email (#esp_mail_current_time)");
  message.text.content = "La Station Météo3 vient de re(démarrer) ! !\n\nEnvoyé le : #esp_mail_current_time";

je ne connais pas la bibliothèque que vous utilisez, est-ce comme cela qu'il faut le faire ? (notamment les F(""))

oui on va attendre le prochain redémarrage pour avoir un résultat d'analyse probant.
concernant l'envoi d'email j'utilise la bibliothèque ESP_MAIL_CLIENT et je me suis inspiré d'un sketch contenu dans les exemples de cette bibliothèque et je n'ai rien modifié donc je pense
que cela doit être comme çà, de plus l'envoi d'email n'est fait qu'au démarrage de la station
et n'est plus utilisé ensuite dans la loop.

OK - à suivre donc

Voici un premier message d'erreur mais pour une exception 2:

Exception 2: InstructionFetchError: Processor internal physical address or data error during instruction fetch
PC: 0x3fffef44
EXCVADDR: 0x3fffef44

Decoding stack results
0x4027de00: ethernet_input at glue-esp/lwip-esp.c line 354
0x401000ab: app_entry_redefinable() at C:\Users\pg886\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.2\cores\esp8266\core_esp8266_main.cpp line 386
0x40100284: ets_post(uint8, ETSSignal, ETSParam) at C:\Users\pg886\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.2\cores\esp8266\core_esp8266_main.cpp line 238
0x40241849: glue2esp_linkoutput at glue-esp/lwip-esp.c line 301
0x40100284: ets_post(uint8, ETSSignal, ETSParam) at C:\Users\pg886\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.2\cores\esp8266\core_esp8266_main.cpp line 238
0x40241ed6: ethernet_output at netif/ethernet.c line 312
0x40100284: ets_post(uint8, ETSSignal, ETSParam) at C:\Users\pg886\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.2\cores\esp8266\core_esp8266_main.cpp line 238
0x40100284: ets_post(uint8, ETSSignal, ETSParam) at C:\Users\pg886\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.2\cores\esp8266\core_esp8266_main.cpp line 238
0x40241849: glue2esp_linkoutput at glue-esp/lwip-esp.c line 301
0x40100284: ets_post(uint8, ETSSignal, ETSParam) at C:\Users\pg886\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.2\cores\esp8266\core_esp8266_main.cpp line 238
0x40241a77: new_linkoutput at glue-lwip/lwip-git.c line 272
0x40241ed6: ethernet_output at netif/ethernet.c line 312
0x40100c42: umm_free_core(umm_heap_context_t*, void*) at C:\Users\pg886\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.2\cores\esp8266\umm_malloc\umm_malloc.cpp line 642
0x4022d780: __esp_suspend() at C:\Users\pg886\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.2\cores\esp8266\core_esp8266_main.cpp line 127
0x402493f8: etharp_output_to_arp_index at core/ipv4/etharp.c line 769
0x402494cc: etharp_output_LWIP2 at core/ipv4/etharp.c line 885
0x40100fc4: malloc(size_t) at C:\Users\pg886\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.2\cores\esp8266\umm_malloc\umm_malloc.cpp line 912
0x4024ae38: ip4_output_if_opt_src at core/ipv4/ip4.c line 1764
0x40100284: ets_post(uint8, ETSSignal, ETSParam) at C:\Users\pg886\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.2\cores\esp8266\core_esp8266_main.cpp line 238
0x40241849: glue2esp_linkoutput at glue-esp/lwip-esp.c line 301
0x40241a77: new_linkoutput at glue-lwip/lwip-git.c line 272
0x40241ed6: ethernet_output at netif/ethernet.c line 312
0x40100284: ets_post(uint8, ETSSignal, ETSParam) at C:\Users\pg886\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.2\cores\esp8266\core_esp8266_main.cpp line 238
0x40100284: ets_post(uint8, ETSSignal, ETSParam) at C:\Users\pg886\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.2\cores\esp8266\core_esp8266_main.cpp line 238
0x4010064a: millis() at C:\Users\pg886\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.2\cores\esp8266\core_esp8266_wiring.cpp line 176
0x40100648: millis() at C:\Users\pg886\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.2\cores\esp8266\core_esp8266_wiring.cpp line 176
0x4022afc4: Print::printNumber (unsigned long, unsigned char) at C:\Users\pg886\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.2\cores\esp8266\Print.cpp line 262
0x4022f738: uart_write(uart_t*, char const*, size_t) at C:\Users\pg886\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.2\cores\esp8266\uart.cpp line 547
0x4022f738: uart_write(uart_t*, char const*, size_t) at C:\Users\pg886\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.2\cores\esp8266\uart.cpp line 547
0x4022a880: HardwareSerial::write(unsigned char const*, unsigned int) at C:\Users\pg886\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.2\cores\esp8266/HardwareSerial.h line 193
0x40209890: ESP8266WiFiSTAClass::status() at C:\Users\pg886\AppData\Local\Arduino15\packages\esp8266\hardware\esp8266\3.1.2\libraries\ESP8266WiFi\src\ESP8266WiFiSTA.cpp line 558

qu'en pensez vous ?

c'est toujours avec le code posté en #1 ?

Oui :+1:

quand vous compilez il dit qu'il reste combien de mémoire ?
comment est configuré l'organisation de la mémoire pour votre ESP? (quel type exactement ?)

et sinon que dit la console série avant le plantage ? (au niveau de toutes les traces ?)

où est la fonction setup_wifi()?

en fait il manque pas mal de chose au code

vous avez quoi dans tout cela ?

#include "connect.h"
#include "wifi.h"
#include "bme280.h"
#include "vent.h"
#include "pluvio.h"
#include "veml6075.h"

combien reste t il de mémoire après compilation :+1:

sai Variables and constants in RAM (global, static), used 40860 / 80192 bytes (50%)
║   SEGMENT  BYTES    DESCRIPTION
╠══ DATA     3348     initialized variables
╠══ RODATA   9824     constants       
╚══ BSS      27688    zeroed variables
. Instruction RAM (IRAM_ATTR, ICACHE_RAM_ATTR), used 62055 / 65536 bytes (94%)
║   SEGMENT  BYTES    DESCRIPTION
╠══ ICACHE   32768    reserved space for flash instruction cache
╚══ IRAM     29287    code in IRAM    
. Code in flash (default, ICACHE_FLASH_ATTR), used 623128 / 1048576 bytes (59%)
║   SEGMENT  BYTES    DESCRIPTION
╚══ IROM     623128   code in flash   
sissez ou collez du code ici