Ce tutoriel montre comment créer un serveur Web avec la carte ESP8266 NodeMCU qui affiche une page Web avec plusieurs curseurs. Les curseurs contrôlent le rapport cyclique de différents signaux PWM pour contrôler la luminosité de plusieurs LED. Au lieu de LED, vous pouvez utiliser ce projet pour contrôler des moteurs à courant continu ou d’autres actionneurs nécessitant un signal PWM. La communication entre les clients et l’ESP8266 se fait à l’aide du protocole WebSocket. De plus, chaque fois qu’il y a un changement, tous les clients mettent à jour leurs valeurs de curseur simultanément.

Vous pouvez également modifier le code présenté dans ce didacticiel pour ajouter des curseurs à vos projets afin de définir des valeurs de seuil ou toute autre valeur que vous devez utiliser dans votre code.
Pour ce projet, la carte ESP8266 sera programmée à l’aide du noyau Arduino. Vous pouvez soit utiliser l’IDE Arduino, VS Code avec PlatformIO, ou tout autre IDE approprié.
Pour mieux comprendre le fonctionnement de ce projet, nous vous conseillons de jeter un œil aux tutoriels suivants :
* Ce projet montre comment créer un serveur Web avec un curseur, mais il utilise des requêtes HTTP. Dans ce didacticiel, nous utiliserons le protocole WebSocket.
Nous avons un tutoriel similaire pour la carte ESP32 :
Aperçu du projet
L’image suivante montre la page Web que nous allons créer pour ce projet :

- La page Web contient trois cartes;
- Chaque carte a un paragraphe pour afficher le titre de la carte (Fader 1, Fader 2, Fader 3) ;
- Il y a un curseur de plage dans chaque carte que vous pouvez déplacer pour régler la luminosité de la LED correspondante ;
- Dans chaque carte, un autre paragraphe affiche la luminosité actuelle de la LED (en pourcentage) ;
- Lorsque vous définissez une nouvelle position pour le curseur, il met à jour tous les clients (si plusieurs onglets de navigateur Web sont ouverts (ou plusieurs appareils), ils sont mis à jour presque simultanément chaque fois qu’il y a un changement).
Comment ça fonctionne?
- L’ESP héberge un serveur Web qui affiche une page Web avec trois curseurs ;
- Lorsque vous définissez une nouvelle position pour un curseur, le client envoie le numéro et la valeur du curseur au serveur via le protocole WebSocket. Par exemple, si vous réglez le curseur numéro 3 sur la position numéro 40, il enverra ce message 3s40 au serveur.

- Le serveur (ESP) reçoit le numéro du curseur et la valeur correspondante et ajuste le rapport cyclique PWM en conséquence. De plus, il informe également tous les autres clients des nouvelles valeurs de curseur actuelles, ce qui nous permet d’avoir tous les clients mis à jour presque instantanément.

- L’ESP8266 émet le signal PWM avec le rapport cyclique correspondant pour contrôler la luminosité de la LED. Un rapport cyclique de 0 % signifie que la LED est complètement éteinte, un rapport cyclique de 50 % signifie que la LED est à moitié allumée et un rapport cyclique de 100 % signifie que la LED est allumée ;

- Chaque fois que vous ouvrez une nouvelle fenêtre de navigateur Web (c’est-à-dire lorsqu’un nouveau client se connecte), il enverra un message à l’ESP8266 (également via le protocole WebSocket) avec le message getValues. Lorsque l’ESP8266 reçoit ce message, il envoie les valeurs actuelles du curseur. De cette façon, chaque fois que vous ouvrez un nouvel onglet, il affiche toujours les valeurs actuelles et mises à jour.

