Serveur Web du thermostat ESP32/ESP8266 – Sortie de contrôle basée sur la température

Serveur Web du thermostat ESP32/ESP8266 - Sortie de contrôle basée sur la température

Dans ce projet, vous allez créer un serveur Web de thermostat ESP32 / ESP8266 avec un champ de saisie pour définir une valeur de seuil de température. Cela vous permet de contrôler automatiquement une sortie en fonction de la lecture de température actuelle. La sortie sera activée si la température est supérieure ou désactivée si elle est inférieure au seuil – cela peut être utilisé pour créer un projet de thermostat simple.

La sortie de contrôle ESP32 ou ESP8266 basée sur le seuil de température crée un serveur Web de thermostat

A titre d’exemple, nous allons lire la température à l’aide d’un capteur de température DS18B20. Vous pouvez utiliser n’importe quel autre capteur de température comme DHT11/DHT22, BME280 ou LM35.

Pour mieux comprendre le fonctionnement de ce projet, nous vous recommandons de lire ces tutoriels :

Aperçu du projet

L’image suivante montre un aperçu de haut niveau du projet que nous allons construire.

Présentation du projet de serveur Web ESP32 ESP8266 avec valeur de seuil de température
  • L’ESP32/ESP8266 héberge un serveur Web qui affiche les dernières lectures de température d’un capteur de température DS18B20.
  • Il y a un champ de saisie pour configurer une valeur de seuil de température. Lorsque la température dépasse le seuil, une sortie sera automatiquement activée. Vous pouvez inverser cette logique en fonction de votre application de projet.
  • Lorsque la température descend en dessous du seuil, la sortie sera désactivée.
  • Le système peut être activé ou désactivé via le serveur Web. Si vous choisissez de désactiver le système, la sortie conservera son état, quelle que soit la valeur de la température.

L’image suivante montre à quoi ressemble la page du serveur Web.

Serveur Web de température ESP32/ESP8266 avec seuil pour le contrôle automatique de la sortie

Conditions préalables

Assurez-vous de vérifier chacune des conditions préalables suivantes avant de poursuivre ce projet.

1. IDE Arduino complémentaire ESP32 ou ESP8266

Ce projet est compatible avec les cartes ESP32 et ESP8266. Nous programmerons ces cartes à l’aide de l’IDE Arduino, alors assurez-vous d’avoir installé les modules complémentaires nécessaires :

2. Bibliothèques de serveurs Web asynchrones

Pour créer le serveur Web asynchrone, vous devez installer ces bibliothèques.

Ces bibliothèques ne peuvent pas être installées via le gestionnaire de bibliothèque Arduino, vous devez donc copier les fichiers de bibliothèque dans le dossier Bibliothèques d’installation Arduino. Alternativement, dans votre IDE Arduino, vous pouvez accéder à Esquisser > Inclure la bibliothèque > Ajouter une bibliothèque .zip et sélectionnez les bibliothèques que vous venez de télécharger.

3. Pièces requises

Cartes de développement ESP32 vs ESP8266

Pour suivre ce tutoriel vous avez besoin des pièces suivantes :

Vous pouvez utiliser les liens précédents ou accéder directement à MakerAdvisor.com/tools pour trouver toutes les pièces pour vos projets au meilleur prix !

1644576490 644 Serveur Web du thermostat ESP32ESP8266 Sortie de controle basee

Diagramme schématique

Avant de continuer, câblez le capteur de température DS18B20 à votre carte.

ESP32 avec DS18B20 et LED

Si vous utilisez un ESP32, câblez le capteur de température DS18B20 comme indiqué dans le schéma suivant, avec la broche de données connectée à GPIO 4.

Schéma de câblage avec capteur de température DS18B20 connecté à la carte ESP32

ESP8266 avec DS18B20 et LED

Si vous utilisez un ESP8266, câblez le capteur de température DS18B20 comme indiqué dans le schéma suivant, avec la broche de données connectée à GPIO 4 (D2).

Schéma de câblage avec capteur de température DS18B20 connecté à la carte ESP8266 (NodeMCU)

Code – Serveur Web du thermostat avec entrée de seuil

Copiez le code suivant dans votre IDE Arduino, mais ne le téléchargez pas encore. Vous devez apporter quelques modifications pour que cela fonctionne pour vous. Vous devez insérer vos informations d’identification réseau et votre valeur de seuil par défaut.

/*********
  Rui Santos
  Complete project details at https://Raspberryme.com/esp32-esp8266-thermostat-web-server/
  
  Permission is hereby granted, free of charge, to any person obtaining a copy
  of this software and associated documentation files.
  
  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.
*********/

