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