Mqtt Dht22 et dhtnew

Bonjour

voila ma 1er application en domotique, un suivie des températures/humidités de l’habitat.

  • un Arduino Uno et shiel Ethernet pour la partie client (du filaire)
  • des capteurs DHT22
  • JeeDom en supervision, avec serveur Mqtt ( mosquitto ) sur une base matériel Odroid C2.

plus d’info jeedom et plugin-mqtt

le croquis Arduino (mon 1er) et un mixe, un copier/coller et modif pour X capteurs.

Ma demande (bah oui :slight_smile: )
Après plusieurs tentative pour l’adapter avec la dernière version de robtillaart.

la DHTNEW <dhtnew.h> https://forum.arduino.cc/index.php?topic=521494.0

voila le code fonctionnelle ’ avec encore un ou deux détail a revoir) mais avec la Lib d’adafruit .
( suis toute ouie pour des coups de sabre et greffe dans le croquis)

//  Arduino Mqtt et des capteurs DHT22 (temp/humidite )
// 
//  Exemple de reconnexion MQTT - non bloquant
//  une recopie-modif du wiki FHEM : https://wiki.fhem.de/wiki/MQTT_Einführung_Teil_3
//
//  base par: Rince du forum Fhem (adaptation 4 capteurs par JeeLet)
//  croquis : Arduino1_mqtt_dht22_eth_v01.ino
//  Biblio: PubSubClient.h (NickOLeary) et dht?? et pour dhtnew pas trouvé
//  date/version: 2020 / v01 (4 capteurs DHT22 en pseudo on-wire )
//
// Ce croquis montre comment garder le client connecté en utilisant
// une fonction de reconnexion non bloquante, Si le client perd sa connexion,
// il tente de se reconnecter toutes les 5 secondes sans bloquer la boucle principale.
//
// 
// -------------- debut ---------------

 #include <DHT.h>
 #include <SPI.h>
 #include <Ethernet.h>
 #include <PubSubClient.h>
 
 #define DHTPIN 6    
 #define DHTPIN1 7
 #define DHTPIN2 8  
 
 #define DHTTYPE DHT22 
 #define DHTTYPE1 DHT22 
 #define DHTTYPE2 DHT22 

 
 DHT dht (DHTPIN, DHTTYPE);
 DHT dht1 (DHTPIN1, DHTTYPE);
 DHT dht2 (DHTPIN2, DHTTYPE);

 byte mac[]    = { 0x90, 0xA2, 0xDA, 0x0D, 0x85, 0xFF }; // adresses mac
 IPAddress ip{ 192, 168, 1, 33};     //ip du client
 IPAddress server{ 192, 168, 1, 21}; //ip du serveur MQTT (le Broker)

        // ------------- mqtt ---------------//

   void callback(char* topic, byte* payload, unsigned int length)
   {
   // gérer le message est arrivé
   }

  EthernetClient ethClient;
  PubSubClient client(ethClient);

  long lastReconnectAttempt = 0;

  boolean reconnect()
 {
    if (client.connect("Arduino_1", "home/Arduino_1", 0, true, "offline")) 
    {
     // Once connected, publish an announcement...
     client.publish("home/Arduino_1","online", true);
     // ... and resubscribe
     client.subscribe("inTopic");
    }
   return client.connected();
 }


 // Réservez la zone de stockage pour sauver la clôture //
 
  // capteur0
  static char humidity[15]; 
  static char temperature[15];
  float h = 0.0;
  float h_alt = 0.0;
  float t = 0.0;
  float t_alt = 0.0;

  // capteur1
  static char char_h1[15]; 
  static char char_t1[15];
  float h1 = 0.0;
  float h1_alt = 0.0;
  float t1 = 0.0;
  float t1_alt = 0.0;

  // capteur2
  static char char_h2[15]; 
  static char char_t2[15];
  float h2 = 0.0;
  float h2_alt = 0.0;
  float t2 = 0.0;
  float t2_alt = 0.0;


// remise a zero du compteur "millisecondes"  depuis le dernier appel.
    unsigned long previousMillis = 0;  
        