#ifdef ESP32
  #include <WiFi.h>
  #include <AsyncTCP.h>
#else
  #include <ESP8266WiFi.h>
  #include <ESPAsyncTCP.h>
#endif
#include <ESPAsyncWebServer.h>
#include <Wire.h>
#include <OneWire.h>
#include <DallasTemperature.h>

// REPLACE WITH YOUR NETWORK CREDENTIALS
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

// Default Threshold Temperature Value
String inputMessage = "25.0";
String lastTemperature;
String enableArmChecked = "checked";
String inputMessage2 = "true";

// HTML web page to handle 2 input fields (threshold_input, enable_arm_input)
const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html><head>
  <title>Temperature Threshold Output Control</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  </head><body>
  <h2>DS18B20 Temperature</h2> 
  <h3>%TEMPERATURE% &deg;C</h3>
  <h2>ESP Arm Trigger</h2>
  <form action="/get">
    Temperature Threshold <input type="number" step="0.1" name="threshold_input" value="%THRESHOLD%" required><br>
    Arm Trigger <input type="checkbox" name="enable_arm_input" value="true" %ENABLE_ARM_INPUT%><br><br>
    <input type="submit" value="Submit">
  </form>
</body></html>)rawliteral";

void notFound(AsyncWebServerRequest *request) {
  request->send(404, "text/plain", "Not found");
}

AsyncWebServer server(80);

// Replaces placeholder with DS18B20 values
String processor(const String& var){
  //Serial.println(var);
  if(var == "TEMPERATURE"){
    return lastTemperature;
  }
  else if(var == "THRESHOLD"){
    return inputMessage;
  }
  else if(var == "ENABLE_ARM_INPUT"){
    return enableArmChecked;
  }
  return String();
}

// Flag variable to keep track if triggers was activated or not
bool triggerActive = false;

const char* PARAM_INPUT_1 = "threshold_input";
const char* PARAM_INPUT_2 = "enable_arm_input";

// Interval between sensor readings. Learn more about ESP32 timers: https://Raspberryme.com/esp32-pir-motion-sensor-interrupts-timers/
unsigned long previousMillis = 0;     
const long interval = 5000;    

// GPIO where the output is connected to
const int output = 2;

// GPIO where the DS18B20 is connected to
const int oneWireBus = 4;     
// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(oneWireBus);
// Pass our oneWire reference to Dallas Temperature sensor 
DallasTemperature sensors(&oneWire);

void setup() {
  Serial.begin(115200);
  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);
  if (WiFi.waitForConnectResult() != WL_CONNECTED) {
    Serial.println("WiFi Failed!");
    return;
  }
  Serial.println();
  Serial.print("ESP IP Address: http://");
  Serial.println(WiFi.localIP());
  
  pinMode(output, OUTPUT);
  digitalWrite(output, LOW);
  
  // Start the DS18B20 sensor
  sensors.begin();
  
  // Send web page to client
  server.on("https://raspberryme.com/", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/html", index_html, processor);
  });

  // Receive an HTTP GET request at <ESP_IP>/get?threshold_input=<inputMessage>&enable_arm_input=<inputMessage2>
  server.on("/get", HTTP_GET, [] (AsyncWebServerRequest *request) {
    // GET threshold_input value on <ESP_IP>/get?threshold_input=<inputMessage>
    if (request->hasParam(PARAM_INPUT_1)) {
      inputMessage = request->getParam(PARAM_INPUT_1)->value();
      // GET enable_arm_input value on <ESP_IP>/get?enable_arm_input=<inputMessage2>
      if (request->hasParam(PARAM_INPUT_2)) {
        inputMessage2 = request->getParam(PARAM_INPUT_2)->value();
        enableArmChecked = "checked";
      }
      else {
        inputMessage2 = "false";
        enableArmChecked = "";
      }
    }
    Serial.println(inputMessage);
    Serial.println(inputMessage2);
    request->send(200, "text/html", "HTTP GET request sent to your ESP.<br><a href=\"/\">Return to Home Page</a>");
  });
  server.onNotFound(notFound);
  server.begin();
}