Conditions préalables
Avant de poursuivre ce didacticiel, assurez-vous de vérifier toutes les conditions préalables suivantes.
1) Pièces requises
Pour suivre ce projet, vous avez besoin de :
Vous n’avez pas besoin de trois LED pour tester ce projet, vous pouvez simplement voir les résultats dans le moniteur série ou utiliser d’autres actionneurs nécessitant un signal PWM pour fonctionner.
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 !
2) Complément pour les cartes Arduino IDE et ESP8266
Nous allons programmer l’ESP8266 à l’aide de l’IDE Arduino. Donc, vous devez avoir installé le module complémentaire ESP8266. Suivez le tutoriel suivant si vous ne l’avez pas déjà fait :
Si vous souhaitez utiliser VS Code avec l’extension PlatformIO, suivez plutôt le tutoriel suivant pour apprendre à programmer l’ESP8266 :
3) Plugin de téléchargement de système de fichiers
Pour télécharger les fichiers HTML, CSS et JavaScript nécessaires à la construction de ce projet dans la mémoire flash ESP8266 (LittleFS), nous utiliserons un plugin pour Arduino IDE : LittleFS Filesystem Uploader. Suivez le tutoriel suivant pour installer le plugin filesystem uploader si vous ne l’avez pas déjà fait :
Si vous utilisez VS Code avec l’extension PlatformIO, lisez le didacticiel suivant pour savoir comment télécharger des fichiers sur le système de fichiers :
4) Bibliothèques
Pour compiler ce projet, vous devez installer les bibliothèques suivantes :
Vous pouvez installer la première bibliothèque à l’aide du gestionnaire de bibliothèque Arduino. Accédez à Esquisse > Inclure la bibliothèque > Gérer les bibliothèques et recherchez le nom de la bibliothèque.
Les bibliothèques ESPAsyncWebServer et ESPAsynTCP 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 aller dans Sketch> Inclure la bibliothèque> Ajouter une bibliothèque .zip et sélectionner les bibliothèques que vous venez de télécharger.
Installation de bibliothèques (VS Code + PlatformIO)
Si vous programmez l’ESP8266 à l’aide de PlatformIO, vous devez ajouter les lignes suivantes au fichier platformio.ini pour inclure les bibliothèques (changez également la vitesse du moniteur série sur 115200 et définissez le système de fichiers littleFS) :
monitor_speed = 115200
board_build.filesystem = littlefs
lib_deps = ESP Async WebServer
arduino-libraries/Arduino_JSON @ 0.1.0
Diagramme schématique
Câblez trois LED à l’ESP8266. Nous utilisons les GPIO 12 (D6), 13 (D7) et 14 (D5). Vous pouvez utiliser tout autre GPIO approprié.

Lecture recommandée : Référence de brochage ESP8266 : Quelles broches GPIO devez-vous utiliser ?
Organisation de vos fichiers
Pour garder le projet organisé et le rendre plus facile à comprendre, nous allons créer quatre fichiers pour construire le serveur Web :
- Esquisse Arduino qui gère le serveur Web ;
- index.html: pour définir le contenu de la page Web ;
- style.css: pour styliser la page Web ;
- script.js: pour programmer le comportement de la page Web – gérer ce qui se passe lorsque vous déplacez le curseur, envoyez, recevez et interprétez les messages reçus via le protocole WebSocket.

