Les Carnets de Byfeel domotique , Objets connectés , DIY , Programmation, Nouvelles Technologies ….
tuto neopixel Ring

Bibliothèque neopixel avec un esp8266

un article , pour expliquer comment utiliser la bibliothèque adafruit neopixel , pour contrôler des leds de type neopixel ( WS2812 ) . Ce sont des LED intégrés sur des microcontroleurs , permettant un affichage facile des couleurs . Pour illustrer cette article j’ai pris un Ring neopixel de 12 led , on en trouve de toutes les tailles ( 16 , 24 , 32 … ) ou sous la forme de bande ( strip ) ou encore sous d’autres formes.

Ci dessous un exemple de ce que vous pourrez obtenir comme effet.

tutu neopixel

Alimentation / Connection

Attention à l’alimentation ….

Les leds neopixels ont besoin de 20 milliAmperes pour fonctionner , selon le type de neopixel utilisés ( dans mon exemple GRB ) , il faudra 60 milliAmperes ( led bleu + led verte + led rouge ) 3 x 20 =60 pour afficher une lumière blanche. Pour un ring de 12 led , mon circuit peut demander jusqu’a 12 x 60 mA = 0,72 A amplement suffisant pour etre alimenté par mon module ESP.

Si vous avez besoin de contrôler plus de led , par exemple un bandeau de 60 led RGB peut consommer jusqu’a 3,6 A. Il faudra alors passer par une alimentation extérieur . et protéger vos led en ajoutant un condensateur entre le +5v et la masse.

Plus de détail sur la documentation ADAFRUIT suivante .

Pour la connection ….

Sur ces types de Led , on a en général 4 PIN ( +5V , GND , DI et DO ) . Le +5V et le GND sont facile à comprendre , ils seront reliés directement aux pin correspondant de votre eSP.

DI = Data In ( c’est l’entree des commandes ) , elle sera relié à une des PIN de l4ESP

DO = Data Out , permet de chainer vers un autre Neopixel ( relié à son DI ).

PIN Ring 12

Le programme

Un programme de base pour allumer des le démarrage les leds 2 à 4 , 7,8, 9 et 12 avec des couleurs différentes.