// valeur intervalle de fréquence d'utilisation du capteur, en millisecondes (60000=1mn)
    const long interval = 12000; 



         //***************** Setup **********************//

 void setup() 
 {
   client.setServer(server, 1883);
   client.setCallback(callback);

   Ethernet.begin(mac, ip);
   delay(1500);
   lastReconnectAttempt = 0;
  
   Serial.begin(9600); 
   Serial.println("DHT22 - Test!");
 
   dht.begin();
   dht1.begin();
   dht2.begin();
  
 }

//***************** Loop ********************** 

 void loop() 
 {
   if (!client.connected())
   {
     long now = millis();
     if (now - lastReconnectAttempt > 5000) // calcul temps pour reconnection client
       {
        lastReconnectAttempt = now;
     
     // Tentative de reconnexion
       if (reconnect()) 
          {
          lastReconnectAttempt = 0;
          }
       }
   }

   else
     {
      client.loop(); // Client connected
     }

   unsigned long currentMillis = millis();

    if (currentMillis - previousMillis >= interval) // calcul temps ecouler du capteur
    {
      previousMillis = currentMillis;

     // ----- lecture des capteurs ------    
     
      h = dht.readHumidity();       //humidite 0
      t = dht.readTemperature();    //Temperature 0

      h1 = dht1.readHumidity();     //humidite 1
      t1 = dht1.readTemperature();  //Temperature 1

      h2 = dht2.readHumidity();     //humidite 2
      t2 = dht2.readTemperature();  //Temperature 2
     }
    
   // Vérifiez si un numéro valide est retourné.
   //  Si "NaN" "Not a Number" (pas un nombre) est renvoyé, affiche erreurs capteur. 

     if (isnan(t) || isnan(h) || isnan(t1) || isnan(h1) || isnan(t2) || isnan(h2) ) 
      {
       Serial.println(" un DHT22 n'a pas pu être lu");
       client.publish("home/Arduino_1","Erreur capteur",true); 
     
     // "true" envoie le message conservé, c'est-à-dire que le message reste sur le courtier 
     //jusqu'à ce que quelque chose de nouveau arrive.
      }
       else if (h == h_alt && t == t_alt && h1 == h1_alt && t1 == t1_alt && h2 == h2_alt && t2 == t2_alt  )
         {
          //ne fais rien
         }
       else
        {
         client.publish("home/Arduino_1","en Ligne", true);
    
         dtostrf(h,6, 1, humidity);
         dtostrf(t,6, 1, temperature);
      
         dtostrf(h1,6, 1, char_h1);
         dtostrf(t1,6, 1, char_t1);

         dtostrf(h2,6, 1, char_h2);
         dtostrf(t2,6, 1, char_t2);

    
         client.publish("home/Arduino_1/cuisine/humidite",humidity, true);
         client.publish("home/Arduino_1/cuisine/Temperature",temperature, true);

         client.publish("home/Arduino_1/bureau/humidite",char_h1, true);
         client.publish("home/Arduino_1/bureau/Temperature",char_t1, true);

         client.publish("home/Arduino_1/chambre/humidite",char_h2, true);
         client.publish("home/Arduino_1/chambre/Temperature",char_t2, true);
    
       h_alt = h;       // annuler l'ancienne lecture ..
       t_alt = t;       // ... pour ne réagir qu'aux changements

       h1_alt = h1;  
       t1_alt = t1; 

       h2_alt = h2;
       t2_alt = t2;
    
// ------------ Visu sur terminal ------------------ 

        Serial.print("humidite: "); 
        Serial.print(h);
        Serial.print(" %\t");
        Serial.print("Temperature: "); 
        Serial.print(t);
        Serial.println(" C");

      Serial.print("humidite 1: "); 
      Serial.print(h1);
      Serial.print(" %\t");
      Serial.print("Temperature 1: "); 
      Serial.print(t1);
      Serial.println(" C");

       Serial.print("humidite 2: "); 
       Serial.print(h2);
       Serial.print(" %\t");
       Serial.print("Temperature 2: "); 
      Serial.print(t2);
       Serial.println(" C");
    
    }
 }
