[Domotique] : Sonde thermique avec un BME680 et ESP32

17 novembre 2023 rdorigny 0 commentaires

Dans un article précédent, j'avais réalisé une sonde la température avec le BMP280. Et bien, il a évolué depuis un moment vers le BME680. Il s'agit d'un capteur I2C produit par Bosch permettant la mesure de la température, de l'humidité, de la pression atmosphérique et de la qualité de l'air.

Nous allons voir comment l'utiliser avec un exemple de réalisation d'une sonde Do It Yourself qui pourra peut-être vous inspirer.




1) Schéma et code

J'apprécie les capteurs de mesure PTH (pression, température et humidité) de la marque BOSCH car ils sont peu couteux, fiables et facilement accessibles. En effet, on les trouve sans difficultés sur Internet, vendu généralement sur des mini plaquettes et déjà prés à l'usage.

Le BME680 est un capteur numérique 4-en-1 avec mesure de gaz, d'humidité, de pression et de température basée sur des principes de détection éprouvés. Le module capteur est logé dans un boîtier LGA à couvercle métallique extrêmement compact avec un encombrement de seulement 3,0 × 3,0 mm² et une hauteur maximale de 1,00 mm (0,93 ± 0,07 mm). Ses petites dimensions et sa faible consommation d'énergie permettent l'intégration dans des appareils alimentés par batterie ou à couplage de fréquence, tels que des combinés ou des appareils portables.

