Problème avec mqtt

Bonjour à tous,
Je débute dans la programmation esp32 et mes projets dépassent mes compétences.
Je souhaite mesurer le taux d'humidité de la terre (shol) et le transmettre par wifi afin de le recevoir dans mqtt broker et bien sur j'ai un problème et je n'arrive pas à trouver de réponse.
J'arrive à avoir ce taux sur le moniteur série (Serial.println(hsol):wink:
j'arrive aussi à créer un topic et message dans mqtt (client.publish(topic, "salut"):wink:
mais je n'arrive pas à publier le taux d'humidité par (client.publish(topic ,shol):wink:
J'ai la réponse exit status 1
Compilation error: no matching function for call to 'PubSubClient::publish(const char*&, float&)'
merci pour votre aide.

la publication mqtt attend un message textuel et là vous passez une variable de type float ➜ il faut convertir le nombre en texte dans un buffer avant de l'envoyer

float hsol = 123.456; // votre variable float

// Taille du buffer pour contenir la chaîne convertie
char buffer[30]; // 30 caractères, il faut qu'il soit assez grand pour stocker le texte et un caractère nul à la fin

// Utilisation de la fonction dtostrf pour convertir le float en chaîne dans le buffer
dtostrf(hsol, 6, 3, buffer); // 6 chiffres minimum au total (dont 3 après la virgule)

// envoi de la chaîne résultante
client.publish(topic, buffer);

sur ESP32 vous pouvez aussi utiliser snprintf() pour fabriquer le message

float hsol = 123.456; // votre variable float

// Taille du buffer pour contenir la chaîne convertie
char buffer[30]; // 30 caractères, il faut qu'il soit assez grand pour stocker le texte et un caractère nul à la fin

// Utilisation de la fonction dtostrf pour convertir le float en chaîne dans le buffer
snprintf(buffer, sizeof buffer, "hsol=%.4f", hsol); // on fabrique le texte "hsol=123.4560" (le .4 veut dire 4 chiffres après la virgule)
// envoi de la chaîne résultante
client.publish(topic, buffer);

merci beaucoup pour votre aide. c'est sympa de prendre du temps pour les débutants.

ça fonctionne maintenant ?

bons bricolages !

je n'ai pas le temps de tester maintenant

C'est bon tout fonctionne.
maintenant comment faire avec plusieurs variables? plusieurs buffers style buffer1 buffer2?
merci encore

peux tu détailler?
plusieurs variable comme hsol ?
que veux tu faire avec buffer1 et et buffer2?

si tu as plusieurs publication, il faut simplement répéter l'opération snprintf et publish

Si vous voulez envoyer un message qui comporte plusieurs variables, utiliser snprintf () comme dans le deuxième exemple, mettez juste dans le format des éléments que vous souhaitez.

Je vous laisse lire la doc de printf, le lien était dans mon message précédent

problème je me suis réjoui trop vite. Peur être faut il vider le buffer.
Le capteur renvoie des valeurs à interval régulier et passé un certain délai l'ESP32 se bloque plus de message dans mqtt.
Pour un débutant un problème en chasse un autre.

Le problème est sans doute dans le code que vous n’avez pas posté…

bonjour,

Voilà ce code qui n'émet plus sur mqtt après un certain temps

//****************************************************
// Mesure analogique et digitale de l'humidité du sol
// Avec le module Humidité Sol
//  TipTopboards.com
//  23 12 2013  demo_hsol
//****************************************************
// Brancher +V -> 3,3 V et GND
// Sortie analogique du capteur -> A0 Arduino
// Sortie digitale du capteur -> pin 3 Arduino (avec seuil)

//On rajoute une LEd témoin sur pin 4


 #include "WiFi.h"
#include "PubSubClient.h"
#include  "Wire.h"

int PinAnalogiqueHumidite=A0;       //Broche Analogique de mesure d'humidité
int PinNumeriqueHumidite=18;        //Broche Numérique mesure de l'humidité
int PinLed=3;    //LED témoin de seuilde  sécheresse


float hsol;  //Humidite su sol, mesure analogique
int secheresse;  //0 ou 1 si seuil atteint

// Taille du buffer pour contenir la chaîne convertie
char buffer[30]; // 30 caractères, il faut qu'il soit assez grand pour stocker le texte et un caractère nul à la fin


  // WiFi 
const char *ssid = "**********"; // Entrez votre SSID WiFi  
const char *password = "*********"; // Entrez votre mot de passe WiFi 
  
// MQTT Broker 
const char *mqtt_broker = "192.*******"; 
const char *topic = "Humidité"; 
const char *mqtt_username = "*****"; 
const char *mqtt_password = "******"; 
const int mqtt_port = 1883; 
WiFiClient espClient; 
PubSubClient client(espClient); 

//-----------------------------------------------------------------

void setup() { 
 //Mise de la vitesse de transmission à 115200; 
 Serial.begin(115200); 

 // Connecting to a Wi-Fi network 
 WiFi.begin(ssid, password); 
 while (WiFi.status() != WL_CONNECTED) { 
 delay(500); 
 Serial.println("Connecting to WiFi.."); 
  } Serial.println("Connected to the Wi-Fi network"); 

   
    pinMode(PinAnalogiqueHumidite, INPUT);       //pin A0 en entrée analogique
    pinMode(PinNumeriqueHumidite, INPUT);  //pin 3 en entrée numérique
    pinMode(PinLed, OUTPUT);   //LED témoin

  //connexion au broker MQTT  
 client.setServer(mqtt_broker, mqtt_port); 
 client.setCallback(callback); 
 while (!client.connected()) { 
 String client_id = "esp32-client-"; 
 client_id += String(WiFi.macAddress()); 
 Serial.printf("The client %s connects to the public MQTT brokern", client_id.c_str()); 
 if (client.connect(client_id.c_str(), mqtt_username, mqtt_password)) { 
  Serial.println("Public EMQX MQTT broker connected"); 
  } else { 
  Serial.print("failed with state "); 
  Serial.print(client.state()); 
  delay(2000); 
  } 
  } 
  // Publish et subscribe 
  client.publish(topic, "Hi, I'm ESP32"); 
  client.subscribe(topic);
  } 
  // Reception du message MQTT 
void callback(char *topic, byte *payload, unsigned int length) { 
Serial.print("Message arrived in topic: "); 
Serial.println(topic); 
  Serial.print("Message:"); 
  for (int i = 0; i < length; i++) { 
Serial.print((char) payload[i]); 
  } 
  Serial.println(); 
  Serial.println("-----------------------"); 
}
  //------------------------------------------------------------------------------------

void loop() { //boucle principale

  client.loop(); 


    hsol = analogRead(PinAnalogiqueHumidite); // Lit la tension analogique
    secheresse = digitalRead(PinNumeriqueHumidite);
    Serial.println(hsol); // afficher la mesure
    Serial.print("  ");
    Serial.println(secheresse);  //0 ou 1 si le seuil est dépassé
    if (secheresse==1)
      {
        digitalWrite(PinLed, HIGH);   // LED allumée
      }
      else {
      digitalWrite(PinLed, LOW);   // LED off
       }

client.publish(topic, "salut");


// Utilisation de la fonction dtostrf pour convertir le float en chaîne dans le buffer
snprintf(buffer, sizeof buffer, "hsol=%.1f", hsol); // on fabrique le texte "hsol=123.4560" (le .0 veut dire 0 chiffres après la virgule)
// envoi de la chaîne résultante
client.publish(topic, buffer);
delay(10000);
  } 



merci pour votre aide

Bonjour,
Peut être faut il relancer l"esp32 régulièrement pour éviter le blocage de celui-ci

Bonjour @cdrhum

'blocage' .....'plus d'émission au bout d'un certain temps'...

Peut être une perte de connection avec le broker , favorisée par le delay(10000) =solution bloquante pour espacer les publications.

utiliser 'millis' pour espacer les publications tout en rendant la main le plus vite possible à client.loop()

IL est aussi utile de tester la connection au broker avant de publier et re-connecter si nécessaire

bonjour,

Merci encore pour votre aide. Mais malheureusement la méthode du millis ne fonctionne pas. C'est mieux d'avec le delay car l'ESP32 tourne 3 fois plus longtemps mais il bloque alors sur le broker alors que les valeurs arrivent toujours sur le moniteur série. Si je relance l'esp32 il se connecte bien alors au broker de nouveau.

c'est à dire tu as un autre problème avec millis ou le même.
Si le delay est la cause de ton problème, peut on vraiment dire que c'est mieux ?

alors avec la fonction delay le broker ne reçoit plus les messages de l'ESP32 après 20 minutes de fonctionnement.
Avec la fonction millis le broker ne reçoit plus les messages de l'ESP32 après 1heure de fonctionnement. c'est mieux.

effectivement, augmente alors ton delay, peut être qu'a un moment ESP fonctionnera en continue :slight_smile:

Disons que c'est moins pire, mais il serait quand même mieux de trouver ce que tu fais de mal, pour avoir ce problème.

Bonjour,
Je pense que j'ai un problème de parenthèses dans mon programme. Sur le moniteur série des commandes qui dépendent de void setup sont affichées sans cesse comme faisant partie du void loop.
Je ne sais pas où est le problème. Pouvez vous m'aider. Merci par avance.

Pour commencer, il faudrait que tu indente ton code, tel quel que tu l'a présenté, c'est illisible.
La plus pars des IDE comme Arduino 2.x et Visual code, te permet lorsque tu te positionne sur une parenthèse ouvrante de voir, la parenthèse fermante.

En reformatant ton code, je ne vois rien qui peut indiqué un problème entre setup et loop.
Qu'es ce qui te faire dire ça ?

ou alors ça veut dire que l'arduino reboote sans cesse