Crash serveur web lors de l'utilisation de MQTT

Bonjour,

J’utilise un arduino méga avec un shield ethernet.

Depuis plusieurs mois je l’utilise pour piloter ma serre avec une interface WEB gérer par mon arduino, et tout se passe très bien.

Récemment j’ai voulu ajouter le Protocol MQTT pour que ma domotique Home Assistant ai un asservissement dessus.

Voici mon problème :

L’envoi des topics de status fonctionne très bien par contre quand j’écoute les Topics (void onMqttMessage(int messageSize)), mon serveur web crash au bout d’environ 1H. L’écoute des TOPIC reste cependant fonctionnel.

Voici ce que j’utilise (5000 lignes de code donc je mets que ce qui concerne MQTT):

#include <ArduinoMqttClient.h>

// Ethernet Shield configuration
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
EthernetServer server(80);
EthernetClient client;

//configuration telnet
EthernetServer serverTelnet(23); // Serveur Telnet
EthernetClient clientTelnet;
bool telnetConnect = false;

/configuration MQTT
const char broker[] = "192.168.1.252";
int port = 1883;
const char username[] = "toto";
const char password[] = "titi »

const char topic1[]  = "Serre/Vanne1/set";
const char topic2[]  = "Serre/Vanne2/set";
const char topic3[]  = "Serre/Vanne3/set";
const char topic4[]  = "Serre/Vanne4/set";
const char topic5[]  = "Serre/Vanne5/set";
const char topic6[]  = "Serre/Vanne6/set";
const char topic7[]  = "Serre/Vanne_reservoir/set";
const char topic8[]  = "Serre/chauffage/set";

EthernetClient clientMQTT;
MqttClient mqttClient(clientMQTT);

void setup() {
mqttClient.setId("Serre");
mqttClient.setUsernamePassword(username, password);}

void loop() {
Status_Serre_MQTT();}