//-------- Fin Pgm --------------

bonjour

Modification du croquis avec changement de librairie pour le capteur DHT22 c’est bon

Reste la gestion des messages de panne du capteur, temporisé l’avalanche des messages :slight_smile:

remarque et amélioration sont les bienvenues

//
//  Arduino avec Mqtt et des capteurs DHT22 (temp/humidite )
//
//  Exemple de reconnexion MQTT - non bloquant
//  une recopie-modif du wiki FHEM : https://wiki.fhem.de/wiki/MQTT_Einführung_Teil_3
//
//  base par: Rince du forum FHEM  / adapt. par JeeLet
//
//  les bibliothèques :  
//    
//  "Ethernet.h" pour le shield Ethernet, et  "SPI.h" pour la com entre le shield et arduino Uno
//
//  "PubSubClient.h" (Ver.:3.1 de NickOLeary) 
//  permet de créer un client MQTT pour publier et de souscrire à un topic.
//  
//  "dhtnew.h" (Ver:0.1.5 de Rob Tillaart)
//  une biblio commune a DHT11 et DHT22; ajout de l'offSet de décalage, notion d'objet pour les sondes,
//  indicateur d'activation/désactivation (voir *//github.com/RobTillaart/Arduino/tree/master/libraries/DHTNEW )
//
//  date/version du croquis: 20/02/20 - Ver01
//
//  Ce croquis montre comment garder le client connecté en utilisant
//  une fonction de reconnexion non bloquante, Si le client perd sa connexion,
//  il tente de se reconnecter toutes les 5 secondes sans bloquer la boucle principale.
//
//  modification :
//  x remplacer "isnan" par le control d'erreur de la nouvelle Lib.
//  - faire une tempo pour les messages de panne capteur ..
//  - voir la gestion pour 4 capteurs (ou plus) ...
//  - ...
//  - ...
//  
// --------------  ARDUINO n°1 "Uno" ---------------

  /*-----( Import libraries )-----*/

  #include <SPI.h>
  #include <Ethernet.h>
  #include <PubSubClient.h> // version de NickOLeary
  #include <dhtnew.h> // nouvelle version de Rob Tillaart's 
 
 /*--------------------( Declare objects et Pin )-------------------------*/
  DHTNEW dht1  (6);
 
 /*--------------------( Config parametre du LAN ethernet )-------------------------*/  
  byte mac[]    = { 0x90, 0xA2, 0xDA, 0x0D, 0x84, 0xFF }; // adresses mac
  IPAddress ip{ 192, 168, 1, 34};     //ip du client
  IPAddress server{ 192, 168, 1, 21}; //ip du serveur MQTT (le Broker)

        // ------------- mqtt ---------------//

   void callback(char* topic, byte* payload, unsigned int length)
   {
   // gérer le message est arrivé
   }

   EthernetClient ethClient;
   PubSubClient client(ethClient);

 //----- sous loop de reconnection au courtier mqtt ---------//

   long lastReconnectAttempt = 0;

   boolean reconnect()
  {
    if (client.connect("Arduino_1", "home/Arduino_1", 0, true, "offline")) 
    {      
      client.publish("home/Arduino_1","online", true); // ...
      client.subscribe("inTopic"); // ... and resubscribe
    }
    return client.connected();
  }

 //----- Réservez la zone de stockage pour sauver la clôture ---------//
 
  // capteur1
    static char capt_h1[15]; 
    static char capt_t1[15];
    float h1 = 0.0;
    float h1_alt = 0.0;
    float t1 = 0.0;
    float t1_alt = 0.0;
  
    unsigned long previousMillis = 0; //reset du compteur des millisecondes.
    
    const long interval = 3000; // <-----fréquence d'utilisation du capteur (60000millisecondes=1mn)
       
 void setup()   /******************* SETUP *************************/
 {
   client.setServer(server, 1883);
   client.setCallback(callback);

   Ethernet.begin(mac, ip);
   delay(1500);
   lastReconnectAttempt = 0;
  
   Serial.begin(9600);  // mise en service du terminal
   Serial.println("  DHT22 - Test!  ");
 }

 void loop()  /********************** LOOP ************************/
 {
   if (!client.connected())
      { long now = millis();
        if (now - lastReconnectAttempt > 500) // <------ tempo pour reconnection client
         {
          lastReconnectAttempt = now;
          if (reconnect())  // Tentative de reconnexion
           {
           lastReconnectAttempt = 0;
           }
         }
      }

   else
       {
       client.loop(); // Client connected
       }
       
 //----- interval de lecture du capteur DHT22 ---------//
       
        unsigned long currentMillis = millis();
     if (currentMillis - previousMillis >= interval) // calcul temps ecouler du capteur
       {
        previousMillis = currentMillis; 
      
       // dht1.read();            // lecture capteurs  
       h1 = dht1.humidity ;    //humidite 1
       t1 = dht1.temperature;  //Temperature 1
       }

 // ------ control du  capteur  ---------// 
    const int error = dht1.read(); 
  
     if (error == DHTLIB_ERROR_CHECKSUM)
       { 
        Serial.println("DHTLIB_ERROR_CHECKSUM");
        Serial.println(" erreur Checksum sur DHT22 ");
      return;
       }
     
     if (error == DHTLIB_ERROR_TIMEOUT) 
       {
        Serial.println("DHTLIB_ERROR_TIMEOUT");
        Serial.println(" erreur Timeout sur DHT22 ");
      return;
       }
        
     if (error == true ) //  erreurs capteur
       {
       client.publish("home/Arduino_1","Erreur capteur",true); 
        //"true" envoie le message conservé, c'est-à-dire que le message reste sur le courtier ...
        // ....jusqu'à ce que quelque chose de nouveau arrive.
      return;
       }
      
    else if (h1 == h1_alt && t1 == t1_alt ) // compar anci/nouv valeurs 
       {
         //ne fais rien
       }
    
    else
       {
        client.publish("home/Arduino_1","en Ligne", true);
    
        dtostrf(h1,6, 1, capt_h1); // conversions "float" pour PubSubClient...
        dtostrf(t1,6, 1, capt_t1); // ... 6 chiffres et 1 décimal
              
        client.publish("home/Arduino_1/cuisine/humidite",capt_h1, true);
        client.publish("home/Arduino_1/cuisine/Temperature",capt_h1, true);
        
        h1_alt = h1;       // annuler l'ancienne lecture ...
        t1_alt = t1;       // ... pour ne réagir qu'aux changements
    
 // ------------ Visu sur terminal ------------------ 

        Serial.print("humidite 1 : "); 
        Serial.print(h1);
        Serial.print(" %\t");
        Serial.print("Temperature 1 : "); 
        Serial.print(t1);
        Serial.println(" C");
    
       }
 }
 //        *********( Fin du Pgm )***********        //