Vous devez enregistrer les fichiers HTML, CSS et JavaScript dans un dossier appelé data dans le dossier d’esquisse Arduino, comme indiqué dans le diagramme précédent. Nous allons télécharger ces fichiers sur le système de fichiers ESP8266 (LittleFS).
Vous pouvez télécharger tous les fichiers du projet :
Fichier HTML
Copiez ce qui suit dans le fichier index.html.
<!-- Complete project details: https://www.raspberryme.com/esp8266-nodemcu-web-server-websocket-sliders/ -->
<!DOCTYPE html>
<html>
<head>
<title>ESP IOT DASHBOARD</title>
<meta name="viewport" content="width=device-width, initial-scale=1">
<link rel="icon" type="image/png" href="https://www.raspberryme.com/esp8266-nodemcu-web-server-websocket-sliders/favicon.png">
<link rel="stylesheet" type="text/css" href="style.css">
</head>
<body>
<div class="topnav">
<h1>Multiple Sliders</h1>
</div>
<div class="content">
<div class="card-grid">
<div class="card">
<p class="card-title">Fader 1</p>
<p class="switch">
<input type="range" onchange="updateSliderPWM(this)" id="slider1" min="0" max="100" step="1" value ="0" class="slider">
</p>
<p class="state">Brightness: <span id="sliderValue1"></span> %</p>
</div>
<div class="card">
<p class="card-title"> Fader 2</p>
<p class="switch">
<input type="range" onchange="updateSliderPWM(this)" id="slider2" min="0" max="100" step="1" value ="0" class="slider">
</p>
<p class="state">Brightness: <span id="sliderValue2"></span> %</p>
</div>
<div class="card">
<p class="card-title"> Fader 3</p>
<p class="switch">
<input type="range" onchange="updateSliderPWM(this)" id="slider3" min="0" max="100" step="1" value ="0" class="slider">
</p>
<p class="state">Brightness: <span id="sliderValue3"></span> %</p>
</div>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
Examinons rapidement les parties les plus pertinentes du fichier HTML.
Création d’un curseur
Les balises suivantes créent la carte pour le premier curseur (Fader 1).
<div class="card">
<p class="card-title">Fader 1</p>
<p class="switch">
<input type="range" onchange="updateSliderPWM(this)" id="slider1" min="0" max="100" step="1" value ="0" class="slider">
</p>
<p class="state">Brightness: <span id="sliderValue1"></span> %</p>
</div>
Le premier paragraphe affiche un titre pour la carte (Fader 1). Vous pouvez changer le texte en celui que vous vouliez.
<p class="card-title">Fader 1</p>
Pour créer un curseur en HTML, vous utilisez la balise . La balise spécifie un champ dans lequel l’utilisateur peut saisir des données.
Il existe une grande variété de types d’entrées. Pour définir un curseur, utilisez l’attribut type avec la valeur de plage. Dans un curseur, vous devez également définir la plage minimale et maximale à l’aide des attributs min et max (dans ce cas, 0 et 100, respectivement).
Vous devez également définir d’autres attributs tels que :
- l’attribut step spécifie l’intervalle entre les nombres valides. Dans notre cas, nous l’avons défini sur 1 ;
- la classe pour styliser le slider (class= »slider »);
- l’identifiant afin que nous puissions manipuler la valeur du curseur à l’aide de JavaScript (id = « slider1 » );
- l’attribut onchange pour appeler une fonction (updateSliderPWM(this)) lorsque vous définissez une nouvelle position pour le curseur. Cette fonction (définie dans le fichier JavaScript) envoie la valeur actuelle du curseur via le protocole WebSocket au client. Le mot-clé this fait référence à l’élément HTML slider.
Le curseur se trouve à l’intérieur d’un paragraphe avec le nom de la classe de commutateur. Voici donc les balises qui créent réellement le curseur.
<p class="switch">
<input type="range" onchange="updateSliderPWM(this)" id="slider1" min="0" max="100" step="1" value ="0" class="slider">
</p>
Enfin, il y a un paragraphe avec une balise , afin que nous puissions insérer la valeur actuelle du curseur dans ce paragraphe en faisant référence à son identifiant (id=”sliderValue1″).
<p class="state">Brightness: <span id="sliderValue1"></span> %</p>
Créer plus de curseurs
Pour créer plus de curseurs, vous devez copier toutes les balises HTML qui créent la carte complète. Cependant, vous devez d’abord considérer que vous avez besoin d’un identifiant unique pour chaque curseur et valeur de curseur. Dans notre cas, nous avons trois curseurs avec les identifiants suivants : slider1, slider2, slider3 et trois espaces réservés pour la valeur du curseur avec les identifiants suivants : sliderValue1, sliderValue2, sliderValue3.
Par exemple, voici la carte pour le curseur numéro 2.
<div class="card">
<p class="card-title"> Fader 2</p>
<p class="switch">
<input type="range" onchange="updateSliderPWM(this)" id="slider2" min="0" max="100" step="1" value ="0" class="slider">
</p>
<p class="state">Brightness: <span id="sliderValue2"></span> %</p>
</div>
Fichier CSS
Copiez ce qui suit dans le fichier style.css.
/* Complete project details: https://www.raspberryme.com/esp8266-nodemcu-web-server-websocket-sliders/ */
html {
font-family: Arial, Helvetica, sans-serif;
display: inline-block;
text-align: center;
}
h1 {
font-size: 1.8rem;
color: white;
}
p {
font-size: 1.4rem;
}
.topnav {
overflow: hidden;
background-color: #0A1128;
}
body {
margin: 0;
}
.content {
padding: 30px;
}
.card-grid {
max-width: 700px;
margin: 0 auto;
display: grid;
grid-gap: 2rem;
grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
}
.card {
background-color: white;
box-shadow: 2px 2px 12px 1px rgba(140,140,140,.5);
}
.card-title {
font-size: 1.2rem;
font-weight: bold;
color: #034078
}
.state {
font-size: 1.2rem;
color:#1282A2;
}
.slider {
-webkit-appearance: none;
margin: 0 auto;
width: 100%;
height: 15px;
border-radius: 10px;
background: #FFD65C;
outline: none;
}
.slider::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 30px;
height: 30px;
border-radius: 50%;
background: #034078;
cursor: pointer;
}
.slider::-moz-range-thumb {
width: 30px;
height: 30px;
border-radius: 50% ;
background: #034078;
cursor: pointer;
}
.switch {
padding-left: 5%;
padding-right: 5%;
}
Jetons un coup d’œil aux parties pertinentes du fichier CSS qui stylisent le curseur. Dans cet exemple, nous devons utiliser les préfixes du fournisseur pour l’attribut d’apparence.
.slider {
-webkit-appearance: none;
margin: 0 auto;
width: 100%;
height: 15px;
border-radius: 10px;
background: #FFD65C;
outline: none;
}
.slider::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 30px;
height: 30px;
border-radius: 50%;
background: #034078;
cursor: pointer;
}
.slider::-moz-range-thumb {
width: 30px;
height: 30px;
border-radius: 50% ;
background: #034078;
cursor: pointer;
}
.switch {
padding-left: 5%;
padding-right: 5%;
}
Préfixes de fournisseur
Les préfixes de fournisseur permettent à un navigateur de prendre en charge de nouvelles fonctionnalités CSS avant qu’elles ne soient entièrement prises en charge. Les navigateurs les plus couramment utilisés utilisent les préfixes suivants :
- -webkit- Chrome, Safari, les nouvelles versions d’Opera, presque tous les navigateurs iOS,
- -moz-Firefox,
- -o- Anciennes versions d’Opera,
- -ms- Microsoft Edge et Internet Explorer.
Les préfixes de fournisseur sont temporaires. Une fois que les propriétés sont entièrement prises en charge par le navigateur que vous utilisez, vous n’en avez plus besoin. Vous pouvez utiliser la référence suivante pour vérifier si la propriété que vous utilisez nécessite des préfixes : http://shouldiprefix.com/
Jetons un coup d’œil au sélecteur .slider (style le curseur lui-même):
.slider {
-webkit-appearance: none;
margin: 0 auto;
width: 100%;
height: 15px;
border-radius: 10px;
background: #FFD65C;outline: none;
}
La définition de -webkit-appearance sur none remplace les styles CSS par défaut appliqués au curseur dans les navigateurs Google Chrome, Safari et Android.
-webkit-appearance: none;
Définir la marge sur 0 auto aligne le curseur à l’intérieur de son conteneur parent.
margin: 0 auto;
La largeur du curseur est définie sur 100 % et la hauteur sur 15 px. Le rayon de bordure est défini sur 10 pixels.
margin: 0 auto;
width: 100%;
height: 15px;
border-radius: 10px;
Définissez la couleur d’arrière-plan du curseur et définissez le contour sur aucun.
background: #FFD65C;
outline: none;
Ensuite, formatez la poignée du curseur. Utilisez -webkit- pour les navigateurs Web Chrome, Opera, Safari et Edge et -moz- pour Firefox.
.slider::-webkit-slider-thumb {
-webkit-appearance: none;
appearance: none;
width: 30px;
height: 30px;
border-radius: 50%;
background: #034078;
cursor: pointer;
}
.slider::-moz-range-thumb {
width: 30px;
height: 30px;
border-radius: 50% ;
background: #034078;
cursor: pointer;
}
Définissez les propriétés -webkit-appearance et d’apparence sur none pour remplacer les propriétés par défaut.
-webkit-appearance: none;
appearance: none;
Définissez une largeur, une hauteur et un rayon de bordure spécifiques pour le gestionnaire. Définir la même largeur et la même hauteur avec un rayon de bordure de 50 % crée un cercle.
width: 30px;
height: 30px;
border-radius: 50%;
Ensuite, définissez une couleur pour l’arrière-plan et définissez le curseur sur un pointeur.
background: #034078;
cursor: pointer;
N’hésitez pas à jouer avec les propriétés du curseur pour lui donner un aspect différent.
Fichier JavaScript
Copiez ce qui suit dans le fichier script.js.
// Complete project details: https://www.raspberryme.com/esp8266-nodemcu-web-server-websocket-sliders/
var gateway = `ws://${window.location.hostname}/ws`;
var websocket;
window.addEventListener('load', onload);
function onload(event) {
initWebSocket();
}
function getValues(){
websocket.send("getValues");
}
function initWebSocket() {
console.log('Trying to open a WebSocket connection…');
websocket = new WebSocket(gateway);
websocket.onopen = onOpen;
websocket.onclose = onClose;
websocket.onmessage = onMessage;
}
function onOpen(event) {
console.log('Connection opened');
getValues();
}
function onClose(event) {
console.log('Connection closed');
setTimeout(initWebSocket, 2000);
}
function updateSliderPWM(element) {
var sliderNumber = element.id.charAt(element.id.length-1);
var sliderValue = document.getElementById(element.id).value;
document.getElementById("sliderValue"+sliderNumber).innerHTML = sliderValue;
console.log(sliderValue);
websocket.send(sliderNumber+"s"+sliderValue.toString());
}
function onMessage(event) {
console.log(event.data);
var myObj = JSON.parse(event.data);
var keys = Object.keys(myObj);
for (var i = 0; i < keys.length; i++){
var key = keys[i];
document.getElementById(key).innerHTML = myObj[key];
document.getElementById("slider"+ (i+1).toString()).value = myObj[key];
}
}
Voici une liste de ce que fait ce code :
- initialise une connexion WebSocket avec le serveur ;
- envoie un message au serveur pour obtenir les valeurs actuelles du curseur ;
- utilise la réponse pour mettre à jour les valeurs du curseur sur la page Web ;
- gère l’échange de données via le protocole WebSocket.
Jetons un coup d’œil à ce code JavaScript pour voir comment cela fonctionne.
La passerelle est le point d’entrée de l’interface WebSocket. window.location.hostname obtient l’adresse de la page actuelle (l’adresse IP du serveur Web).
var gateway = ws://${window.location.hostname}/ws;
Créez une nouvelle variable globale appelée websocket.
var websocket;
Ajoutez un écouteur d’événement qui appellera la fonction onload lors du chargement de la page Web.
window.addEventListener('load', onload);
La fonction onload() appelle la fonction initWebSocket() pour initialiser une connexion WebSocket avec le serveur.
function onload(event) {
initWebSocket();
}
La fonction initWebSocket() initialise une connexion WebSocket sur la passerelle définie précédemment. Nous attribuons également plusieurs fonctions de rappel lorsque la connexion WebSocket est ouverte, fermée ou lorsqu’un message est reçu.
function initWebSocket() {
console.log('Trying to open a WebSocket connection…');
websocket = new WebSocket(gateway);
websocket.onopen = onOpen;
websocket.onclose = onClose;
websocket.onmessage = onMessage;
}
Notez que lorsque la connexion websocket est ouverte, nous appellerons la fonction getValues.
function onOpen(event) {
console.log('Connection opened');
getValues();
}
La fonction getValues() envoie un message au serveur getValues pour obtenir la valeur actuelle de tous les curseurs. Ensuite, nous devons gérer ce qui se passe lorsque nous recevons ce message côté serveur (ESP8266).
function getStates(){
websocket.send("getValues");
}
Nous traitons les messages reçus via le protocole websocket sur la fonction onMessage().
function onMessage(event) {
console.log(event.data);
var myObj = JSON.parse(event.data);
var keys = Object.keys(myObj);
for (var i = 0; i < keys.length; i++){
var key = keys[i];
document.getElementById(key).innerHTML = myObj[key];
document.getElementById("slider"+ (i+1).toString()).value = myObj[key];
}
}
Le serveur envoie les états au format JSON, par exemple :
{
sliderValue1: 20;
sliderValue2: 50;
sliderValue3: 0;
}
La fonction onMessage() parcourt simplement toutes les valeurs et les place aux endroits correspondants sur la page HTML.
La fonction updateSliderPWM() s’exécute lorsque vous déplacez les curseurs.
function updateSliderPWM(element) {
var sliderNumber = element.id.charAt(element.id.length-1);
var sliderValue = document.getElementById(element.id).value;
document.getElementById("sliderValue"+sliderNumber).innerHTML = sliderValue;
console.log(sliderValue);
websocket.send(sliderNumber+"s"+sliderValue.toString());
}
Cette fonction obtient la valeur du curseur et met à jour le paragraphe correspondant avec la bonne valeur. Cette fonction envoie également un message au serveur afin que l’ESP8266 mette à jour la luminosité des LED.
websocket.send(sliderNumber+"s"+sliderValue.toString());
Le message est envoyé au format suivant :
Par exemple, si vous déplacez le curseur numéro 3 en position 40, il enverra le message suivant :
3s40
Esquisse Arduino
Copiez le code suivant dans votre IDE Arduino ou dans le fichier main.cpp si vous utilisez PlatformIO.
/*
Rui Santos
Complete project details at https://Raspberryme.com/esp8266-nodemcu-web-server-websocket-sliders/
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.
*/
#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include "LittleFS.h"
#include <Arduino_JSON.h>
// Replace with your network credentials
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
// Create AsyncWebServer object on port 80
AsyncWebServer server(80);
// Create a WebSocket object
AsyncWebSocket ws("/ws");
// Set LED GPIO
const int ledPin1 = 14;
const int ledPin2 = 12;
const int ledPin3 = 13;
String message = "";
String sliderValue1 = "0";
String sliderValue2 = "0";
String sliderValue3 = "0";
int dutyCycle1;
int dutyCycle2;
int dutyCycle3;
//Json Variable to Hold Slider Values
JSONVar sliderValues;
//Get Slider Values
String getSliderValues(){
sliderValues["sliderValue1"] = String(sliderValue1);
sliderValues["sliderValue2"] = String(sliderValue2);
sliderValues["sliderValue3"] = String(sliderValue3);
String jsonString = JSON.stringify(sliderValues);
return jsonString;
}
// Initialize LittleFS
void initFS() {
if (!LittleFS.begin()) {
Serial.println("An error has occurred while mounting LittleFS");
}
else{
Serial.println("LittleFS mounted successfully");
}
}
// Initialize WiFi
void initWiFi() {
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
Serial.print("Connecting to WiFi ..");
while (WiFi.status() != WL_CONNECTED) {
Serial.print('.');
delay(1000);
}
Serial.println(WiFi.localIP());
}
void notifyClients(String sliderValues) {
ws.textAll(sliderValues);
}
void handleWebSocketMessage(void *arg, uint8_t *data, size_t len) {
AwsFrameInfo *info = (AwsFrameInfo*)arg;
if (info->final && info->index == 0 && info->len == len && info->opcode == WS_TEXT) {
data[len] = 0;
message = (char*)data;
if (message.indexOf("1s") >= 0) {
sliderValue1 = message.substring(2);
dutyCycle1 = map(sliderValue1.toInt(), 0, 100, 0, 1023);
Serial.println(dutyCycle1);
Serial.print(getSliderValues());
notifyClients(getSliderValues());
}
if (message.indexOf("2s") >= 0) {
sliderValue2 = message.substring(2);
dutyCycle2 = map(sliderValue2.toInt(), 0, 100, 0, 1023);
Serial.println(dutyCycle2);
Serial.print(getSliderValues());
notifyClients(getSliderValues());
}
if (message.indexOf("3s") >= 0) {
sliderValue3 = message.substring(2);
dutyCycle3 = map(sliderValue3.toInt(), 0, 100, 0, 1023);
Serial.println(dutyCycle3);
Serial.print(getSliderValues());
notifyClients(getSliderValues());
}
if (strcmp((char*)data, "getValues") == 0) {
notifyClients(getSliderValues());
}
}
}
void onEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len) {
switch (type) {
case WS_EVT_CONNECT:
Serial.printf("WebSocket client #%u connected from %s\n", client->id(), client->remoteIP().toString().c_str());
break;
case WS_EVT_DISCONNECT:
Serial.printf("WebSocket client #%u disconnected\n", client->id());
break;
case WS_EVT_DATA:
handleWebSocketMessage(arg, data, len);
break;
case WS_EVT_PONG:
case WS_EVT_ERROR:
break;
}
}
void initWebSocket() {
ws.onEvent(onEvent);
server.addHandler(&ws);
}
void setup() {
Serial.begin(115200);
pinMode(ledPin1, OUTPUT);
pinMode(ledPin2, OUTPUT);
pinMode(ledPin3, OUTPUT);
initFS();
initWiFi();
initWebSocket();
// Web Server Root URL
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
request->send(LittleFS, "/index.html", "text/html");
});
server.serveStatic("/", LittleFS, "/");
// Start server
server.begin();
}
void loop() {
analogWrite(ledPin1, dutyCycle1);
analogWrite(ledPin2, dutyCycle2);
analogWrite(ledPin3, dutyCycle3);
ws.cleanupClients();
}
Comment fonctionne le code
Jetons un coup d’œil aux parties pertinentes pour ce projet. Pour mieux comprendre le fonctionnement du code, nous vous conseillons de suivre ce tutoriel sur le protocole WebSocket avec l’ESP8266 et ce tutoriel sur le PWM avec l’ESP8266.
Insérez vos identifiants réseau dans les variables suivantes pour connecter l’ESP8266 à votre réseau local :
const char* ssid = "REPLACE_WITH_YOUR_SSID";
const char* password = "REPLACE_WITH_YOUR_PASSWORD";
La fonction getSliderValues() crée une chaîne JSON avec les valeurs de curseur actuelles.
String getSliderValues(){
sliderValues["sliderValue1"] = String(sliderValue1);
sliderValues["sliderValue2"] = String(sliderValue2);
sliderValues["sliderValue3"] = String(sliderValue3);
String jsonString = JSON.stringify(sliderValues);
return jsonString;
}
La fonction notifyClients() notifie tous les clients avec les valeurs de curseur actuelles. L’appel de cette fonction nous permet de notifier les changements dans tous les clients chaque fois que vous définissez une nouvelle position pour un curseur.
void notifyClients(String sliderValues) {
ws.textAll(sliderValues);
}
Le handleWebSocketMessage(), comme son nom l’indique, gère ce qui se passe lorsque le serveur reçoit un message du client via le protocole WebSocket. Nous avons vu dans le fichier JavaScript, que le serveur peut recevoir le message getValues ou un message avec le numéro du curseur et la valeur du curseur.
Lorsqu’il reçoit le message getValues, il envoie les valeurs actuelles du curseur.
if (strcmp((char*)data, "getValues") == 0) {
notifyClients(getSliderValues());
}
S’il reçoit un autre message, nous vérifions à quel curseur correspond le message et mettons à jour la valeur du rapport cyclique correspondant. Enfin, nous informons tous les clients qu’un changement s’est produit. Voici un exemple pour le curseur 1 :
if (message.indexOf("1s") >= 0) {
sliderValue1 = message.substring(2);
dutyCycle1 = map(sliderValue1.toInt(), 0, 100, 0, 1023);
Serial.println(dutyCycle1);
Serial.print(getSliderValues());
notifyClients(getSliderValues());
}
Dans la boucle (), nous mettons à jour le rapport cyclique des canaux PWM pour ajuster la luminosité des LED.
void loop() {
analogWrite(ledPin1, dutyCycle1);
analogWrite(ledPin2, dutyCycle2);
analogWrite(ledPin3, dutyCycle3);
ws.cleanupClients();
}
Télécharger le code et les fichiers
Après avoir inséré vos informations d’identification réseau, enregistrez le code. Accédez à Sketch > Show Sketch Folder et créez un dossier appelé data.