Caractéristiques principales :
  • Capteurs de gaz, de pression, de température et d'humidité hautes performances;
  • Très faible consommation d'énergie : 3,6 µA à 1 Hz d'humidité, de pression et de température et 0,1 à 16 mA pour p/h/T/gaz selon le mode de fonctionnement;
  • Dimension : 3,0 x 3,0 mm², hauteur 1,0 mm;
  • Plage d'alimentation : 1,71 V … 3,6 V;
  • Interface numérique flexible pour se connecter à l'hôte via I2C ou SPI.

  • Pour plus d'informations, vous trouverez le datasheet du BME680 ici.

    J'ai choisis le microcontrôleur ESP32 D1 mini pour piloter la puce par l'intermédiaire du protocole I2C, moins couteux en connexions que le SPI.



    Pour le schéma, rien de plus simple, il suffit d'alimenter la mini plaquette avec la sortie 3.3V de l'ESP32; et d'interconnecter les deux ports I2C entre l'ESP32 (généralement SCA est en PIN 21 et SCL est en PIN 22) et la plaquette BME680. Cliquez sur le schéma pour agrandir.
    #include (Wire.h)  //remplacer les () par <>
    #include (Adafruit_Sensor.h) //remplacer les () par <>
    #include "Adafruit_BME680.h"
    
    #define SEALEVELPRESSURE_HPA (1013.25)
    
    Adafruit_BME680 bme; // I2C
    
    void setup() {
      Serial.begin(9600);
      while (!Serial);
      Serial.println(F("BME680 test"));
    
      if (!bme.begin()) {
        Serial.println("Could not find a valid BME680 sensor, check wiring!");
        while (1);
      }
    
      // Set up oversampling and filter initialization
      bme.setTemperatureOversampling(BME680_OS_8X);
      bme.setHumidityOversampling(BME680_OS_2X);
      bme.setPressureOversampling(BME680_OS_4X);
      bme.setIIRFilterSize(BME680_FILTER_SIZE_3);
      bme.setGasHeater(320, 150); // 320*C for 150 ms
    }
    
    void loop() {
      if (! bme.performReading()) {
        Serial.println("Failed to perform reading :(");
        return;
      }
      Serial.print("Temperature = ");
      Serial.print(bme.temperature);
      Serial.println(" *C");
    
      Serial.print("Pressure = ");
      Serial.print(bme.pressure / 100.0);
      Serial.println(" hPa");
    
      Serial.print("Humidity = ");
      Serial.print(bme.humidity);
      Serial.println(" %");
    
      Serial.print("Gas = ");
      Serial.print(bme.gas_resistance / 1000.0);
      Serial.println(" KOhms");
    
      Serial.print("Approx. Altitude = ");
      Serial.print(bme.readAltitude(SEALEVELPRESSURE_HPA));
      Serial.println(" m");
    
      Serial.println();
      delay(2000);
    }
    

    Concernant le code, j'utilise la bibliothèque proposée par Adafruit, dont l'exemple de mise en œuvre est ci-dessus. En résumé, il connecte le BME680 à l'ESP32, réalise une mesure et affiche les données toutes les 2 secondes.



    2) Réalisation de la sonde

    Comme je l'ai déjà présenté, le principe de mes sondes domotique consiste à les connecter sur Internet afin de transmettre les informations mesurées sur un hébergement cloud via une API. Pour plus d'informations, regardez mon système de centrale domotique. Cela évite d'avoir un serveur à la maison ou un NAS, qui sont souvent gourmand en énergie. Pour le cloud, il existe des abonnements chez des hébergeurs (IONOS pour moi) qui sont à quelques euros par mois.

    J'utilise la connectivité WIFI de l'ESP32 pour le connecter à la box WIFI de la maison. J'ai prévu d'avoir 4 sondes d'où l'intérêt de faire des cartes PCB maison. Pour cela, le logiciel gratuit KICAD est particulièrement adapté.



    Pour connaitre l'état de connexion de la sonde au WIFI, j'ai prévu une diode RGB (vert OK, rouge NOK). Ensuite, je transfère les fichiers gerbers sur le site d'un fabricant de cartes de circuits imprimés (JLCPCB, pas trop couteux et fabrication super propre).


    Pour le boitier imprimé en 3D, rien de tel que Fusion 360!



    Enfin, le code de la sonde qui transmet les data via api dans une base de données chez un hébergeur cloud. La centrale domotique récupère ces informations pour les afficher.

    #include (Wire.h) //remplacer les () par <>
    #include (Adafruit_Sensor.h) //remplacer les () par <>
    #include "Adafruit_BME680.h"
    #include (WiFi.h) //remplacer les () par <>
    #include "esp_system.h"
    #include (HTTPClient.h) //remplacer les () par <>
    
    //#define SEALEVELPRESSURE_HPA (1013.25)
    #define SEALEVELPRESSURE_HPA (1027)
    
    
    const char* ssid = "votre_ssid";
    const char* password =  "le_password";
    int cpt=0;
    
    const int led1 =  26;      // the number of the LED pin
    const int led2 =  18;      // the number of the LED pin
    const int led3 =  19;
    
    Adafruit_BME680 bme; 
    
    void setup() {
      Serial.begin(115200);
      while (!Serial);
      Serial.println(F("BME680 async test"));
    
      // initialize the LEDs pins as an output:
      pinMode(led1, OUTPUT);
      pinMode(led2, OUTPUT);  
      pinMode(led3, OUTPUT); 
        
      //Affichage WIFI KO
      digitalWrite(led3, HIGH); 
      
     //Connexion au wifi
      WiFi.begin(ssid, password); 
      while (WiFi.status() != WL_CONNECTED) { //Check la connexion
        delay(1000);
        Serial.println("Tentative de connexion au WiFi...");
        cpt++;
        if (cpt>30)
          {
          Serial.println("Pas de connexion au wifi! Reboot automatique...");
          esp_restart();
          }
      }
      Serial.println("Connexion au réseau local wifi");
      
      //Affichage WIFI OK
      digitalWrite(led3, LOW); 
      digitalWrite(led1, HIGH); 
      
      if (!bme.begin()) {
        Serial.println(F("Could not find a valid BME680 sensor, check wiring!"));
        while (1);
      }
    
      // Set up oversampling and filter initialization
      bme.setTemperatureOversampling(BME680_OS_8X);
      bme.setHumidityOversampling(BME680_OS_2X);
      bme.setPressureOversampling(BME680_OS_4X);
      bme.setIIRFilterSize(BME680_FILTER_SIZE_3);
      bme.setGasHeater(320, 150); // 320*C for 150 ms
    }
    
    void loop() { 
      // Tell BME680 to begin measurement.
      unsigned long endTime = bme.beginReading();
      if (endTime == 0) {
        Serial.println(F("Failed to begin reading :("));
        return;
      }
      Serial.print(F("Reading started at "));
      Serial.print(millis());
      Serial.print(F(" and will finish at "));
      Serial.println(endTime);
    
      Serial.println(F("You can do other work during BME680 measurement."));
      delay(50); 
      
      if (!bme.endReading()) {
        Serial.println(F("Failed to complete reading :("));
        return;
      }
      else
        { 
        /*Serial.print(F("Reading completed at "));Serial.println(millis());
        Serial.print(F("Temperature = "));Serial.print(bme.temperature);Serial.println(F(" *C"));
        Serial.print(F("Pressure = "));Serial.print(bme.pressure / 100.0);Serial.println(F(" hPa"));
        Serial.print(F("Humidity = "));Serial.print(bme.humidity);
        Serial.println(F(" %"));
        Serial.print(F("Gas = "));Serial.print(bme.gas_resistance / 1000.0);
        Serial.println(F(" KOhms"));
        Serial.print(F("Approx. Altitude = "));Serial.print(bme.readAltitude(SEALEVELPRESSURE_HPA));
        Serial.println(F(" m"));
        Serial.println();
        delay(2000);*/
    
       if(WiFi.status()== WL_CONNECTED){   //Check WiFi connection status
         //Emission de la requete vers l'API
         HTTPClient http;   
         float pr=bme.pressure;
         pr=pr/100;
         float gas=bme.gas_resistance;
         gas=gas/1000;     
         String str;
         str="http://www.votresite.fr/votre_api.php?tp="+String(bme.temperature)+"&humidite="
         +String(bme.humidity)+"&legas="+String(gas)+"&pression="+String(pr)+"&numdomo=bureau";   
         Serial.println(str);             
         http.begin(str); 
         http.addHeader("Content-Type", "text/plain");            
         int httpResponseCode = http.POST("POSTING from ESP32");   
         if(httpResponseCode>0){
          String response = http.getString();                      
          Serial.println(httpResponseCode);   
          Serial.println(response);           
         }else{ 
          Serial.print("Error on sending POST: ");
          Serial.println(httpResponseCode); 
         }
         http.end();  //Free resources
       }else{
          Serial.println("Perte de la connexion WIFI. Reboot automatique."); 
          esp_restart();
       }
      }
    delay(900000);  //Emission toutes les 15 minutes
    //delay(60000); //Si besoin de tests  
    }
    

    Conclusion

    Voila pour le BME680, il est super simple d'utilisation, rien de difficile! Je n'ai pas exploité la fonctionnalité de mesure de qualité de l'air car pas vraiment vu son intérêt. Les sondes fonctionnent depuis un bon moment sans souci et semblent fiables.

    Evidemment, vous me direz, il suffit d'acheter une centrale domotique avec des sondes pour ce faire, mais j'ai eu beaucoup de plaisir à la réaliser. :-) Et au moins, si elle tombe en panne, je saurais la réparer...







    Pseudonyme (obligatoire) :
    Adresse mail (obligatoire) :
    Site web :




    © 2024 www.doritique.fr par Robert DORIGNY