Serveur Web asynchrone ESP8266 NodeMCU – Sorties de contrôle

Serveur Web asynchrone ESP8266 NodeMCU - Sorties de contrôle

Dans ce didacticiel, vous apprendrez à créer un serveur Web asynchrone avec la carte ESP8266 NodeMCU pour contrôler ses sorties. La carte sera programmée à l’aide de l’IDE Arduino et nous utiliserons la bibliothèque ESPAsyncWebServer.

Sorties de contrôle de serveur Web asynchrone ESP8266 NodeMCU avec la bibliothèque Arduino IDE ESPAsyncWebServer

Vous pourriez aussi aimer: Serveur Web ESP32 Async – Sorties de contrôle avec Arduino IDE (bibliothèque ESPAsyncWebServer)

Serveur Web asynchrone

Pour construire le serveur Web, nous utiliserons le Bibliothèque ESPAsyncWebServer qui fournit un moyen simple de créer un serveur Web asynchrone. La construction d’un serveur Web asynchrone présente plusieurs avantages, comme mentionné dans la page GitHub de la bibliothèque, tels que :

  • « Gérer plus d’une connexion en même temps » ;
  • « Lorsque vous envoyez la réponse, vous êtes immédiatement prêt à gérer d’autres connexions pendant que le serveur se charge d’envoyer la réponse en arrière-plan » ;
  • « Moteur de traitement de modèle simple pour gérer les modèles » ;
  • Et beaucoup plus.

Jetez un oeil à la documentation de la bibliothèque sur sa page GitHub.

Pièces requises

Dans ce didacticiel, nous contrôlerons trois sorties. Par exemple, nous allons contrôler les LED. Donc, 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 !

Serveur Web asynchrone ESP8266 NodeMCU Sorties de controle

Schématique

Avant de procéder au code, câblez 3 LED à l’ESP8266. Nous connectons les LED aux GPIO 5, 4 et 2, mais vous pouvez utiliser n’importe quel autre GPIO (lisez le guide de référence ESP8266 NodeMCU GPIO).

ESP8266 NodeMCU Arduino Sorties Async ESPAsyncWebServer schéma de câblage de la bibliothèque

Installation de bibliothèques – Serveur Web ESP Async

Pour construire le serveur Web, vous devez installer les bibliothèques suivantes. Cliquez sur les liens ci-dessous pour télécharger les 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.

Aperçu du projet

Pour mieux comprendre le code, voyons comment fonctionne le serveur Web.

Sorties de contrôle de serveur Web asynchrone ESP8266 NodeMCU
  • Le serveur Web contient une rubrique « ESP Web Server » et trois boutons (interrupteurs à bascule) pour contrôler trois sorties. Chaque bouton de curseur a une étiquette indiquant la broche de sortie GPIO. Vous pouvez facilement supprimer/ajouter plus de sorties.
  • Lorsque le curseur est rouge, cela signifie que la sortie est activée (son état est HIGH). Si vous basculez le curseur, il désactive la sortie (changez l’état sur LOW).
  • Lorsque le curseur est gris, cela signifie que la sortie est désactivée (son état est BAS). Si vous basculez le curseur, il active la sortie (changez l’état sur HIGH).

Comment ça fonctionne?

Présentation du projet de serveur Web asynchrone ESP8266 NodeMCU Bibliothèque ESPAsyncWebServer

Voyons ce qui se passe lorsque vous basculez les boutons. Nous verrons l’exemple pour GPIO 2. Cela fonctionne de la même manière pour les autres boutons.

1. Dans le premier scénario, vous basculez le bouton pour activer GPIO 2. Lorsque cela se produit, il effectue une requête HTTP GET sur le /mise à jour?sortie=2&état=1 URL. Sur la base de cette URL, nous changeons l’état de GPIO 2 en 1 (HAUT) et allumez la LED.

