Piloter un ring led ws2812b avec input color serveur web esp32
Description :
Projet permettant de piloter un anneau de LED WS2812B via un input color sur une page Web hébergée par un ESP32, pour changer la couleur en temps réel.
L’utilisateur sélectionne une couleur sur le navigateur, et l’ESP32 reçoit la valeur pour ajuster instantanément l’animation ou la couleur du Ring LED, offrant un contrôle interactif et visuel des LEDs pour des projets IoT, domotique ou décoratifs.
Prérequis :
- 1 x Carte ESP32
- 1 x Anneau LED x12 RGB WS2812
- 1 x Breadboard
- Fils de connexion
Version IDE :
- Arduino IDE 2.3.5
Bibliothèque :
- LittleFS.h (Tuto dispo)
- ESPAsyncWebServer.h (version: 3.7.10 par ESP32Async)
- AsyncTCP.h (version 3.4.7 par ESP32Async)
- Adafruit_NeoPixel.h (version 1.15.1 par Adafruit)
Vidéo de démonstration :
Schéma de câblage :


Code :
Code Arduino :
#include "LittleFS.h"
#include <AsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include <WiFi.h>
#include <Adafruit_NeoPixel.h>
#define PIN 2
#define NUMPIXELS 12
const char *ssid = "......"; // "Votre Nom_du_routeur"
const char *password = "......"; // "Votre Mot_de_passe_du_routeur"
AsyncWebServer server(80);
Adafruit_NeoPixel pixels(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);
int i;
int ValeurR = 219;
int ValeurG = 51;
int ValeurB = 51;
String ValeurHex = "#db3333";
char msg[20];
void setup() {
Serial.begin(115200);
Serial.println();
Serial.print("Connecting to ");
Serial.println(ssid);
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.println("WiFi connected.");
Serial.println("IP address: ");
// Imprimer l'adresse IP locale ESP
Serial.println(WiFi.localIP());
if (!LittleFS.begin()) {
Serial.println("An Error has occurred while mounting LittleFS");
return;
}
server.on("/", HTTP_GET, [](AsyncWebServerRequest *request) {
request->send(LittleFS, "/index.html", "text/html");
});
server.on("/script.js", HTTP_GET, [](AsyncWebServerRequest *request) {
request->send(LittleFS, "/script.js", "text/javascript");
});
server.on("/write_ValeurR", HTTP_POST, [](AsyncWebServerRequest *request) {
if (request->hasParam("ValeurR", true)) {
String message;
message = request->getParam("ValeurR", true)->value();
ValeurR = message.toInt();
}
if (request->hasParam("ValeurG", true)) {
String message;
message = request->getParam("ValeurG", true)->value();
ValeurG = message.toInt();
}
if (request->hasParam("ValeurB", true)) {
String message;
message = request->getParam("ValeurB", true)->value();
ValeurB = message.toInt();
}
if (request->hasParam("ValeurHex", true)) {
String message;
message = request->getParam("ValeurHex", true)->value();
ValeurHex = message;
}
request->send(204);
});
server.on("/read_ValeurHex", HTTP_GET, [](AsyncWebServerRequest *request) {
String message = String(ValeurHex);
request->send(200, "text/plain", message);
});
// Démarrer le serveur
server.begin();
pixels.begin();
}
void loop() {
Serial.print("Valeur INPUT Color : RGB(");
Serial.print(ValeurR);
Serial.print(",");
Serial.print(ValeurG);
Serial.print(",");
Serial.print(ValeurB);
Serial.print(") ,");
Serial.println(ValeurHex);
//Animation Ring 1
if (i < NUMPIXELS - 1) {
i++;
} else {
i = 0;
}
int e = i - 2;
if (i == 0) { e = NUMPIXELS - 2; }
if (i == 1) { e = NUMPIXELS - 1; }
pixels.setPixelColor(e, pixels.Color(0, 0, 0));
pixels.setPixelColor(i, pixels.Color(ValeurR, ValeurG, ValeurB));
pixels.show();
delay(150);
}
Code HTML :
( index.html )
<!DOCTYPE html>
<html lang="fr">
<head>
<meta charset="UTF-8">
<title>Color Picker avec bouton</title>
<meta name="viewport" content="width=device-width, initial-scale=1" charset="UTF-8" />
<script type="text/javascript" src="https://webapps1.chicago.gov/cdn/jQuery-3.4.1/jquery-3.4.1.min.js"></script>
<style>
body {
font-family: Arial, sans-serif;
padding: 40px;
}
.picker-wrapper {
display: flex;
align-items: center;
gap: 20px;
}
input[type="color"] {
width: 120px;
height: 60px;
border: none;
background: none;
cursor: pointer;
}
#colorInfo {
font-size: 18px;
line-height: 1.6;
}
button {
padding: 10px 20px;
font-size: 16px;
cursor: pointer;
border: none;
border-radius: 6px;
background-color: #3498db;
color: #fff;
}
button:hover {
background-color: #2980b9;
}
</style>
</head>
<body>
<h2>Sélecteur de couleur ESP32</h2>
<div class="picker-wrapper">
<input type="color" id="colorPicker">
<button id="validateBtn">Valider</button>
<div id="colorInfo">
<div><strong>HEX :</strong> <span id="hexValue"></span></div>
<div><strong>RGB :</strong> <span id="rgbValue"></span></div>
</div>
</div>
<script src="script.js"></script>
</body>
</html>
Code Javascript :
( script.js )
const colorInput = document.getElementById("colorPicker");
const hexValue = document.getElementById("hexValue");
const rgbValue = document.getElementById("rgbValue");
const validateBtn = document.getElementById("validateBtn");
var ValeurR;
var ValeurG;
var ValeurB;
var ValeurHex;
function hexToRgb(hex) {
const r = parseInt(hex.substr(1, 2), 16);
const g = parseInt(hex.substr(3, 2), 16);
const b = parseInt(hex.substr(5, 2), 16);
ValeurR = r;
ValeurG = g;
ValeurB = b;
return `rgb(${r}, ${g}, ${b})`;
}
function updateColorDisplay(color) {
const rgb = hexToRgb(color);
hexValue.textContent = color;
rgbValue.textContent = rgb;
}
// Initial display
updateColorDisplay(colorInput.value);
$(document).ready(function () {
$("#validateBtn").click(function () {
updateColorDisplay(colorInput.value);
ValeurHex = colorInput.value;
$.post("write_ValeurR", {
ValeurR: ValeurR,
ValeurG: ValeurG,
ValeurB: ValeurB,
ValeurHex: ValeurHex
});
});
});
function getDataValeurHex() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function () {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("colorPicker").value = this.responseText;
}
updateColorDisplay(colorInput.value);
};
xhttp.open("GET", "read_ValeurHex", true);
xhttp.send();
};
getDataValeurHex();
