Serveur Web ESP32/ESP8266 : sorties de contrôle avec minuterie

Serveur Web ESP32/ESP8266 : sorties de contrôle avec minuterie

Dans ce didacticiel, vous allez créer un serveur Web pour contrôler les sorties ESP32 ou ESP8266 NodeMCU avec une impulsion à l’aide de l’IDE Arduino. La largeur d’impulsion (« minuterie ») peut être ajustée à l’aide d’un curseur sur la page Web. Lorsque vous cliquez sur le bouton ON, l’ESP définit l’état de sortie sur HIGH pendant le nombre de secondes défini dans le curseur. Cela peut être particulièrement utile pour contrôler les appareils qui ont besoin d’un signal HIGH pendant un nombre prédéterminé de secondes pour s’actionner.

Serveur Web ESP32 ESP8266 NodeMCU : contrôler les sorties avec minuterie à l'aide de l'IDE Arduino

Les cartes ESP32/ESP8266 seront programmées à l’aide de l’IDE Arduino. Assurez-vous donc que ces cartes sont installées :

Aperçu du projet

L’image suivante montre un aperçu du fonctionnement de ce projet.

ESP32 ESP8266 Sorties de contrôle NodeMCU avec serveur Web de minuterie Comment ça marche Présentation du projet
  • L’ESP32/ESP8266 héberge un serveur web qui permet de contrôler une sortie avec une impulsion ;
  • Le serveur Web contient un curseur qui vous permet de définir la largeur d’impulsion (combien de secondes la sortie doit être ÉLEVÉE) ;
  • Il y a un bouton ON/OFF. Réglez-le sur ON pour envoyer l’impulsion. Après cela, vous verrez une minuterie diminuer pendant la durée de la largeur d’impulsion ;
  • Lorsque la minuterie est terminée, la sortie est réglée sur LOW et le bouton du serveur Web revient à l’état OFF ;
  • Ce serveur Web peut être utile pour contrôler les appareils qui ont besoin d’une impulsion pour s’activer comme les ouvre-portes de garage, par exemple.

Installation de bibliothèques – Serveur Web asynchrone

Pour construire le serveur Web, vous devez installer les bibliothèques suivantes :

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.

Code

Copiez le code suivant dans votre IDE Arduino.

/*********
  Rui Santos
  Complete project details at https://Raspberryme.com/esp32-esp8266-web-server-timer-pulse/
  
  The above copyright notice and this permission notice shall be included in all
  copies or substantial portions of the Software.
*********/

// Import required libraries
#ifdef ESP32
  #include <WiFi.h>
  #include <AsyncTCP.h>
#else
  #include <ESP8266WiFi.h>
  #include <ESPAsyncTCP.h>
#endif
#include <ESPAsyncWebServer.h>

// Replace with your network credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

const char* PARAM_INPUT_1 = "state";
const char* PARAM_INPUT_2 = "value";

const int output = 2;

String timerSliderValue = "10";

// Create AsyncWebServer object on port 80
AsyncWebServer server(80);

