Contrôler un circuit LED WS2812 avec une carte ESP12
Effet attendu
Je rappelle que je ne suis pas cameraman 🥲
Matériel utilisé
Pour les besoins de ce tutoriel, je me suis équipé des éléments suivants :
- Un anneau LED WS2812 de 24 diodes ;
- Une carte ESP32 ;
- Une plaque de prototypage (breadboard) pour le montage électronique ;
- Un ordinateur avec le logiciel Arduino installé ;
- Un câble USB pour relier l'ESP32 à l'ordinateur.
Prise en charge de l'ESP32 sur Arduino
Afin de programmer notre ESP32 avec Arduino, il faut ajouter le support correspondant à votre carte.
Il existe des centaines de modèles de carte ESP32. La procédure peut varier d'une carte à l'autre.
Je vous recommande donc de consulter la documentation de votre carte lorsqu'elle existe.
De manière générale, il faut :
- lancer l'application Arduino sur votre ordinateur ;
- se rendre dans le menu
Outils
>Type de carte
>Gestionnaire de cartes
; - rechercher
ESP32
dans la barre de recherche puis sélectionnerInstaller
sur la bibliothèque (ne pas confondre avecArduino ESP32
).

Une fois la bibliothèque installée, retournez dans le menu Outils
> Type de carte
afin de sélectionner le modèle correspondant.
Par exemple, pour la carte AZ-Delivery ESP32-WROOM, le manuel indique de choisir ESP32 Dev Module
.
Installation de la bibliothèque Adafruit NeoPixel
Dans cet article, pour piloter notre circuit LED, je vous propose d'utiliser la bibliothèque Adafruit NeoPixel.
Sans cette bibliothèque, le message d'erreur suivant apparaîtra à la compilation des projets :
Pour cela :
- lancez le logiciel Arduino ;
- sélectionnez
Outils
>Gérer les bibliothèques
; - recherchez
NeoPixel
; - cliquez sur
Installer
.

Montage électronique
Pour le montage, je vais utiliser la plaque de prototypage sur laquelle je vais venir poser mon ESP32.
Étant donné que mon circuit LED a besoin d'être alimenté en 5V et devrait consommer assez peu de courant, je vais utiliser la sortie 5V
fournie par la carte.
Pour d'autres besoins (voltage différent ou consommation supérieure), je vous invite à utiliser une source d’énergie extérieure pour l'alimentation de votre circuit LED tout en reliant les masses de chaque circuit entre elles.
Voici le montage à réaliser :
- Le
GND (0V)
du circuit LED sur un desGND
de l'ESP32 ; - Le
5V (VCC)
du circuit LED sur la sortie5V
de l'ESP32 ; - L'entrée
DI
(pour Data Input) sur une des sorties de l'ESP32. Il est conseillé d'ajouter une résistance en série afin de limiter les pics de tension et protéger les LED. Souvenez-vous du numéro de la broche pour le code. - Enfin, il est recommandé de placer un condensateur monté en parallèle entre les broches
5V
etGND
, au plus près du circuit LED afin de stabiliser la tension et répondre aux pics de consommation.
La valeur de la résistance devrait être comprise entre 330 et 470Ω pour un circuit classique. Plus le câble séparant la sortie de l'ESP32 et l'entrée
DI
sera long, plus elle devrait être élevée.
La valeur du condensateur dépendra du nombre de LED. Pour les circuits jusqu'à 60 LED, 1000 µF devraient être suffisants. Pour 300 LED, il faudrait envisager un condensateur de 4700 µF. Il est préférable de surdimensionner que l'inverse. La tension nominale du condensateur doit être supérieure à la tension du circuit LED.