/****************************************************************************/
/*                  Status + pilotage MQTT                                  */
/****************************************************************************/
void Status_Serre_MQTT() {
  mqttClient.poll();
  if (millis() - lastExecutionMQTT >= 10000 && presence_reseau == 1) {  // Limiter l'envoi de MAJ à 10 secondes
    lastExecutionMQTT = millis(); // Mettre à jour le temps de la dernière exécution
    if (presence_reseau == 1) {
      // Contrôle toujours connecté au serveur MQTT
      if (!mqttClient.connected()) { // Si la connexion MQTT est perdue....
        Logs(F("Connection MQTT en cours..."));
        // Tentative de reconnexion avec nom d'utilisateur et mot de passe
        if (mqttClient.connect(broker, port)) {
          mqttClient.onMessage(onMqttMessage); //active le tread qui va écouter les messages et enclencher onMqttMessage(tread activé lors d'un mqttClient.poll())
          mqttClient.subscribe(topic1); // abonnement a tous les sous-topics
          mqttClient.subscribe(topic2); // abonnement a tous les sous-topics
          mqttClient.subscribe(topic3); // abonnement a tous les sous-topics
          mqttClient.subscribe(topic4); // abonnement a tous les sous-topics
          mqttClient.subscribe(topic5); // abonnement a tous les sous-topics
          mqttClient.subscribe(topic6); // abonnement a tous les sous-topics
          mqttClient.subscribe(topic7); // abonnement a tous les sous-topics
          mqttClient.subscribe(topic8); // abonnement a tous les sous-topics
          Logs(F("connected MQTT [OK]"));
          Logs(F("Attente des messages sur les topic: "));
          Logs(String(topic1));
          Logs(String(topic2));
          Logs(String(topic3));
          Logs(String(topic4));
          Logs(String(topic5));
          Logs(String(topic6));
          Logs(String(topic7));
          Logs(String(topic8));
        } else {
          Logs(F("!!!!!!!!!!!!!!!!!!!"));
          uint8_t error_code = mqttClient.connectError();
          String error_message = CodeErreurMQTT(error_code);
          Logs("Erreur connection MQTT, code erreur=0x" + String(error_code, HEX) + ", message erreur= " + error_message);
        }
      } else {  // Si on est connecté
        DernierDialogueMQTT = TempsFonctionnement;
        //********************************* Envoi status MQTT *********************************

        //maj MQTT temp si différente du dernier envoi
        if (temperature != lastTemperature || hydrometrie != lastHydrometrie) {
          lastTemperature = temperature;
          lastHydrometrie = hydrometrie;
          mqttClient.beginMessage(F("Serre/temperature"));
          mqttClient.print(String(temperature) + "," + String(hydrometrie));
          mqttClient.endMessage();
          Logs("Envoi statuts MQTT : Serre/temperature = " + String(temperature) + "," + String(hydrometrie));
        }

        //MAJ MQTT sondes si différentes du dernier envoi
        for (int i = 1; i <= NbrSondes; i++) {
          if (hydrometrie_Pourcent[i] != lastSondeHygrometrie[i]) {
            lastSondeHygrometrie[i] = hydrometrie_Pourcent[i];
            mqttClient.beginMessage("Serre/hygrometrie" + String(i));
            mqttClient.print(hydrometrie_Pourcent[i]);
            mqttClient.endMessage();
            Logs("Envoi statuts MQTT : Serre/hygrometrie = " + hydrometrie_Pourcent[i]);
          }
        }

        //MAJ MQTT relais si différents du dernier envoi
        for (int i = 1; i <= 8; i++) {
          if (EtatRelais[i] != lastEtatRelais[i]) { //control etat different avant MAJ
            lastEtatRelais[i] = EtatRelais[i];
            if ( i < 7) {
              mqttClient.beginMessage("Serre/Vanne" + String(i) + "/stat");
              mqttClient.print(EtatRelais[i]);
              mqttClient.endMessage();
              Logs("Envoi statuts MQTT: Serre/Vanne" + String(i) +  + "/stat = " + String(EtatRelais[i]));
            }
            else if (i == 7) {
              mqttClient.beginMessage(F("Serre/Vanne_reservoir/stat"));
              mqttClient.print(EtatRelais[i]);
              mqttClient.endMessage();
              Logs("Envoi statuts MQTT: Serre/Vanne_reservoir/stat = " + String(EtatRelais[i]));
            }
            else if (i == 8) {
              mqttClient.beginMessage(F("Serre/chauffage/stat"));
              mqttClient.print(EtatRelais[i]);
              mqttClient.endMessage();
              Logs("Envoi statuts MQTT: Serre/chauffage/stat = " + String(EtatRelais[i]));
            }
          }
        }

        //maj niveau cuve si différent du dernier envoi
        int niveauCuve = digitalRead(FondCuve);
        if (niveauCuve != lastEtatReservoir) {
          lastEtatReservoir = niveauCuve;
          mqttClient.beginMessage(F("Serre/Reservoir"));
          mqttClient.print(niveauCuve);
          mqttClient.endMessage();
          Logs("Envoi statuts MQTT : Serre/Reservoir = " + String(niveauCuve));
        }

        //maj MQTT lum si différente du dernier envoi
        for (int i = 0; i <= 1; i++) {
          if (Lum_value[i] != lastLum_value[i]) {
            lastLum_value[i] = Lum_value[i];
            mqttClient.beginMessage("Serre/luminosite" + String(i + 1));
            mqttClient.print(Lum_value[i]);
            mqttClient.endMessage();
            Logs("Envoi statuts MQTT : Serre/luminosite" + String(i + 1) + " = " + niveauCuve);
          }
        }
        //maj TempsFonctionnement (pas de log car appelé trop souvent)
        mqttClient.beginMessage(F("Serre/systeme/TempsFonctionnement"));
        mqttClient.print(uptime_formatter::getUptime());
        mqttClient.endMessage();
      }
    }
  }
}

/****************************************************************************/
/*             Gestion des topics MQTT de pilotage                          */
/****************************************************************************/
void onMqttMessage(int messageSize) {
  // we received a message, print out the topic and contents
  String topic = mqttClient.messageTopic();
  DernierDialogueMQTT = TempsFonctionnement;
  Logs("Message MQTT recu : " + topic);

  //lie la valeur du topic MQTT
  String ValeurTopic = "";
  for (int i = 0; i < messageSize; i++) {
    char c = (char) mqttClient.read();
    ValeurTopic += c;
  }

  // Comparaison du sujet MQTT avec topic1
  if (topic == topic1) {
    Serial.println(F("***Le sujet MQTT est égal à topic1***"));
  }
  else if (topic == topic2) {
    Serial.println(F("***Le sujet MQTT est égal à topic2***"));
  }
  else {
    Serial.println(F("***topic inconnu***"));
  }

  Serial.print(F("Valeur topic = ")); Serial.println(ValeurTopic);

merci d'avance pour votre aide

C'est à dire?
Du coup cela veut dire que ton programme dysfonctionne sur la partie que tu n'a pas montrée?
Tu semple indiquer que le problème intervient à cause de l'écoute d'un topic, cela veut dire que tu as essayé de désactivé cette partie?

J'ai finalement trouvé le problème. Même avec mqttClientpoll() , le serveur MQTT doit nous déconnecter au bout d'un certain temps. Ma fonction se reconnecte automatiquement et se réabonne aux topics. C'est là où est le problème, la re-souscription pose problème au bout d'un certain temps (saturation mémoire ????) J'ai déplacé la souscription dans le setup() et maintenant le programme est stable.
Merci pour ton aide

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.