const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html>
<head>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <title>ESP Web Server</title>
  <style>
    html {font-family: Arial; display: inline-block; text-align: center;}
    h2 {font-size: 2.4rem;}
    p {font-size: 2.2rem;}
    body {max-width: 600px; margin:0px auto; padding-bottom: 25px;}
    .switch {position: relative; display: inline-block; width: 120px; height: 68px} 
    .switch input {display: none}
    .slider {position: absolute; top: 0; left: 0; right: 0; bottom: 0; background-color: #ccc; border-radius: 34px}
    .slider:before {position: absolute; content: ""; height: 52px; width: 52px; left: 8px; bottom: 8px; background-color: #fff; -webkit-transition: .4s; transition: .4s; border-radius: 68px}
    input:checked+.slider {background-color: #2196F3}
    input:checked+.slider:before {-webkit-transform: translateX(52px); -ms-transform: translateX(52px); transform: translateX(52px)}
    .slider2 { -webkit-appearance: none; margin: 14px; width: 300px; height: 20px; background: #ccc;
      outline: none; -webkit-transition: .2s; transition: opacity .2s;}
    .slider2::-webkit-slider-thumb {-webkit-appearance: none; appearance: none; width: 30px; height: 30px; background: #2f4468; cursor: pointer;}
    .slider2::-moz-range-thumb { width: 30px; height: 30px; background: #2f4468; cursor: pointer; } 
  </style>
</head>
<body>
  <h2>ESP Web Server</h2>
  <p><span id="timerValue">%TIMERVALUE%</span> s</p>
  <p><input type="range" onchange="updateSliderTimer(this)" id="timerSlider" min="1" max="20" value="%TIMERVALUE%" step="1" class="slider2"></p>
  %BUTTONPLACEHOLDER%
<script>
function toggleCheckbox(element) {
  var sliderValue = document.getElementById("timerSlider").value;
  var xhr = new XMLHttpRequest();
  if(element.checked){ xhr.open("GET", "/update?state=1", true); xhr.send();
    var count = sliderValue, timer = setInterval(function() {
      count--; document.getElementById("timerValue").innerHTML = count;
      if(count == 0){ clearInterval(timer); document.getElementById("timerValue").innerHTML = document.getElementById("timerSlider").value; }
    }, 1000);
    sliderValue = sliderValue*1000;
    setTimeout(function(){ xhr.open("GET", "/update?state=0", true); 
    document.getElementById(element.id).checked = false; xhr.send(); }, sliderValue);
  }
}
function updateSliderTimer(element) {
  var sliderValue = document.getElementById("timerSlider").value;
  document.getElementById("timerValue").innerHTML = sliderValue;
  var xhr = new XMLHttpRequest();
  xhr.open("GET", "/slider?value="+sliderValue, true);
  xhr.send();
}
</script>
</body>
</html>
)rawliteral";

// Replaces placeholder with button section in your web page
String processor(const String& var){
  //Serial.println(var);
  if(var == "BUTTONPLACEHOLDER"){
    String buttons = "";
    String outputStateValue = outputState();
    buttons+= "<p><label class=\"switch\"><input type=\"checkbox\" onchange=\"toggleCheckbox(this)\" id=\"output\" " + outputStateValue + "><span class=\"slider\"></span></label></p>";
    return buttons;
  }
  else if(var == "TIMERVALUE"){
    return timerSliderValue;
  }
  return String();
}

String outputState(){
  if(digitalRead(output)){
    return "checked";
  }
  else {
    return "";
  }
  return "";
}

void setup(){
  // Serial port for debugging purposes
  Serial.begin(115200);

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

  // Connect to Wi-Fi
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi..");
  }

  // Print ESP Local IP Address
  Serial.println(WiFi.localIP());

  // Route for root / web page
  server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
    request->send_P(200, "text/html", index_html, processor);
  });

  // Send a GET request to <ESP_IP>/update?state=<inputMessage>
  server.on("/update", HTTP_GET, [] (AsyncWebServerRequest *request) {
    String inputMessage;
    // GET input1 value on <ESP_IP>/update?state=<inputMessage>
    if (request->hasParam(PARAM_INPUT_1)) {
      inputMessage = request->getParam(PARAM_INPUT_1)->value();
      digitalWrite(output, inputMessage.toInt());
    }
    else {
      inputMessage = "No message sent";
    }
    Serial.println(inputMessage);
    request->send(200, "text/plain", "OK");
  });
  
  // Send a GET request to <ESP_IP>/slider?value=<inputMessage>
  server.on("/slider", HTTP_GET, [] (AsyncWebServerRequest *request) {
    String inputMessage;
    // GET input1 value on <ESP_IP>/slider?value=<inputMessage>
    if (request->hasParam(PARAM_INPUT_2)) {
      inputMessage = request->getParam(PARAM_INPUT_2)->value();
      timerSliderValue = inputMessage;
    }
    else {
      inputMessage = "No message sent";
    }
    Serial.println(inputMessage);
    request->send(200, "text/plain", "OK");
  });
  
  // Start server
  server.begin();
}
  
void loop() {
  
}

Afficher le code brut

Il vous suffit d’entrer vos informations d’identification réseau (SSID et mot de passe) et le serveur Web fonctionnera immédiatement. Le code est compatible avec les deux ESP32 et ESP8266 embarque et contrôle la LED embarquée GPIO 2 – vous pouvez changer le code pour contrôler n’importe quel autre GPIO.

Comment fonctionne le code

Nous avons déjà expliqué en détail le fonctionnement des serveurs Web comme celui-ci dans les didacticiels précédents (DHT Temperature Web Server ou Relay Web Server), nous allons donc simplement examiner les parties pertinentes pour ce projet.

Informations d’identification réseau

Comme dit précédemment, insérez vos identifiants réseau dans les lignes suivantes :

const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";

Libellé du curseur

Au-dessus du curseur, il y a un nombre indiquant la valeur actuelle du curseur.

<p><span id="timerValue">%TIMERVALUE%</span> s</p>

Par défaut, la valeur du curseur est définie sur %TIMERVALUE% espace réservé.

le %TIMERVALUE% est un espace réservé qui sera remplacé par la valeur stockée dans le timerSliderValuetimerSliderValue variable qui vaut 10 par défaut. Mais vous pouvez changer cela dans la ligne suivante :

String timerSliderValue = "10";

Cela sera également modifié lorsque vous déplacerez le curseur. Lorsque le curseur est déplacé, il appelle une fonction JavaScript qui met à jour la valeur du curseur.

Glissière

La ligne suivante crée le curseur.

<input type="range" onchange="updateSliderTimer(this)" id="timerSlider" min="1" max="20" value="%TIMERVALUE%" step="1" class="slider2">

Décomposons cela en sections plus petites.

En HTML, un curseur est un type d’entrée. le tag spécifie un champ de saisie dans lequel l’utilisateur peut saisir des données. Le curseur est un champ de saisie de type intervalle. Il existe de nombreux autres types de champs de saisie.

<input type="range">

La plage par défaut du curseur est comprise entre 0 et 100. Vous pouvez utiliser les attributs suivants pour personnaliser les paramètres du curseur :

  • maximum: spécifie la valeur maximale autorisée. Dans notre exemple, nous le fixons à 20, mais vous pouvez modifier cette valeur.
  • min: spécifie la valeur minimale. Dans ce cas, nous le mettons à 1.
  • étape: spécifie l’intervalle de nombres. Il est réglé sur 1.
  • valeur: spécifie la valeur par défaut du curseur. Dans ce cas, il est égal à %TIMERVALUE%.
<input type="range" onchange="updateSliderTimer(this)" id="timerSlider" min="1" max="20" value="%TIMERVALUE%" step="1" class="slider2">

le %TIMERVALUE% est un espace réservé qui sera remplacé par une valeur réelle. Dans le code, il sera remplacé par la valeur du timerSliderValuetimerSliderValue variable qui vaut 10 par défaut. Mais vous pouvez changer cela dans la ligne suivante :

String timerSliderValue = "10";

Le curseur a deux attributs supplémentaires : identifiant et sur le changement.

  • identifiant: spécifie un identifiant unique pour un élément HTML (curseur). L’id nous permet de manipuler l’élément en utilisant CSS ou JavaScript.
  • sur le changement: est un attribut d’événement qui se produit lorsque nous modifions la valeur de l’élément (le curseur). Lorsque vous déplacez le curseur, il appelle le updateSliderTimer() une fonction.

Mettre à jour la valeur du curseur (JavaScript)

Lorsque vous déplacez le curseur, le updateSliderTimer() fonction est exécutée.

Il obtient la valeur actuelle du curseur en se référant à son identifiant minuterieCurseur:

var sliderValue = document.getElementById("timerSlider").value;

Met à jour l’étiquette du curseur à la valeur actuelle du curseur en se référant à son identifiant timerValue:

document.getElementById("timerValue").innerHTML = sliderValue;

Ensuite, il fait une requête sur le /slider?value=sliderValue URL. Où le sliderValue est égal à la valeur actuelle du curseur.

Ensuite, l’ESP32/ESP8266 gère ce qui se passe lorsqu’il reçoit une requête sur cette URL.

Contrôler la sortie avec la minuterie (JavaScript)

Lorsque vous cliquez sur le bouton ON/OFF pour contrôler la sortie, il appelle le toogleCheckbox() Fonction JavaScript.

Cette fonction obtient la valeur actuelle de l’étiquette du curseur :

var sliderValue = document.getElementById("timerSlider").value;

Fait une demande sur le /mise à jour?état=1 URL pour que l’ESP sache qu’il doit définir la sortie sur HAUT.

if(element.checked){ xhr.open("GET", "/update?state=1", true); xhr.send();

Les lignes suivantes diminuent la valeur de l’étiquette du curseur chaque seconde en créant le compte à rebours.

var count = sliderValue, timer = setInterval(function() {
  count--; document.getElementById("timerValue").innerHTML = count;
  if(count == 0){ clearInterval(timer); document.getElementById("timerValue").innerHTML = document.getElementById("timerSlider").value; }
}, 1000);

Lorsque la minuterie atteint zéro, la valeur de l’étiquette revient à sa valeur d’origine et une demande est faite sur le /mise à jour?état=0 URL, afin que l’ESP sache qu’il est temps de définir la sortie sur MEUGLER. Le bouton du serveur Web revient à l’état désactivé.

setTimeout(function(){ xhr.open("GET", "/update?state=0", true); 
document.getElementById(element.id).checked = false; xhr.send(); }, sliderValue);

Traiter les demandes

L’ESP32/ESP8266 doit gérer ce qui se passe lorsqu’il reçoit une requête sur une certaine URL.

URL root

Lorsque vous accédez à l’URL root /envoyez le texte HTML enregistré sur le index_html variable. Tous les espaces réservés sont remplacés par les valeurs réelles par le processeur() une fonction.

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

État de la sortie de contrôle

Les lignes suivantes gèrent ce qui se passe lorsque vous recevez une demande sur le /mise à jour?état=1 et /mise à jour?état=0 URL. Il définit l’état de sortie sur HAUT ou MEUGLER par conséquent.

server.on("/update", HTTP_GET, [] (AsyncWebServerRequest *request) {
  String inputMessage;
  // GET input1 value on <ESP_IP>/update?state=<inputMessage>
  if (request->hasParam(PARAM_INPUT_1)) {
    inputMessage = request->getParam(PARAM_INPUT_1)->value();
    digitalWrite(output, inputMessage.toInt());
  }
  else {
    inputMessage = "No message sent";
  }
  Serial.println(inputMessage);
  request->send(200, "text/plain", "OK");
});

L’état de la sortie est mis à jour dans la ligne suivante :

digitalWrite(output, inputMessage.toInt());

Mettre à jour la valeur du curseur

Chaque fois que vous faites glisser le curseur, l’ESP reçoit une requête avec la nouvelle valeur. Nous stockons la nouvelle valeur du curseur et l’imprimons dans le moniteur série.

// Send a GET request to <ESP_IP>/slider?value=<inputMessage>
server.on("/slider", HTTP_GET, [] (AsyncWebServerRequest *request) {
  String inputMessage;
  // GET input1 value on <ESP_IP>/slider?value=<inputMessage>
  if (request->hasParam(PARAM_INPUT_2)) {
    inputMessage = request->getParam(PARAM_INPUT_2)->value();
    timerSliderValue = inputMessage;
  }
  else {
    inputMessage = "No message sent";
  }
  Serial.println(inputMessage);
  request->send(200, "text/plain", "OK");
});

Manifestation

Téléchargez le code sur votre carte ESP32 ou ESP8266 NodeMCU. Ensuite, ouvrez le moniteur série et appuyez sur le bouton RST/EN intégré pour obtenir son adresse IP.

Ouvrez un navigateur sur votre réseau local et saisissez l’adresse IP ESP. La page suivante devrait se charger.

Sorties de contrôle du serveur Web ESP32 ESP8266 NodeMCU avec minuterie à l'aide de la démonstration IDE Arduino

Faites glisser le curseur pour régler la largeur d’impulsion, puis cliquez sur le bouton ON/OFF. La sortie (dans ce cas GPIO 2 – LED intégrée) restera allumée pendant la durée que vous avez définie sur le curseur.

Carte ESP32 LED intégrée allumée HIGH

Regardez la prochaine vidéo rapide pour une démonstration en direct :

Conclusion

Dans ce didacticiel, vous avez appris à créer un serveur Web pour contrôler une sortie avec une impulsion. La largeur d’impulsion peut être ajustée avec un curseur sur la page du serveur Web. Cela peut être particulièrement utile pour contrôler certains appareils nécessitant un signal HIGH pendant un nombre déterminé de secondes pour s’actionner, comme les ouvre-portes de garage.

Nous espérons que ce tutoriel vous a plu. Nous avons d’autres projets de serveur Web que vous pourriez aimer :

Apprenez-en plus sur les cartes ESP32 et ESP8266 avec nos ressources.