void loop() {
  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;
    sensors.requestTemperatures();
    // Temperature in Celsius degrees 
    float temperature = sensors.getTempCByIndex(0);
    Serial.print(temperature);
    Serial.println(" *C");
    
    // Temperature in Fahrenheit degrees
    /*float temperature = sensors.getTempFByIndex(0);
    Serial.print(temperature);
    Serial.println(" *F");*/
    
    lastTemperature = String(temperature);
    
    // Check if temperature is above threshold and if it needs to trigger output
    if(temperature > inputMessage.toFloat() && inputMessage2 == "true" && !triggerActive){
      String message = String("Temperature above threshold. Current temperature: ") + 
                            String(temperature) + String("C");
      Serial.println(message);
      triggerActive = true;
      digitalWrite(output, HIGH);
    }
    // Check if temperature is below threshold and if it needs to trigger output
    else if((temperature < inputMessage.toFloat()) && inputMessage2 == "true" && triggerActive) {
      String message = String("Temperature below threshold. Current temperature: ") + 
                            String(temperature) + String(" C");
      Serial.println(message);
      triggerActive = false;
      digitalWrite(output, LOW);
    }
  }
}

Afficher le code brut

Comment fonctionne le code

Continuez à lire pour savoir comment fonctionne le code ou passez à la section Démonstration.

Bibliothèques

Commencez par importer les bibliothèques requises. le Wifi (ou ESP8266Wi-Fi), AsyncTCP (ou ESPAsyncTCP) et ESPAsyncWebServer sont nécessaires pour créer le serveur Web.

le Un fil et DallasTempérature sont nécessaires pour s’interfacer avec le DS18B20.

Le code importe automatiquement les bonnes bibliothèques en fonction de la carte sélectionnée (ESP32 ou ESP8266).

#ifdef ESP32
  #include <WiFi.h>
  #include <AsyncTCP.h>
#else
  #include <ESP8266WiFi.h>
  #include <ESPAsyncTCP.h>
#endif
#include <ESPAsyncWebServer.h>
#include <Wire.h>
#include <OneWire.h>
#include <DallasTemperature.h>

Informations d’identification réseau

Insérez vos identifiants réseau dans les lignes suivantes :

// REPLACE WITH YOUR NETWORK CREDENTIALS
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

Valeur de seuil de température par défaut

Dans le inputMessage variable insérez votre valeur de seuil de température par défaut. Nous le réglons sur 25,0mais vous pouvez le définir avec n’importe quelle autre valeur.

String inputMessage = "25.0";

Variables auxiliaires

le dernièretempérature La variable contiendra la dernière lecture de température à comparer avec la valeur de seuil.

String lastTemperature;

le enableArmChecked La variable nous dira si la case à cocher pour contrôler automatiquement la sortie est cochée ou non.

String enableArmChecked = "checked";

Dans le cas où elle est cochée, la valeur enregistrée sur le inputMessage2 doit être réglé sur vrai.

String inputMessage2 = "true";

Texte HTML

Ensuite, nous avons du texte HTML de base pour construire une page avec deux champs de saisie : un champ de saisie de seuil de température et une case à cocher pour activer ou désactiver le contrôle automatique de la sortie.

La page Web affiche également la dernière lecture de température du capteur de température DS18B20.

Les lignes suivantes affichent la température :

<h2>DS18B20 Temperature</h2> 
<h3>%TEMPERATURE% &deg;C</h3>

le %TEMPÉRATURE% est un espace réservé qui sera remplacé par la valeur de température réelle lorsque l’ESP32/ESP8266 servira la page.

Ensuite, nous avons un formulaire avec deux champs de saisie et un bouton « Soumettre ». Lorsque l’utilisateur saisit des données et clique sur le bouton « Soumettre », ces valeurs sont envoyées à l’ESP pour mettre à jour les variables.

<form action="/get">
  Temperature Threshold <input type="number" step="0.1" name="threshold_input" value="%THRESHOLD%" required><br>
  Arm Trigger <input type="checkbox" name="enable_arm_input" value="true" %ENABLE_ARM_INPUT%><br><br>
  <input type="submit" value="Submit">
</form>

Le premier champ de saisie est de type numéro et le deuxième champ d’entrée est un case à cocher. Pour en savoir plus sur les champs de saisie, nous vous recommandons de consulter les ressources suivantes du site Web w3schools :

le action L’attribut du formulaire spécifie où envoyer les données insérées dans le formulaire après avoir appuyé sur Soumettre. Dans ce cas, il fait une requête HTTP GET à :

/get?threshold_input=value&enable_arm_input=value

le valeur fait référence au texte que vous saisissez dans chacun des champs de saisie. Pour en savoir plus sur la gestion des champs de saisie avec l’ESP32/ESP8266, lisez : Données d’entrée sur le serveur Web HTML Form ESP32/ESP8266 à l’aide de l’IDE Arduino.

processeur()

le processeur() La fonction remplace tous les espaces réservés dans le texte HTML par les valeurs réelles.

  • %TEMPÉRATURE% » dernièretempérature
  • %SEUIL% » inputMessage