Bonsoir

la suite de mon install, la partie afficheur LCD.

deux bouton poussoir pour défilement des pages pour lecture des sondes Dht22 transmit par mosquitto .

le croquis est un copier/coller/torturé vue sur instructables.com pour le principal.

bref je continue mon apprentissage.

/* 
* LCD_multiple_page_mqtt_v01.ino
*
* LCD 20x4 et MQTT avec bouton poussoir
* 2 BP haut bas pour afficher valeur des sondes
* et retour auto sur la page principal.
* sur Arduino Uno et carte Ethernet (oui du filaire)
*
* sur une base de :NJarpa et Padeath chez instructables.com 
* modif par : JeeLet / le 30-3-20 
*
*  modification :
*  x : modif bouton poussoir (activer PullUp sur entrée AI)
*  x : ajout partie Mqtt avec la Lib PubSubClient.h" (Ver.:3.1 de NickOLeary)
*  x : ajout Msg d'erreur Mqtt (ok ou hs )  
*  x : ajout partie non bloquant 
*  - :  
*  - : futur (bus CAN ?? )
*/
// -------------------- arduino uno ----- le 30-3-2020
  #include <SPI.h>
  #include <Ethernet.h>
  #include <PubSubClient.h>
  #include <LiquidCrystal.h>

  LiquidCrystal lcd(8, 9, 5, 7, 3, 2);