// bibliotheque adafruit neopixel
#include <Adafruit_NeoPixel.h>
// pin ou est branché la commande dataIn du ring
#define LED_PIN  D3
// Nombre de led
#define LED_COUNT  12
// NeoPixel luminosite, 0 (min) to 255 (max)
#define BRIGHTNESS 50
// Declare votre neopixel Ring
Adafruit_NeoPixel ring(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
// Argument 1 = Nombre de Pixel dans le Ring
// Argument 2 = Wemos Pin
// Argument 3 = Pixel type
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Led cablé selon GRB (most NeoPixel products)
//   NEO_GRBW    Led cablé selon GRB + W (most NeoPixel products) + Led blanche
//   NEO_RGB     Led cablé selon RGB (v1 FLORA pixels, not v2)
//   NEO_RGBW   led cablé selon  RGBW (NeoPixel RGBW products)
void setup() {
 ring.begin();           // INITIALIZE NeoPixel ring object (REQUIRED)
 ring.setBrightness(BRIGHTNESS); // Set BRIGHTNESS to about 1/5 (max = 255)
 ring.fill(ring.Color(0,0,255),1,3);   // allume la led 2,3 et 4  en bleu
 ring.setPixelColor(6, ring.Color(255,0,0));   // allume la led 7 en rouge
 ring.setPixelColor(7, ring.Color(255,255,255));   // allume la led 8 en blanc
 ring.setPixelColor(8, ring.Color(0,0,255));   // allume la led 9 en bleu
 ring.setPixelColor(11,ring.Color(0,255,0));   // allume la led 12 en vert
 ring.show();            // pour afficher les modifications
}
void loop() {
}

En détail :

include Adafruit_neopixel.h

Permet de charger la bibliothèque adafruit neopixel

// pin ou est branché la commande dataIn du ring
#define LED_PIN D3

// Nombre de led
#define LED_COUNT 12

// NeoPixel luminosite, 0 (min) to 255 (max)
#define BRIGHTNESS 50

Définition des constantes , LED_PIN numero PIN de l’arduino ou du module ESP . LED_COUNT , définit le nombre de led et BRIGHTNESS la luminosité ( de 0 à 255 ) .

// Declare votre neopixel Ring
Adafruit_NeoPixel ring(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
// Argument 1 = Nombre de Pixel dans le Ring
// Argument 2 = Wemos Pin
// Argument 3 = Pixel type
// NEO_KHZ800 800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
// NEO_KHZ400 400 KHz (classic ‘v1’ (not v2) FLORA pixels, WS2811 drivers)
// NEO_GRB Led cablé selon GRB (most NeoPixel products)
// NEO_GRBW Led cablé selon GRB + W (most NeoPixel products) + Led blanche
// NEO_RGB Led cablé selon RGB (v1 FLORA pixels, not v2)
// NEO_RGBW led cablé selon RGBW (NeoPixel RGBW products)

la commande Adafruit_NeoPixel ring(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800); permet d’initialiser l’objet ring , avec pour paramètre :

  • Argument 1 : LED_COUNT ( nombre de led ou pixel ) ici 12
  • Argument 2 : LED_PIN ( numero PIN ou est relié l’entrée Data In ) ici D3 sur mon WEMOS D1 R1 ( a adapter en fonction de votre carte )
  • Argument 3 : Composé de deux informations définissant le type de Led utilisé ou pixel , utilisez vous des led de type RGB ou RGB + W . Un mauvais choix dans cet argument , peut entrainer des fonctionnements aléatoires , pas la bonne couleur , pas la bonne place …. etc …. A verifier , lors de votre achat , ici j’utilise un ring de 12 pixel de type RGB ( mais codé en GRB , qui correspond à la plupart des différents ring ) . Ainsi que la fréquence du taux de rafraichissement ( en général pour les neopixels sous WS2812 – 800 KHZ)

ring.begin();

ring.begin() , permet de preparer l’objet ring ( obligatoire , pour que cela fonctionne , à placé dans le setup() ).

ring.setBrightness(BRIGHTNESS);

ring.setBrightness( valeur ) , permet de régler la luminosité ( optionnel )

ring.fill(ring.Color(0,0,255),5,3);

la fonction ring.fill(couleur,debut,nb) , permet d’allumer les led entre debut et les nb LEDs suivantes avec la couleur envoyé. Dans cet exemple les LEDs 5 a 8 sont allumés en bleu.

Si debut et nb , ne sont pas mentionné , ils sont remplacé par les valeurs par défaut ( 0 pour début ) et ( LED_COUNT-1 pour x).La totalité des LEDs seront concernés.

Pour allumer une seule led ,

ring.setPixelColor(2, ring.Color(0,0,255));

ring.setPixelColor(numero_led, ring.Color(R,V,B)); numero_id = numero de la led de 0 à 11 ( si 12 led ) et ring.color(r,v,b) définition de la couleur à afficher ou R = 0 à 255 ( canal rouge ) , V =0 à 255 ( canal vert ) et B ( 0 à 255 ) canal bleue.

ring.show();

ring.show() , permet d’afficher les modifications effectué. Sans cette fonction , aucune modification n’est visible.

Effet circulaire

le programme suivant , explique comment mettre en place deux effets circulaires.

  • Le premier : les leds s’allument au fur et a mesure en rouge puis en bleue avec une vitesse différente.
  • Le second : Une seule led s’allume en blanc et tourne autour du cercle ( deux fois ).

Le programme

// bibliotheque adafruit neopixel
#include <Adafruit_NeoPixel.h>
// pin ou est branché la commande dataIn du ring
#define LED_PIN  D3
// Nombre de led
#define LED_COUNT  12
// NeoPixel luminosite, 0 (min) to 255 (max)
#define BRIGHTNESS 30
// Declare votre neopixel Ring
Adafruit_NeoPixel ring(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
// Argument 1 = Nombre de Pixel dans le Ring
// Argument 2 = Wemos Pin
// Argument 3 = Pixel type
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Led cablé selon GRB (most NeoPixel products)
//   NEO_GRBW    Led cablé selon GRB + W (most NeoPixel products) + Led blanche
//   NEO_RGB     Led cablé selon RGB (v1 FLORA pixels, not v2)
//   NEO_RGBW   led cablé selon  RGBW (NeoPixel RGBW products)
// definition des couleurs
uint32_t Red=ring.Color(255,   0,   0);
uint32_t Blue=ring.Color(0,   0,   255);
uint32_t Green=ring.Color(0, 255,   0);
uint32_t Yellow=ring.Color(255, 255,   0);
uint32_t White=ring.Color(255, 255, 255);
// fonction qui allume les leds unes apres les autres de la même couleur
// arg 1 : couleur , arg 2 : Vitesse , arg 3 : une seule led allumé
void colorWipe(uint32_t color, int speed=50,bool single=false) {
  for(int i=0; i<ring.numPixels(); i++) {
    if (single) ring.clear();
    ring.setPixelColor(i, color);
    ring.show();
    delay(speed);
  }
}
void setup() {
ring.begin();           // INITIALIZE NeoPixel ring object (REQUIRED)
ring.setBrightness(BRIGHTNESS); // Set BRIGHTNESS to about 1/5 (max = 255)
ring.show();            // Turn OFF all pixels ASAP
}
void loop() {
  ring.clear();
  colorWipe(Red); // Red
  colorWipe(Blue, 100); // Green
  colorWipe(White,50,true);
  colorWipe(White,50,true);
}

Quoi de neuf ?

afin de s’organiser au mieux , j’ai choisi de définir les couleurs en amont

// definition des couleurs
uint32_t Red=ring.Color(255, 0, 0);

Ici je définis la valeur Red ( Rouge ) en positionnant le canal rouge au max 255 et les deux autres canaux à zero.

La fonction de circulation des leds ( ou chenillard ) – colorWipe()

// fonction qui allume les leds unes apres les autres de la même couleur
// arg 1 : couleur , arg 2 : Vitesse , arg 3 : une seule led allumé
void colorWipe(uint32_t color, int speed=50,bool single=false) {
  for(int i=0; i<ring.numPixels(); i++) {
    if (single) ring.clear();
    ring.setPixelColor(i, color);
    ring.show();
    delay(speed);
  }
}

Permet d’allumer les leds , les unes après les autres , selon Trois arguments :

Argument 1 : La couleur
Argument 2 : La vitesse
Argument 3 : Ne fait circuler qu’une led à la fois , ou les laisses allumer

la fonction ring.numpixel() : me donne le nombre de pixel et la fonction ring.clear() : permet d’effacer les leds allumés .

Et enfin la boucle led , répète sans cesse les différents appels aux fonctions

A vous de jouer …..

Bonus

Une fonction qui permet de faire varier la couleur , tout en tournant ( effet arc en ciel ) avec un effet de fondu entrant et sortant.

La fonction

void rainbow(int rainbowLoops,int F=100,int speed=3, int S=255) {
  int fadeVal=0, fadeMax;
  fadeMax=constrain(F, 1, 100);
  for(uint32_t firstPixelHue = 0; firstPixelHue < rainbowLoops*65536;
    firstPixelHue += 256) {
    for(int i=0; i<ring.numPixels(); i++) {
      uint32_t pixelHue = firstPixelHue + (i * 65536L / ring.numPixels());
      ring.setPixelColor(i, ring.gamma32(ring.ColorHSV(pixelHue, S,255* fadeVal / fadeMax )));
    }
    ring.show();
    delay(speed);
    if(firstPixelHue < 65536) {                              // Premiere boucle,
      if(fadeVal < fadeMax) fadeVal++;                       // fade in
    } else if(firstPixelHue >= ((rainbowLoops-1) * 65536)) { // Derniere boucle loop,
      if(fadeVal > 0) fadeVal--;                             // fade out
    } else {
      fadeVal = fadeMax; // boucle intermediaire fade=fademax
    }
  }
}

Dans cette fonction , on découvre deux nouvelles fonctionnalité.

  • ring.ColorHSV(H,S,V) : Qui permet de régler les couleurs en fonctions de la variable Hue ( teinte de la couleur de 0 à 65535 ) , Saturation ( S ) entre 0 et 255 et la luminosité ( V ) entre 0 et 255 . Si S et V sont omis , les valeurs max , sont appliqués par défaut.
  • ring.gamma32() permet d’utiliser ses valeurs « plus réaliste » de la couleur lorsque l’on travaille avec des changements de couleur plus nuancés, et que les choses peuvent paraître trop brillantes ou délavées. Ce n’est généralement pas un problème avec les couleurs primaires et secondaires simples, mais plutôt avec les mélanges, les transitions et les types de couleurs pastel que l’on peut obtenir avec la fonction ColorHSV. Numériquement, les valeurs de couleur sont correctes, mais nos yeux en font quelque chose de différent, c’est la qu’intervient la fonction gamma32 qui permet un rendu plus réel et d’utiliser la palette Hue.

Il est alors possible de définir une couleur plus précise sous la forme :

valeur de hue , en fonction de la teinte désirée

uint32_t Orange = ring.gamma32(ring.ColorHSV(5462, 255, 255));
uint32_t Violet = ring.gamma32(ring.ColorHSV(52000, 255, 255));
uint32_t Pink = ring.gamma32(ring.ColorHSV(60080));

Le programme complet , qui montre toutes les fonctionnalité.

// Tuto Ring Neopixel
// byfeel 2019
// bibliotheque adafruit neopixel
#include <Adafruit_NeoPixel.h>
// pin ou est branché la commande dataIn du ring
#define LED_PIN  D3
// Nombre de led
#define LED_COUNT  12
// NeoPixel luminosite, 0 (min) to 255 (max)
#define BRIGHTNESS 30
// Declare votre neopixel Ring
Adafruit_NeoPixel ring(LED_COUNT, LED_PIN, NEO_GRB + NEO_KHZ800);
// Argument 1 = Nombre de Pixel dans le Ring
// Argument 2 = Wemos Pin
// Argument 3 = Pixel type
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Led cablé selon GRB (most NeoPixel products)
//   NEO_GRBW    Led cablé selon GRB + W (most NeoPixel products) + Led blanche
//   NEO_RGB     Led cablé selon RGB (v1 FLORA pixels, not v2)
//   NEO_RGBW   led cablé selon  RGBW (NeoPixel RGBW products)
// definition des couleurs
uint32_t Red=ring.Color(255,   0,   0);
uint32_t Blue=ring.Color(0,   0,   255);
uint32_t Green=ring.Color(0, 255,   0);
uint32_t Yellow=ring.Color(255, 255,   0);
uint32_t White=ring.Color(255, 255, 255);
uint32_t Orange = ring.gamma32(ring.ColorHSV(5462, 255, 255));
uint32_t Violet = ring.gamma32(ring.ColorHSV(52000, 255, 255));
uint32_t Pink = ring.gamma32(ring.ColorHSV(60080));
// gonction qui allume les leds unes apres les autres de la même couleur
void colorWipe(uint32_t color, int speed=50,bool single=false,int loops=1) {
for (int j=0;j<loops;j++) {
  for(int i=0; i<ring.numPixels(); i++) {
    if (single) ring.clear();
    ring.setPixelColor(i, color);
    ring.show();
    delay(speed);
  }
}
}
void rainbow(int rainbowLoops,int F=100,int speed=3, int S=255) {
  int fadeVal=0, fadeMax;
  fadeMax=constrain(F, 1, 100);
  for(uint32_t firstPixelHue = 0; firstPixelHue < rainbowLoops*65536;
    firstPixelHue += 256) {
    for(int i=0; i<ring.numPixels(); i++) {
      uint32_t pixelHue = firstPixelHue + (i * 65536L / ring.numPixels());
      ring.setPixelColor(i, ring.gamma32(ring.ColorHSV(pixelHue, S,255* fadeVal / fadeMax )));
    }
    ring.show();
    delay(speed);
    if(firstPixelHue < 65536) {                              // Premiere boucle,
      if(fadeVal < fadeMax) fadeVal++;                       // fade in
    } else if(firstPixelHue >= ((rainbowLoops-1) * 65536)) { // Derniere boucle loop,
      if(fadeVal > 0) fadeVal--;                             // fade out
    } else {
      fadeVal = fadeMax; // boucle intermediaire fade=fademax
    }
  }
}
void setup() {
ring.begin();           // INITIALIZE NeoPixel ring object (REQUIRED)
ring.setBrightness(BRIGHTNESS); // Set BRIGHTNESS to about 1/5 (max = 255)
ring.show();            // Turn OFF all pixels ASAP
}
void loop() {
  ring.fill(Orange,1,3);
  ring.fill(Violet,5,7);
  ring.fill(Pink,9,11);
  ring.show();
  delay(1000);
  ring.clear();
  colorWipe(Red); // Red
  colorWipe(Blue, 100); // Green
  colorWipe(Orange,60,true,2);
  rainbow(3,50);
  colorWipe(White,30,true,5);
  rainbow(5,100,10,200);
}

Plus d’info , sur la page ADAFRUIT NEOPIXEL

Retrouvez sur mon github , les sources de ce tuto .

2 commentaires sur “Bibliothèque neopixel avec un esp8266”

Les commentaires sont fermés.