String processor(const String& var){
  //Serial.println(var);
  if(var == "TEMPERATURE"){
    return lastTemperature;
  }
  else if(var == "THRESHOLD"){
    return inputMessage;
  }
  else if(var == "ENABLE_ARM_INPUT"){
    return enableArmChecked;
  }
  return String();
}

Paramètres de champ d’entrée

Les variables suivantes seront utilisées pour vérifier si nous avons reçu une requête HTTP GET de ces champs de saisie et enregistrer les valeurs dans les variables en conséquence.

const char* PARAM_INPUT_1 = "threshold_input";
const char* PARAM_INPUT_2 = "enable_arm_input";

Intervalle entre les lectures

Toutes les 5000 millisecondes (5 secondes), nous obtiendrons une nouvelle lecture de température du capteur de température DS18B20 et la comparerons à la valeur seuil. Pour garder une trace du temps, nous utilisons des minuteries.

Changer la intervalle variable si vous souhaitez modifier le temps entre chaque lecture du capteur.

unsigned long previousMillis = 0;
const long interval = 5000;

Sortie GPIO

Dans cet exemple, nous contrôlerons GPIO 2. Ce GPIO est connecté aux LED intégrées ESP32 et ESP8266, ce qui nous permet de vérifier facilement si le projet fonctionne comme prévu. Vous pouvez contrôler n’importe quelle autre sortie et pour de nombreuses applications, vous souhaiterez contrôler un module de relais.

// GPIO where the output is connected to
const int output = 2;

Initiation du capteur de température DS18B20

Initialiser le capteur de température DS18B20.

// GPIO where the DS18B20 is connected to
const int oneWireBus = 4;
// Setup a oneWire instance to communicate with any OneWire devices
OneWire oneWire(oneWireBus);
// Pass our oneWire reference to Dallas Temperature sensor 
DallasTemperature sensors(&oneWire);

Pour en savoir plus sur l’interfaçage du capteur de température DS18B20 avec la carte ESP, lisez :

mettre en place()

Dans le mettre en place()connectez-vous au Wi-Fi en mode station et imprimez l’adresse IP ESP :

Serial.begin(115200);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
if (WiFi.waitForConnectResult() != WL_CONNECTED) {
  Serial.println("WiFi Failed!");
  return;
}
Serial.println();
Serial.print("ESP IP Address: http://");
Serial.println(WiFi.localIP());

Ensemble GPIO 2 comme sortie et réglez-le sur MEUGLER lorsque l’ESP démarre pour la première fois.

pinMode(output, OUTPUT);
digitalWrite(output, LOW);

Initialisez le capteur de température DS18B20 :

sensors.begin();

Gérer le serveur Web

Ensuite, définissez ce qui se passe lorsque l’ESP32 ou l’ESP8266 reçoit des requêtes HTTP. Lorsque nous obtenons une requête sur la root / url, envoyez le texte HTML avec le processeur (afin que les espaces réservés soient remplacés par les dernières valeurs).

server.on("https://raspberryme.com/", HTTP_GET, [](AsyncWebServerRequest *request){
  request->send_P(200, "text/html", index_html, processor);
});

Lorsqu’un formulaire est soumis, l’ESP reçoit une requête sur l’URL suivante :

<ESP_IP>/get?threshold_input=<inputMessage>&enable_arm_input=<inputMessage2>

Nous vérifions donc si la requête contient des paramètres d’entrée et enregistrons ces paramètres dans des variables :

server.on("/get", HTTP_GET, [] (AsyncWebServerRequest *request) {
  // GET threshold_input value on <ESP_IP>/get?threshold_input=<inputMessage>
  if (request->hasParam(PARAM_INPUT_1)) {
    inputMessage = request->getParam(PARAM_INPUT_1)->value();
    // GET enable_arm_input value on <ESP_IP>/get?enable_arm_input=<inputMessage2>
    if (request->hasParam(PARAM_INPUT_2)) {
      inputMessage2 = request->getParam(PARAM_INPUT_2)->value();
      enableArmChecked = "checked";
    }
    else {
      inputMessage2 = "false";
      enableArmChecked = "";
    }
  }

C’est la partie du code où les variables seront remplacées par les valeurs soumises sur le formulaire. le inputMessage variable enregistre la valeur du seuil de température et la inputMessage2 enregistre si la case est cochée ou non (si nous devons contrôler le GPIO ou non).

Après avoir soumis les valeurs sur le formulaire, il affiche une nouvelle page indiquant que la demande a été envoyée avec succès à votre tableau et avec un lien pour revenir à la page d’accueil.

request->send(200, "text/html", "HTTP GET request sent to your ESP.<br><a href=\"/\">Return to Home Page</a>");
});

