Ce projet montre comment contrôler les sorties d’un ESP32 ou ESP8266 à l’aide d’un serveur web et d’un bouton physique, simultanément.
L’état de la sortie est mis à jour sur la page web, qu’il soit modifié à l’aide du bouton physique ou directement depuis le serveur web
Présentation du projet
- L’état actuel de la sortie est affiché sur la page du serveur web.
- L’ESP32 ou l’ESP8266 est également connecté à un bouton-poussoir physique qui permet de contrôler cette même sortie.
- Si vous modifiez l’état de la sortie à l’aide du bouton-poussoir physique, son état actuel est également mis à jour sur la page du serveur web.
En résumé : ce projet permet de contrôler une même sortie simultanément à l’aide d’un serveur web et d’un bouton-poussoir physique. Chaque fois que l’état de la sortie change, la page web est mise à jour afin d’afficher son nouvel état.
Matériel nécessaire
Voici la liste des composants nécessaires pour réaliser le circuit :
Carte ESP32 DEVKIT V1
LED de 5 mm
Résistance de 220 Ω
Bouton-poussoir
Résistance de 10 kΩ
Plaque d’essai (breadboard)
Fils de connexion (jumpers)
Le schéma électrique du projet.
Installation des bibliothèques pour ESP32.
Pour réaliser ce serveur web, nous utilisons deux bibliothèques : ESPAsyncWebServer et AsyncTCP. Si vous avez déjà installé ces bibliothèques, vous pouvez passer à l’étape suivante.
1. Installer la bibliothèque ESPAsyncWebServer.
Suivez les étapes suivantes pour installer la bibliothèque ESPAsyncWebServer :
Cliquez sur le lien de téléchargement de la bibliothèque ESPAsyncWebServer. Vous obtiendrez un fichier compressé au format
.zipdans votre dossier Téléchargements.Décompressez le fichier ZIP. Vous obtiendrez un dossier nommé
ESPAsyncWebServer-master.Renommez ce dossier en
ESPAsyncWebServer.Déplacez le dossier dans le répertoire des bibliothèques de votre installation Arduino IDE.
Autre méthode : dans Arduino IDE, accédez au menu Croquis (Sketch) → Inclure une bibliothèque (Include Library) → Ajouter la bibliothèque .ZIP (Add .ZIP Library…), puis sélectionnez le fichier ZIP que vous avez téléchargé.
2. Installer la bibliothèque AsyncTCP pour ESP32.
La bibliothèque ESPAsyncWebServer nécessite également la bibliothèque AsyncTCP pour fonctionner avec l’ESP32.
Suivez les étapes suivantes :
Cliquez sur le lien de téléchargement de la bibliothèque AsyncTCP. Vous obtiendrez un fichier compressé au format
.zipdans votre dossier Téléchargements.Décompressez le fichier ZIP. Vous obtiendrez un dossier nommé
AsyncTCP-master.Renommez ce dossier en
AsyncTCP.Déplacez le dossier
AsyncTCPdans le répertoire des bibliothèques de votre installation Arduino IDE.Enfin, redémarrez Arduino IDE pour que les bibliothèques soient correctement prises en compte.
Autre méthode : dans Arduino IDE, accédez au menu Croquis → Inclure une bibliothèque → Ajouter la bibliothèque .ZIP, puis sélectionnez le fichier ZIP de la bibliothèque AsyncTCP.
Remarque : ces instructions concernent l’ESP32. Pour une carte ESP8266, la bibliothèque réseau correspondante est généralement ESPAsyncTCP, et non AsyncTCP.
CODE.
Nous allons programmer l’ESP32 à l’aide de l’Arduino IDE. Assurez-vous donc que le module complémentaire ESP32 est installé avant de poursuivre. Si vous avez déjà effectué cette étape, vous pouvez passer à la suivante.
Installation du module ESP32 dans Arduino IDE
Après avoir installé les bibliothèques nécessaires, ouvrez le fichier
Avant de téléverser le code sur votre carte ESP32, n’oubliez pas de renseigner vos identifiants Wi-Fi (nom du réseau et mot de passe) afin que l’ESP32 puisse se connecter à votre réseau local.
Fonctionnement du code
Le programme permet de contrôler une LED connectée à l’ESP32 à l’aide d’un serveur web et d’un bouton-poussoir physique. Les deux commandes agissent sur la même LED et son état est actualisé sur la page web.
La variable ledState mémorise l’état de la sortie de la LED. Par défaut, au démarrage du serveur web, sa valeur est LOW, ce qui signifie que la LED est éteinte.
Les variables buttonState et lastButtonState sont utilisées pour détecter si le bouton-poussoir a été appuyé ou non. Elles permettent de suivre l’état du bouton et de détecter un changement d’état afin de contrôler la LED.
Nous n’avons pas inclus le code HTML permettant de créer le bouton dans la variable index_html.
Cela s’explique par le fait que nous voulons pouvoir modifier ce bouton en fonction de l’état actuel de la LED, qui peut également être modifié à l’aide du bouton-poussoir.
Nous avons donc créé un espace réservé appelé %BUTTONPLACEHOLDER%. Celui-ci sera remplacé plus tard dans le code par du texte HTML permettant de créer le bouton. Cette opération est réalisée dans la fonction processor().
La fonction processor() remplace les espaces réservés présents dans le code HTML par leurs valeurs réelles.
Tout d’abord, elle vérifie si le texte HTML contient un espace réservé appelé %BUTTONPLACEHOLDER%.
if (var == "BUTTONPLACEHOLDER") {Ensuite, nous appelons la fonction outputState(), qui renvoie l’état actuel de la sortie. Nous enregistrons cette valeur dans la variable outputStateValue.
String outputStateValue = outputState();Après cela, nous utilisons cette valeur pour créer le code HTML permettant d’afficher le bouton avec l’état approprié :
buttons += "<h4>Sortie - GPIO 2 - État <span id=\"outputState\"></span></h4>"
"<label class=\"switch\"><input type=\"checkbox\" onchange=\"toggleCheckbox(this)\" id=\"output\" "
+ outputStateValue + "><span class=\"slider\"></span></label>";Requête HTTP GET pour modifier l’état de la sortie (JavaScript)
Lorsque vous appuyez sur le bouton, la fonction toggleCheckbox() est appelée. Cette fonction envoie une requête vers différentes URL afin d’allumer ou d’éteindre la LED.
function toggleCheckbox(element) {
var xhr = new XMLHttpRequest();
if (element.checked) {
xhr.open("GET", "/update?state=1", true);
} else {
xhr.open("GET", "/update?state=0", true);
}
xhr.send();
}Pour allumer la LED, une requête est envoyée à l’URL /update?state=1 :
if (element.checked) {
xhr.open("GET", "/update?state=1", true);
}Sinon, une requête est envoyée à l’URL /update?state=0 pour éteindre la LED.
Requête HTTP GET pour mettre à jour l’état (JavaScript)
Pour maintenir à jour l’état de la sortie sur le serveur Web, nous appelons la fonction suivante. Elle envoie une nouvelle requête à l’URL /state toutes les secondes.
setInterval(function () {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
var inputChecked;
var outputStateM;
if (this.responseText == 1) {
inputChecked = true;
outputStateM = "Allumée";
} else {
inputChecked = false;
outputStateM = "Éteinte";
}
document.getElementById("output").checked = inputChecked;
document.getElementById("outputState").innerHTML = outputStateM;
}
};
xhttp.open("GET", "/state", true);
xhttp.send();
}, 1000);Gestion des requêtes
Ensuite, nous devons définir ce qui se passe lorsque l’ESP32 ou l’ESP8266 reçoit des requêtes sur ces URL.
Lorsqu’une requête est reçue à l’adresse principale /, nous envoyons la page HTML ainsi que la fonction processor.
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) {
request->send_P(200, "text/html", index_html, processor);
});Les lignes suivantes vérifient si une requête a été reçue à l’adresse /update?state=1 ou /update?state=0, puis modifient la variable ledState en conséquence.
server.on("/update", HTTP_GET, [](AsyncWebServerRequest *request) {
String inputMessage;
String inputParam;
// Récupérer la valeur du paramètre input1
// depuis <ESP_IP>/update?state=<inputMessage>
if (request->hasParam(PARAM_INPUT_1)) {
inputMessage = request->getParam(PARAM_INPUT_1)->value();
inputParam = PARAM_INPUT_1;
digitalWrite(output, inputMessage.toInt());
ledState = !ledState;
} else {
inputMessage = "Aucun message envoyé";
inputParam = "none";
}
Serial.println(inputMessage);
request->send(200, "text/plain", "OK");
});Lorsqu’une requête est reçue à l’adresse /state, nous envoyons l’état actuel de la sortie :
server.on("/state", HTTP_GET, [](AsyncWebServerRequest *request) {
request->send(200, "text/plain",
String(digitalRead(output)).c_str());
});Fonction loop()
Dans la fonction loop(), nous éliminons les rebonds du bouton-poussoir (debouncing) et allumons ou éteignons la LED en fonction de la valeur de la variable ledState.
digitalWrite(output, ledState);