2. Dans le deuxième exemple, lorsque vous basculez le bouton pour désactiver GPIO 2. Lorsque cela se produit, faites une requête HTTP GET sur le /mise à jour?sortie=2&état=0 URL. Sur la base de cette URL, nous changeons l’état de GPIO 2 à 0 (MEUGLER) et éteignez la LED.

Code pour le serveur Web asynchrone ESP

Copiez le code suivant dans votre IDE Arduino.

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

// Import required libraries
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#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 = "output";
const char* PARAM_INPUT_2 = "state";

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

const char index_html[] PROGMEM = R"rawliteral(
<!DOCTYPE HTML><html>
<head>
  <title>ESP Web Server</title>
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" href="https://www.raspberryme.com/esp8266-nodemcu-async-web-server-espasyncwebserver-library/data:,">
  <style>
    html {font-family: Arial; display: inline-block; text-align: center;}
    h2 {font-size: 3.0rem;}
    p {font-size: 3.0rem;}
    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: 6px}
    .slider:before {position: absolute; content: ""; height: 52px; width: 52px; left: 8px; bottom: 8px; background-color: #fff; -webkit-transition: .4s; transition: .4s; border-radius: 3px}
    input:checked+.slider {background-color: #b30000}
    input:checked+.slider:before {-webkit-transform: translateX(52px); -ms-transform: translateX(52px); transform: translateX(52px)}
  </style>
</head>
<body>
  <h2>ESP Web Server</h2>
  %BUTTONPLACEHOLDER%
<script>function toggleCheckbox(element) {
  var xhr = new XMLHttpRequest();
  if(element.checked){ xhr.open("GET", "/update?output="+element.id+"&state=1", true); }
  else { xhr.open("GET", "/update?output="+element.id+"&state=0", 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 = "";
    buttons += "<h4>Output - GPIO 5</h4><label class="switch"><input type="checkbox" onchange="toggleCheckbox(this)" id="5" " + outputState(5) + "><span class="slider"></span></label>";
    buttons += "<h4>Output - GPIO 4</h4><label class="switch"><input type="checkbox" onchange="toggleCheckbox(this)" id="4" " + outputState(4) + "><span class="slider"></span></label>";
    buttons += "<h4>Output - GPIO 2</h4><label class="switch"><input type="checkbox" onchange="toggleCheckbox(this)" id="2" " + outputState(2) + "><span class="slider"></span></label>";
    return buttons;
  }
  return String();
}

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

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

  pinMode(5, OUTPUT);
  digitalWrite(5, LOW);
  pinMode(4, OUTPUT);
  digitalWrite(4, LOW);
  pinMode(2, OUTPUT);
  digitalWrite(2, 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?output=<inputMessage1>&state=<inputMessage2>
  server.on("/update", HTTP_GET, [] (AsyncWebServerRequest *request) {
    String inputMessage1;
    String inputMessage2;
    // GET input1 value on <ESP_IP>/update?output=<inputMessage1>&state=<inputMessage2>
    if (request->hasParam(PARAM_INPUT_1) && request->hasParam(PARAM_INPUT_2)) {
      inputMessage1 = request->getParam(PARAM_INPUT_1)->value();
      inputMessage2 = request->getParam(PARAM_INPUT_2)->value();
      digitalWrite(inputMessage1.toInt(), inputMessage2.toInt());
    }
    else {
      inputMessage1 = "No message sent";
      inputMessage2 = "No message sent";
    }
    Serial.print("GPIO: ");
    Serial.print(inputMessage1);
    Serial.print(" - Set to: ");
    Serial.println(inputMessage2);
    request->send(200, "text/plain", "OK");
  });

  // Start server
  server.begin();
}

void loop() {

}

Afficher le code brut

Comment fonctionne le code

Dans cette section, nous expliquerons le fonctionnement du code. Continuez à lire si vous voulez en savoir plus ou passez à la section Démonstration pour voir le résultat final.

Importation de bibliothèques

Tout d’abord, importez les bibliothèques requises. Vous devez inclure le Wifi, ESPAsyncWebserver et le ESPAsyncTCP bibliothèques.

#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>

Définition de vos identifiants réseau

Insérez vos informations d’identification réseau dans les variables suivantes, afin que l’ESP8266 puisse se connecter à votre réseau local.

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

Paramètres d’entrée

Pour vérifier les paramètres passés sur l’URL (numéro GPIO et son état), on crée deux variables, une pour la sortie et l’autre pour l’état.

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

N’oubliez pas que l’ESP8266 reçoit des requêtes comme celle-ci : /mettre à jour?sortir=2&Etat=0

Objet AsyncWebServerAsyncWebServer object

Créé un AsyncWebServer objet sur le port 80.

AsyncWebServer server(80);

Construire la page Web

Tout le texte HTML avec les styles et JavaScript est stocké dans le index_html variable. Nous allons maintenant parcourir le texte HTML et voir ce que fait chaque partie.

Le titre va à l’intérieur du et Mots clés. Le titre est exactement ce à quoi il ressemble : le titre de votre document, qui s’affiche dans la barre de titre de votre navigateur Web. Dans ce cas, il s’agit de « ESP Web Server ».

<title>ESP Web Server</title>
Titre de la page Web du serveur Web asynchrone ESP32 HTML

Ce qui suit tag rend votre page Web réactive dans n’importe quel navigateur (ordinateur portable, tablette ou smartphone).

<meta name="viewport" content="width=device-width, initial-scale=1">

La ligne suivante empêche les requêtes sur le favicon. Dans ce cas, nous n’avons pas de favicon. Le favicon est l’icône du site Web qui s’affiche à côté du titre dans l’onglet du navigateur Web. Si nous n’ajoutons pas la ligne suivante, l’ESP recevra une demande de favicon chaque fois que nous accédons au serveur Web.

<link rel="icon" href="https://www.raspberryme.com/esp8266-nodemcu-async-web-server-espasyncwebserver-library/data:,">

Entre le

balises, nous ajoutons du CSS pour styliser la page Web. Nous n’entrerons pas dans les détails sur le fonctionnement de ce style CSS.

<style>
    html {font-family: Arial; display: inline-block; text-align: center;}
    h2 {font-size: 3.0rem;}
    p {font-size: 3.0rem;}
    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: 6px}
    .slider:before {position: absolute; content: ""; height: 52px; width: 52px; left: 8px; bottom: 8px; background-color: #fff; -webkit-transition: .4s; transition: .4s; border-radius: 3px}
    input:checked+.slider {background-color: #b30000}
    input:checked+.slider:before {-webkit-transform: translateX(52px); -ms-transform: translateX(52px); transform: translateX(52px)}
</style>

Corps HTML

À l’intérieur de les balises sont l’endroit où nous ajoutons le contenu de la page Web.

le

les balises ajoutent un titre à la page Web. Dans ce cas, le texte « ESP Web Server », mais vous pouvez ajouter n’importe quel autre texte.

<h2>ESP Web Server</h2>

Après le titre, nous avons les boutons. La façon dont les boutons s’affichent sur la page Web (rouge : si le GPIO est activé ; ou gris : si le GPIO est désactivé) varie en fonction de l’état actuel du GPIO.

Lorsque vous accédez à la page du serveur Web, vous souhaitez qu’elle affiche les bons états GPIO actuels. Ainsi, au lieu d’ajouter le texte HTML pour créer les boutons, nous ajouterons un espace réservé %BUTTONPLACEHOLDER%. Cet espace réservé sera ensuite remplacé par le texte HTML réel pour créer les boutons avec les bons états, lorsque la page Web est chargée.

%BUTTONPLACEHOLDER%

Javascript

Ensuite, il y a du JavaScript qui est chargé de faire une requête HTTP GET lorsque vous basculez les boutons comme nous l’avons expliqué précédemment.

<script>function toggleCheckbox(element) {
  var xhr = new XMLHttpRequest();
  if(element.checked){ xhr.open("GET", "/update?output="+element.id+"&state=1", true); }
  else { xhr.open("GET", "/update?output="+element.id+"&state=0", true); }
  xhr.send();
}
</script>

Voici la ligne qui fait la requête :

if(element.checked){ xhr.open("GET", "/update?output="+element.id+"&state=1", true); }

élément.id renvoie l’identifiant d’un élément HTML. L’identifiant de chaque bouton sera le GPIO contrôlé comme nous le verrons dans la section suivante :

  • Bouton GPIO 5 » element.id = 5
  • Bouton GPIO 4 » element.id = 4
  • Bouton GPIO 2 » element.id = 2

Processeur

Maintenant, nous devons créer le processeur() fonction, qui remplace les espaces réservés dans le texte HTML par ce que nous définissons.

Lorsque la page Web est demandée, vérifiez si le code HTML contient des espaces réservés. S’il trouve le %BUTTONPLACEHOLDER% espace réservé, il renvoie le texte HTML pour créer les boutons.

String processor(const String& var){
  //Serial.println(var);
  if(var == "BUTTONPLACEHOLDER"){
    String buttons = "";
    buttons += "<h4>Output - GPIO 5</h4><label class="switch"><input type="checkbox" onchange="toggleCheckbox(this)" id="5" " + outputState(5) + "><span class="slider"></span></label>";
    buttons += "<h4>Output - GPIO 4</h4><label class="switch"><input type="checkbox" onchange="toggleCheckbox(this)" id="4" " + outputState(4) + "><span class="slider"></span></label>";
    buttons += "<h4>Output - GPIO 2</h4><label class="switch"><input type="checkbox" onchange="toggleCheckbox(this)" id="2" " + outputState(2) + "><span class="slider"></span></label>";
    return buttons;
  }
  return String();
}

Vous pouvez facilement supprimer ou ajouter plus de lignes pour créer plus de boutons.

Voyons comment les boutons sont créés. Nous créons une variable String appelée boutons qui contient le texte HTML pour construire les boutons. Nous concaténons le texte HTML avec l’état de sortie actuel afin que le bouton bascule soit gris ou rouge. L’état actuel de la sortie est renvoyé par le état de sortie() fonction (elle accepte comme argument le numéro GPIO). Voir ci-dessous:

buttons += "<h4>Output - GPIO 2</h4><label class="switch"><input type="checkbox" onchange="toggleCheckbox(this)" id="2" " + outputState(2) + "><span class="slider"></span></label>";

Le est utilisé pour que nous puissions passer «  » à l’intérieur de la chaîne.

le état de sortie () la fonction renvoie soit « vérifié » si le GPIO est sur ou et champ vide «  » si le GPIO est éteint.

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

Ainsi, le texte HTML pour GPIO 2 lorsqu’il est activé serait :

<h4>Output - GPIO 2</h4>
<label class="switch">
<input type="checkbox" onchange="toggleCheckbox(this)" id="2" checked><span class="slider"></span>
</label>

Décomposons cela en sections plus petites pour comprendre comment cela fonctionne.

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

<input type="checkbox">

La case peut être cochée ou non. Quand il est coché, vous avez quelque chose comme suit :

<input type="checkbox" checked>

le sur le changement est un attribut d’événement qui se produit lorsque nous modifions la valeur de l’élément (la case à cocher). Chaque fois que vous cochez ou décochez l’interrupteur à bascule, il appelle le toggleCheckbox() Fonction JavaScript pour cet identifiant d’élément spécifique (cette).

le identifiant spécifie un identifiant unique pour cet élément HTML. L’id nous permet de manipuler l’élément en utilisant JavaScript ou CSS.

<input type="checkbox" onchange="toggleCheckbox(this)" id="2" checked>

mettre en place()

Dans le mettre en place() initialiser le moniteur série à des fins de débogage.

Serial.begin(115200);

Définissez les GPIO que vous souhaitez contrôler en tant que sorties à l’aide du PinMode() fonction et réglez-les sur LOW lorsque l’ESP8266 démarre pour la première fois. Si vous avez ajouté plus de GPIO, procédez de la même manière.

pinMode(2, OUTPUT);
pinMode(5, OUTPUT);
digitalWrite(5, LOW);
pinMode(4, OUTPUT);
digitalWrite(4, LOW);
pinMode(2, OUTPUT);
digitalWrite(2, LOW);

Connectez-vous à votre réseau local et imprimez l’adresse IP ESP8266.

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());

Dans le mettre en place(), vous devez gérer ce qui se passe lorsque l’ESP8266 reçoit des requêtes. Comme nous l’avons vu précédemment, vous recevez une requête de ce type :

<ESP_IP>/update?output=<inputMessage1>&state=<inputMessage2>

Ainsi, nous vérifions si la demande contient le PARAM_INPUT1 valeur variable (sortir) et le PARAM_INPUT2(Etat) et enregistrez les valeurs correspondantes sur le input1Message et input2Message variables.

if (request->hasParam(PARAM_INPUT_1) && request->hasParam(PARAM_INPUT_2)) {
  inputMessage1 = request->getParam(PARAM_INPUT_1)->value();
  inputMessage2 = request->getParam(PARAM_INPUT_2)->value();

Ensuite, nous contrôlons le GPIO correspondant avec l’état correspondant (le inputMessage1 variable enregistre le numéro GPIO et le inputMessage2 enregistre l’état – 0 ou 1)

digitalWrite(inputMessage1.toInt(), inputMessage2.toInt());

Voici le code complet pour gérer le HTTP GET /mettre à jour demande:

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

Enfin, démarrez le serveur :

server.begin();

Manifestation

Après avoir téléchargé le code sur votre ESP8266, ouvrez le moniteur série à un débit en bauds de 115200. Appuyez sur le bouton RST/EN intégré. Vous devriez obtenir son adresse IP.

Ouvrez un navigateur et saisissez l’adresse IP ESP. Vous aurez accès à une page Web similaire.

Boutons de commutation du navigateur Web du serveur Web asynchrone ESP8266 NodeMCU

Appuyez sur les boutons à bascule pour contrôler les ESP GPIO. En même temps, vous devriez recevoir les messages suivants dans le moniteur série pour vous aider à déboguer votre code.

Serveur Web asynchrone ESP8266 NodeMCU Moniteur série Arduino IDE

Vous pouvez également accéder au serveur Web à partir d’un navigateur sur votre smartphone. Chaque fois que vous ouvrez le serveur Web, il affiche les états GPIO actuels. Le rouge indique que le GPIO est activé et le gris que le GPIO est désactivé.

ESP8266 NodeMCU Async Web Server Boutons de commutation de navigateur Web Mobile Responsive

Conclusion

Dans ce didacticiel, vous avez appris à créer un serveur Web asynchrone avec le NodeMCU ESP8266 pour contrôler ses sorties à l’aide d’interrupteurs à bascule. Chaque fois que vous ouvrez la page Web, elle affiche les états GPIO mis à jour.

Nous avons d’autres exemples de serveur Web utilisant la bibliothèque ESPAsyncWebServer qui pourraient vous plaire :

Nous espérons que vous avez trouvé ce tutoriel utile. Si vous avez des questions, postez un commentaire ci-dessous et nous essaierons de vous répondre.

Si vous aimez l’ESP8266, vous pouvez envisager de vous inscrire à notre eBook « La domotique avec l’ESP8266 ». Vous pouvez également accéder à nos ressources ESP8266 gratuites ici.

Merci pour la lecture.