/*--------------------( Config parametre du LAN ethernet )-------------------------*/  
   byte mac[] = { 0x90, 0xA2, 0xDA, 0x0D, 0x84, 0xFF };
   IPAddress ip(192, 168, 1, 34);
   IPAddress server(192, 168, 1, 21);

   EthernetClient ethClient;  
   PubSubClient client(ethClient);
  

  int page_counter=1 ;       //page d'accueil 
  
  unsigned long previousMillis = 0;   // pour l'auto-retourne
  unsigned long interval = 20000;     // tempo de retour 10000

  int up = 14;        // Pin boutton Up               
  int down = 15;      // Pin boutton Down  
  
  boolean last_up = LOW;        // Créez et stockez les états...           
  boolean last_down = LOW;      // ...(derniers et actuels)...   
  boolean current_up = LOW;     // ...en tant que booléens. 
  boolean current_down = LOW;  

  long lastReconnectAttempt = 0; // partie non-bloquant

// -------- valeurs Mqtt ------------  
  String strPayload;
  String strTopic;

  String mq0; // etat de connection mqtt
  int errormq = 0; 
  
  String mq1;
  String mq2;
  
  String mq3;
  String mq4;
  
// -------------------- callback et mqtt ------------------------

  void callback(char* topic, byte* payload, unsigned int length)
  {
   payload[length] = '\0';
   strTopic = String((char*)topic);
   
//----------------- Local : bureau   
  if(strTopic == "home/Arduino_2/Temperature1")  
     {
      mq1 = String((char*)payload);
     }
  if(strTopic == "home/Arduino_2/humidite1")    
      {
      mq2 = String((char*)payload);   
      }
//----------------- Local : chambre     
  if(strTopic == "home/Arduino_2/Temperature2")     
      {
      mq3 = String((char*)payload);
      }  
  if(strTopic == "home/Arduino_2/humidite2")   
      {
      mq4 = String((char*)payload);
      }
/*----------------- Local : ???     
  if(strTopic == "home/Arduino_2/Temperature2")     
      {
      mq5 = String((char*)payload);
      }  
  if(strTopic == "home/Arduino_2/humidite2")   
      {
      mq6 = String((char*)payload);
      }
*/
  }

// ---------------------- Reconnect -----------------------
    boolean reconnect()
  {
   Serial.print("Tentative de connexion MQTT...");
    if (client.connect("Arduino_3")) // Attempt to connect
        {
         Serial.println("connecter");
         client.publish ("arduino4","afficheur LCD connecter"); //Une fois connecté,publie une annonce
        client.subscribe("home/Arduino_2/#");  // abonnement au Topic
        }
    return 
    client.connected(); 
  }
 
// -------------- Msg erreur mqtt ----------
void errormqtt()
  {
  const int errormq = client.state (); // Error abfangen und Sensor auslesen
   if (errormq == 0)
    { 
    mq0 = ("ok");
    return;
    }
   else
    { 
     mq0 = ("hs");
     }
    }
// ------------------- setup ------------------
void setup()
	{
    Serial.begin(9600);
  	lcd.begin(20,4); 

    Ethernet.begin(mac, ip);
    client.setServer(server, 1883);
    client.setCallback(callback);   //connection pour fonction de rappel callback
	
	  pinMode(up, INPUT_PULLUP);
	  pinMode(down, INPUT_PULLUP);

    lastReconnectAttempt = 0;  // partie non-bloquant
	}

  boolean debounce(boolean last, int pin) //--- anti-rebond pour tous les boutons 
	{
	boolean current = digitalRead(pin);
	if (last != current)
		{
		delay(5);
		current = digitalRead(pin);
		}
	return current;
	}