Dans ce dossier, vous devez enregistrer les fichiers HTML, CSS et JavaScript.
Ensuite, téléchargez le code sur votre carte ESP8266. Assurez-vous d’avoir sélectionné la bonne carte et le bon port COM. Assurez-vous également d’avoir ajouté vos informations d’identification réseau.

Après avoir téléchargé le code, vous devez télécharger les fichiers. Accédez à Outils > ES8266 LittleFS Data Sketch Upload et attendez que les fichiers soient téléchargés.

Lorsque tout est téléchargé avec succès, ouvrez le moniteur série à un débit en bauds de 115200. Appuyez sur le bouton ESP8266 EN/RST, et il devrait imprimer l’adresse IP ESP8266.
Manifestation
Ouvrez un navigateur sur votre réseau local et collez l’adresse IP ESP8266. Vous devriez avoir accès à la page du serveur Web pour contrôler la luminosité des LED.

Déplacez les curseurs pour contrôler la luminosité des LED.

Ouvrez plusieurs onglets ou connectez-vous au serveur Web à l’aide d’un autre appareil, et notez que les valeurs du curseur sont mises à jour presque instantanément chaque fois qu’il y a un changement.
Vous pouvez regarder la vidéo de démonstration (la vidéo suivante montre une démonstration pour l’ESP32, mais cela fonctionne de manière similaire avec l’ESP8266) :
Conclusion
Dans ce didacticiel, vous avez appris à créer un serveur Web avec l’ESP8266 qui sert une page Web avec plusieurs curseurs. Les curseurs permettent de contrôler la luminosité des LED connectées à l’ESP8266. De plus, nous avons utilisé le protocole WebSocket pour communiquer entre l’ESP8266 et les clients.
Pour en savoir plus sur la création de serveurs Web avec les cartes ESP8266, nous vous recommandons vivement de consulter notre eBook :
En savoir plus sur l’ESP8266 avec nos ressources :
Merci pour la lecture.
Apprenez l’histoire de Raspberry Pi à travers cette vidéo :