Enfin, démarrez le serveur :

server.begin();

boucler()

Dans le boucler()nous utilisons des minuteries pour obtenir de nouvelles lectures de température toutes les 5 secondes.

unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= interval) {
  previousMillis = currentMillis;
  sensors.requestTemperatures();
  // Temperature in Celsius degrees 
  float temperature = sensors.getTempCByIndex(0);
  Serial.print(temperature);
  Serial.println(" *C");
    
  // Temperature in Fahrenheit degrees
  /*float temperature = sensors.getTempFByIndex(0);
  Serial.print(temperature);
  Serial.println(" *F");*/
  
  lastTemperature = String(temperature);

Après avoir obtenu une nouvelle lecture de température, nous vérifions si elle est supérieure ou inférieure au seuil et activons ou désactivons la sortie en conséquence.

Dans cet exemple, nous définissons l’état de sortie sur HAUTsi toutes ces conditions sont remplies :

  • La température actuelle est supérieure au seuil ;
  • Le contrôle automatique de la sortie est activé (la case est cochée sur la page Web) ;
  • Si la sortie n’a pas encore été déclenchée.
// Check if temperature is above threshold and if it needs to trigger output
if(temperature > inputMessage.toFloat() && inputMessage2 == "true" && !triggerActive){
  String message = String("Temperature above threshold. Current temperature: ") 
                   + String(temperature) + String("C");
  Serial.println(message);
  triggerActive = true;
  digitalWrite(output, HIGH);
}

Ensuite, si la température passe en dessous du seuil, réglez la sortie sur MEUGLER.

else if((temperature < inputMessage.toFloat()) && inputMessage2 == "true" && triggerActive) {
  String message = String("Temperature below threshold. Current temperature: ") 
                   + String(temperature) + String(" C");
  Serial.println(message);
  triggerActive = false;
  digitalWrite(output, LOW);
}

En fonction de votre application, vous souhaiterez peut-être modifier la sortie en MEUGLERlorsque la température est supérieure au seuil et à HAUT lorsque la sortie est inférieure au seuil.

Démonstration – Thermostat ESP

Téléchargez le code sur votre carte ESP (avec le DS18B20 câblé à votre carte ESP32 ou ESP8266).

Ouvrez le moniteur série à un débit en bauds de 115200 et appuyez sur le bouton RST/EN intégré. L’ESP imprimera son adresse IP et commencera à afficher de nouvelles valeurs de température toutes les 5 secondes.

ESP32 ESP8266 Seuil de température Arduino IDE Serial Monitor

Ouvrez un navigateur et saisissez l’adresse IP ESP. Une page Web similaire devrait se charger avec les valeurs par défaut (définies dans votre code) :

ESP32 ESP8266 Serveur Web de déclenchement de seuil de température Arduino IDE

Si le déclencheur d’armement est activé (case cochée) et si la température dépasse le seuil, la LED doit s’allumer (la sortie est réglée sur HAUT).

ESP32 ESP8266 Sortie de contrôle lorsque la température est supérieure au serveur Web de seuil

Après cela, si la température descend en dessous du seuil, la sortie s’éteindra.

ESP32 ESP8266 sortie de contrôle lorsque la température est inférieure au serveur Web de seuil

Vous pouvez utiliser les champs de saisie de la page Web pour modifier la valeur de seuil ou pour armer et désarmer le contrôle de la sortie. Pour que tout changement prenne effet, il vous suffit d’appuyer sur le bouton « Soumettre ».

En même temps, vous devriez obtenir les nouveaux champs de saisie dans le Serial Monitor.

ESP32 ESP8266 Modifier le seuil de température sur le serveur Web

Emballer

Dans ce projet, vous avez appris à créer un serveur Web avec une valeur de seuil pour contrôler automatiquement une sortie en fonction du serveur Web du thermostat de lecture de température actuelle). Par exemple, nous avons contrôlé une LED. Pour les applications du monde réel, vous souhaiterez probablement contrôler un module de relais. Vous pouvez lire les guides suivants pour apprendre à contrôler un relais avec l’ESP :

Nous avons utilisé du texte HTML brut pour rendre le projet plus facile à suivre. Nous vous suggérons d’ajouter du CSS pour styliser votre page Web afin de la rendre plus agréable. Vous pouvez également ajouter des notifications par e-mail à ce projet.

Si vous souhaitez en savoir plus sur l’ESP32 et l’ESP8266, essayez nos projets et ressources :

Merci d’avoir lu.