// --------------- Loop -----------------------
void loop()
 {
 errormqtt();   // info erreur mqtt
   if (!client.connected())
    {
    long now = millis();
    if (now - lastReconnectAttempt > 5000)
      {
      lastReconnectAttempt = now;
        if (reconnect()) // Tentative de reconnexion
        {
        lastReconnectAttempt = 0;
        }
      }
    }
    else
    {
    client.loop();
    }
    
	current_up = debounce(last_up, up);         // anti-rebond BP Up ...
	current_down = debounce(last_down, down);   //... et BP Down

//------------compteur pour mouvement des pages ----------

	if (last_up== LOW && current_up == HIGH)	//When up button is pressed
	  {  
	    if(page_counter <5)			  // compteur de Page total
		      {              
		      page_counter= page_counter +1;   
          lcd.clear();        //When page is changed, lcd clear to print new page 
	      	}
	    else
		      {
		      page_counter= 5;      // ----- nombre de page
		      }
	  }
	      last_up = current_up;		// ------ Up

      if (last_down== LOW && current_down == HIGH)	//When down button is pressed
  	    { 
	      if(page_counter >1)			//Page counter never lower than 1 (total of pages)
		      {              
		      page_counter= page_counter -1;   
          lcd.clear();                   //When page is changed, lcd clear to print new page
		      }
      else
          {
          page_counter= 1;  
	      	}
	      }
 
	    last_down = current_down;	// ------- Down	

      
// ---------- valeurs des pages -----------

  switch (page_counter) 
 {
  case 1:		// page 1
  {     
    lcd.setCursor(3,0);
    lcd.print("afficheur MQTT");
    lcd.setCursor(2,1);
    lcd.print("mesures ambiantes");
    lcd.setCursor(5,2);
    lcd.print("Page general");
    lcd.setCursor(3,3);
    lcd.print(":tempo");
    lcd.setCursor(12,3);
    lcd.print("mqtt:");
    lcd.print(mq0);
    
  }
  break;

  case 2:		// page 2 
	{ 
    lcd.setCursor(2,0);
    lcd.print("<-- sallon -->");
    lcd.setCursor(3,1);
    lcd.print("temp et hygro");
    lcd.setCursor(2,2);
    lcd.print(mq1); 
    lcd.print((char)223);
    lcd.print(mq2); 
    lcd.print("%");
  }
  break;

  case 3:		// page 3 
	{   
    lcd.setCursor(2,0);
    lcd.print("<-- chambre -->");
    lcd.setCursor(3,1);
    lcd.print("temp et hygro");
    lcd.setCursor(2,2);
    lcd.print(mq1); 
    lcd.print((char)223);
    lcd.print(mq2); 
    lcd.print("%");
  }
  break;
  
  case 4:    // page 4 
  {   
    lcd.setCursor(2,0);
    lcd.print("<-- bureau -->");
    lcd.setCursor(3,1);
    lcd.print("temp et hygro");
    lcd.setCursor(2,2);
    lcd.print(mq1); 
    lcd.print((char)223);
    lcd.print(mq2); 
    lcd.print("%");
  }
  break;

  case 5:    // page 5 
  {   
    lcd.setCursor(2,0);
    lcd.print("<-- biblio -- fino ");
    lcd.setCursor(3,1);
    lcd.print("temp et hygro");
    lcd.setCursor(2,2);
    lcd.print(mq1); 
    lcd.print((char)223);
    lcd.print(mq2); 
    lcd.print("%");
  }
  break;
 }        // ---------fin des switch ------------
    
//----------- Fonction Auto-return --------------

    unsigned long currentMillis = millis();
    lcd.setCursor(1,4);                               // Affiche valeur du compteur millis
    lcd.print((currentMillis-previousMillis)/1000);  // 1000
      
    if (currentMillis - previousMillis > interval)  //si interval ok, return page general
      {  
      previousMillis = currentMillis;
      lcd.clear();
      page_counter = 1;               // choix du N° de la page "General"
      }  
    if (digitalRead(14) == LOW || digitalRead(15) == LOW) //reset compteur millis si BP activer
      {  
      previousMillis = currentMillis;
      }
    
  } 
  // --------------- fin du Pgm --------------------