Si vous souhaitez dupliquer l'affichage sur plusieurs circuits, il est possible de connecter les deux entrées
DI
ensemble. Prenez alors garde à l'alimentation.
Il est également possible de chaîner les circuits si ceux-ci sont équipés d'une sortieDO
(pour Data Output). Cela créera virtuellement un circuit LED plus grand. Il faudra alors relier leDI
(entrée) du deuxième circuit LED sur leDO
(sortie) du premier circuit. Faites là encore attention à l'alimentation.
Présentation de la bibliothèque
La bibliothèque Adafruit_NeoPixel est très pratique pour contrôler les LED WS2812 en simplifiant leur utilisation.
Importer la bibliothèque NeoPixel
Pour importer la bibliothèque à notre projet, nous allons écrire :
(ino)1#include <Adafruit_NeoPixel.h>
Création de l'instance
Nous allons créer l'instance avec la commande suivante :
(ino)1Adafruit_NeoPixel ledStrip(24, 27, NEO_GRB + NEO_KHZ800); // Crée l'instance ledStrip avec 24 LED/pixels sur la sortie 27 du microcontrôleur. La communication se fera en GRB (Green, Red, Blue) à 800kHZ 2// Adafruit_NeoPixel <nom de l'instance>(<nombre de led>, <pin de contrôle>, <mode de couleur> + <fréquence>);
NEO_GRB
va définir l’ordre des couleurs attendu par le circuit LED. Cela pourrait aussi être NEO_RGB
, NEO_BRG
... Dans le cas d'une erreur, les couleurs s'afficheront mal.
NEO_KHZ800
va définir la fréquence de communication entre l'ESP32 et le circuit LED.
Initialisation de l'instance
Nous allons ensuite initialiser notre instance avec la fonction begin
. Cela ne doit être fait qu'une seule fois. Dans le cadre d'un projet Arduino, il est courant de le faire dans la fonction setup
:
(ino)1void setup() { 2 ledStrip.begin(); // Initialiser l'instance ledStrip 3}
Changer la couleur d'un pixel
Avant de pouvoir changer l'affichage d'un pixel, encore faut-il savoir définir une couleur.
Définir une couleur
Les couleurs peuvent être définies par leur code hexadécimal :
(ino)1uint32_t color = 0xFFFFFF; // Blanc
Ou en RGB avec la bibliothèque NeoPixel :
(ino)1uint32_t green = ledStrip.Color(0, 255, 0); // Définit la couleur verte en RGB (Red, Green, Blue) via l'instance ledStrip 2// uint32_t green = <nom de l'instance>.Color(<rouge>, <vert>, <bleu>);
Changer la couleur d'un pixel
Pour changer la couleur d'un pixel, il faut utiliser :
(ino)1ledStrip.setPixelColor(4, ledStrip.Color(255, 0, 0)); // Définit la future couleur du pixel 4 en rouge 2// <nom de l'instance>.setPixelColor(<adresse du pixel>, <couleur>); 3 4ledStrip.show(); // Applique le changement
Définir la couleur de plusieurs pixels à la fois
Pour changer la couleur de plusieurs pixels, il existe, depuis la version 1.18 de la bibliothèque, la fonction fill
:
(ino)1ledStrip.fill(0xFFFFFF); // Définit la future couleur de tous les pixels 2ledStrip.show(); // Applique les changements 3 4delay(2000); // Attends 2 secondes 5 6ledStrip.fill(0x0000FF, 1, 7); // Définit la future couleur des pixels 1 à 7 en bleu 7ledStrip.fill(0x00FF00, 1, 7); // Définit la future couleur des pixels 8 à 10 en vert 8ledStrip.show(); // Applique les changements 9 10delay(2000); // Attends 2 secondes
Définir la luminosité
Pour définir la luminosité de l'ensemble du circuit, il faut utiliser la fonction setBrightness
avec une valeur de 0 (éteint) à 255 (très lumineux) :
(ino)1ledStrip.setBrightness(200); 2// <nom de l'instance>.setBrightness(<intensité>);
Récupérer la couleur d'un pixel
Pour récupérer la couleur d'un circuit, nous pouvons utiliser la fonction getPixelColor
:
(ino)1uint32_t color = ledStrip.getPixelColor(24); 2// uint32_t color = <nom de l'instance>.getPixelColor(<adresse du pixel>);
Éteindre le circuit LED
Pour éteindre toutes les LED, nous pouvons utiliser la fonction clear
. Il faut néanmoins utiliser show
pour appliquer les changements :
(ino)1ledStrip.clear(); // Éteint toutes les LED 2ledStrip.show(); // Applique les changements
Code du projet de démonstration
Fichier : led.ino (ino)1#include <Adafruit_NeoPixel.h> 2 3#define WS2812_PIN 27 4#define WS2812_PIXELS_NUM 24 5 6Adafruit_NeoPixel ledStrip(WS2812_PIXELS_NUM, WS2812_PIN, NEO_GRB + NEO_KHZ800); 7 8uint32_t colors[] = { 9 0x002656, // Bleu 10 0xFFFFFF, // Blanc 11 0xCE1126 // Rouge 12}; 13 14void setup() { // Ce code sera exécuté une fois au lancement de l'ESP32 15 ledStrip.begin(); // Initialisation du circuit LED 16} 17 18void loop() { // Ce code s'exécutera en boucle après la fonction setup 19 20 // Allume tous les pixels les uns après les autres, des trois couleurs du tableau colors 21 for(int colorNum = 0; colorNum < (sizeof(colors) / sizeof(colors[0])); colorNum++) { // Pour chaque couleur 22 for(int pixelNum = 0; pixelNum < WS2812_PIXELS_NUM; pixelNum++) { // Et pour chaque pixel 23 ledStrip.setPixelColor(pixelNum, colors[colorNum]); // Définit la couleur du pixel sans l'appliquer 24 ledStrip.show(); // Applique les changements 25 delay(200); // Pause de 200 millisecondes 26 } 27 } 28 29 delay(2000); // Pause de 2 secondes avant le motif suivant 30 31 ledStrip.clear(); // Efface la bande 32}
Et voilà, nous sommes maintenant en mesure de créer nos propres animations et effets lumineux.
― Valentin LORTET