Page 1 sur 4

Contrôler leds Neopixels (WS2812b) avec un bouton poussoir

Posté : dim. 15 févr. 2015 11:32
par Tomdu38
Salut,

J'ai trouvé cette idée de contrôler des leds WS2812b sur la vidéo de présentation d'un des derniers racers : le Vortex.
Dans la vidéo, on voit une personne, qui, en cliquant sur un bouton, fait changer le mode de clignotement des leds.
J'avais envie de comprendre comment cela fonctionnait, et notamment le contrôle de plusieurs leds par seulement 1 petit fils de signal et une alim en 5V... trop top.

Le code suivant propose une solution pour le contrôle de ces leds. Dans mon montage, j'ai utilisé une barre de 8 leds acheter chez Adafruit.

Le principe : à chaque "clic" sur le bouton poussoir, on déclenche un mode différent. On peut tout de suite imaginer plein d'application et d'évolution, notamment remplacer le bouton poussoir par un interrupteur.

Fonction utiliser dans le programme : Je profite de ce post pour présenter de manière rapide une fonction qui fonctionne très bien lorsque l'on souhaite coder différent mode. la fonction "switch" + "case"

Les utilisations sont diverses :
- code pour un afficheur lcd ( ex : un menu ...)
- différent mode pour une télécommande ( ex : si j'appuie sur "1" alors .... si j'appuie sur "2" alors ...)
- dans le cas présent : plusieurs mode en fonction d'un compteur = variable qui compte le nombre de fois que l'on clique sur le bouton
- et surement plein d'autres possibilités ...

Câblage en pièce jointe.

Ici le code :
ATTENTION : PENSEZ A INSTALLER LA LIBRAIRIE NEOPIXEL : https://github.com/adafruit/Adafruit_NeoPixel" onclick="window.open(this.href);return false;

Code : Tout sélectionner


#include <Adafruit_NeoPixel.h>
#include <avr/power.h>

#define PIN            6 // Which pin on the Arduino is connected to the NeoPixels ; On a Trinket or Gemma we suggest changing this to 1
#define NUMPIXELS      8 // How many NeoPixels are attached to the Arduino?
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(NUMPIXELS, PIN, NEO_GRB + NEO_KHZ800);



// PushButton Stat
boolean PushButtonStat = false;

// PushbuttonPin
const int  PushbuttonPin = 7; 

// Variables will change:
int buttonPushCounter = 0;   // counter for the number of button presses
int buttonState = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button
int NumberOfMode = 9;        // 7 + 2 mode OFF

long Mode1previousMillis = 0; 
long Mode2previousMillis = 0;
long Mode3previousMillis = 0;

long PushButtonpreviousMillis = 0; 

 unsigned long currentMillis = 0;

long Mode1Interval = 50;   // Timer (Delay) Mode 1
long Mode2Interval = 500;   // Timer (Delay) Mode 2
long Mode3Interval = 50;   // Timer (Delay) Mode 3

long Pushinterval = 750;

long blinkMillis = 300; // Blinker delay

// Color Set Mode 1
int R = 250;
int G = 250;
int B = 250;

// Color Set Mode 2
int R_2 = 0;
int G_2 = 0;
int B_2 = 50;

// Color Set Mode 3
int R_3 = 0;
int G_3 = 50;
int B_3 = 0;

// Color Set Mode 4
int R_4 = 250;
int G_4 = 0;
int B_4 = 250;

// Color Set Mode 5
int R_5 = 0;
int G_5 = 20;
int B_5 = 25;

// Color Set Mode 6
int R_6 = 25;
int G_6 = 20;
int B_6 = 0;

// Color Set Mode 7
int R_7 = 0;
int G_7 = 0;
int B_7 = 30;

// Color Set Mode 8
int R_8 = 0;
int G_8 = 0;
int B_8 = 30;




// **** Test ******************

long FirstcurrentMillis = 0;
long FirstpreviousMillis = 0;

long SeccurrentMillis = 0;
long SecpreviousMillis = 0;

long ThirdcurrentMillis = 0;
long ThirdpreviousMillis = 0;

int testvalue = 0;
int ledState = LOW;
int LedPos = 0;
int LedPos2 = 0;
boolean LedOff = false;

// ************Test***********


// Program Start //

void setup() {
    
  pinMode(PushbuttonPin, INPUT_PULLUP);  // initialize the button pin as a input:
  Serial.begin(9600);         // initialize serial communication:
  pixels.begin();             // This initializes the NeoPixel library.
}

void loop() {
 
currentMillis = millis();

 // Push Button Counter
 if(currentMillis - PushButtonpreviousMillis > Pushinterval) 
  {
     buttonState = digitalRead(PushbuttonPin);
                     
    // compare the buttonState to its previous state
     if (buttonState != lastButtonState) 
     {
       // if the state has changed, increment the counter
        if (buttonState == HIGH) 
        {
           // if the current state is HIGH then the button
           // wend from off to on:
          buttonPushCounter++;
          Serial.println("on");
          Serial.print("number of button pushes:  ");
          Serial.println(buttonPushCounter);
        } 
        
         else
         {
         // if the current state is LOW then the button
         // wend from on to off:
          Serial.println("off"); 
         }
     }
       // save the current state as the last state, 
        //for next time through the loop
        lastButtonState = buttonState;
                            
       if (buttonPushCounter == NumberOfMode)
        {
          buttonPushCounter = 0; // reset buttonPushCounter
        }
  }  // Push Button Counter
             

//***************** Start Modes **********************//

  switch (buttonPushCounter)
  {
    case 0:
    
           for (int i = 0; i<NUMPIXELS; i++)
            {
                   pixels.setPixelColor(i, pixels.Color(0,0,0));  // All Leds OFF.
                   pixels.show(); // This sends the updated pixel color to the hardware.
            }
    
    break;
    
    case 1:
           for (int i = 0; i<NUMPIXELS; i++)
            {
                   pixels.setPixelColor(i, pixels.Color(R,G,B)); 
                   pixels.show(); // This sends the updated pixel color to the hardware.
            }
    
    break;
    
    case 2:
           for (int i = 0; i<NUMPIXELS; i++)
            {
                   pixels.setPixelColor(i, pixels.Color(R_2,G_2,B_2)); 
                   pixels.show(); // This sends the updated pixel color to the hardware.
            }
    break;
    
    case 3:
           for (int i = 0; i<NUMPIXELS; i++)
            {
                   pixels.setPixelColor(i, pixels.Color(R_3,G_3,B_3)); 
                   pixels.show(); // This sends the updated pixel color to the hardware.
            }
    break;
    
    case 4:
           for (int i = 0; i<NUMPIXELS; i++)
            {
                   pixels.setPixelColor(i, pixels.Color(R_4,G_4,B_4)); 
                   pixels.show(); // This sends the updated pixel color to the hardware.
            }

    break;
    
    case 5 : // Blink Mode

      FirstcurrentMillis = millis();
       
       if(FirstcurrentMillis - FirstpreviousMillis > blinkMillis)     
          {
             FirstpreviousMillis = FirstcurrentMillis;        
               if (ledState == LOW)
               {
                     for (int i = 0; i<NUMPIXELS; i++)
                     {
                     pixels.setPixelColor(i, pixels.Color(R_5,G_5,B_5)); 
                     pixels.show(); // This sends the updated pixel color to the hardware. 
                     ledState = HIGH;
                     }
             }
               else
               {
                     for (int i = 0; i<NUMPIXELS; i++)
                     {
                     pixels.setPixelColor(i, pixels.Color(0,0,0)); 
                     pixels.show(); // This sends the updated pixel color to the hardware.
                     ledState = LOW;
                   }
               }
                   }
    break;
    
    case 6 : // 
             
                     SeccurrentMillis = millis();
                     
                     if(SeccurrentMillis - SecpreviousMillis > 40)     
                            {
                              SecpreviousMillis = SeccurrentMillis;
                                
                                  pixels.setPixelColor(LedPos, pixels.Color(R_6,G_6,B_6)); 
                                  pixels.show(); // This sends the updated pixel color to the hardware. 
                                  pixels.setPixelColor(LedPos - 1 , pixels.Color(0,0,0)); // turn off previous led
                                  pixels.show(); // This sends the updated pixel color to the hardware.
                                  LedPos = LedPos + 1 ;
                            }

                            if (LedPos > NUMPIXELS)
                              {
                                 LedPos = 0;
                              }

           
    break;
    
    case 7 :
    
               for (int i = 0; i<NUMPIXELS; i++)
            {
                   pixels.setPixelColor(i, pixels.Color(0,0,0));  // All Leds OFF.
                   pixels.show(); // This sends the updated pixel color to the hardware.
            }
    
    LedPos2 = 0;
    break;
    
    
    
    case 8 :
     
      ThirdcurrentMillis = millis();

          if(ThirdcurrentMillis - ThirdpreviousMillis > 350)     
               {
                    ThirdpreviousMillis = ThirdcurrentMillis;
                    
                    pixels.setPixelColor(0, pixels.Color(R_8,G_8,B_8)); // start from the first led
                    pixels.show(); // This sends the updated pixel color to the hardware.
                    pixels.setPixelColor(0 + LedPos2, pixels.Color(R_8,G_8,B_8)); // turn on each led one by one
                    pixels.show(); // This sends the updated pixel color to the hardware.  
                    LedPos2 = LedPos2 + 1 ;
                     
                     Serial.println("LedPos2");
                     Serial.println(LedPos2);
                    //LedOff = false;
                }
         if (LedPos2 >= NUMPIXELS)
               {
                   LedPos2 = 0;
               }

     break;
  }
  
} // end of loop

Enjoy !

PS : Video coming soon !


Re: Contrôler leds Neopixels (WS2812b) avec un bouton pousso

Posté : dim. 15 févr. 2015 11:59
par willmodelisme
Tu sais si les librairies sont importables sur attiny ?

Re: Contrôler leds Neopixels (WS2812b) avec un bouton pousso

Posté : dim. 15 févr. 2015 12:00
par Tomdu38
Normalement oui, ça devrait fonctionner.
A+

Re: Contrôler leds Neopixels (WS2812b) avec un bouton pousso

Posté : dim. 15 févr. 2015 13:14
par willmodelisme
Tu alimentes les LED en 5V ? L'arduino supporte le courant ?

Re: Contrôler leds Neopixels (WS2812b) avec un bouton pousso

Posté : dim. 15 févr. 2015 13:29
par Tomdu38
Dans le montage, en effet, les neopixels sont alimentées par l'arduino, mais par la Pin +5V (pas un output classique).

D'après le datasheet de l'arduino nano, la sortie régulée +5V peut fournir 500mA.
Les leds neopixels à pleine puissance consomment : 60mA / led, donc 8 x 60 = 480 mA ça passe !

Si tu as besoin d'alimenter plus de leds, il faut juste alimenter en parallèle l'arduino et la bande de leds par une alimentation +5V adaptée : fastoche ! ;)

A+

Tom !

Re: Contrôler leds Neopixels (WS2812b) avec un bouton pousso

Posté : dim. 15 févr. 2015 16:03
par willmodelisme
Je testerai, j'ai commandé 2 strip Neo de 8 Leds et un cercle de 12 ;)

Re: Contrôler leds Neopixels (WS2812b) avec un bouton pousso

Posté : lun. 23 févr. 2015 18:22
par willmodelisme
Existe t il des tuto pour adafruit, ou bien une doc brute ?
Là c'est difficile :pleur4:

Re: Contrôler leds Neopixels (WS2812b) avec un bouton pousso

Posté : lun. 23 févr. 2015 18:28
par Papi78
C'est à la mode ces LED, je me suis amusé cet aprèm :

Re: Contrôler leds Neopixels (WS2812b) avec un bouton pousso

Posté : lun. 23 févr. 2015 19:19
par Tomdu38
Existe t il des tuto pour adafruit, ou bien une doc brute ?
Là c'est difficile :pleur4:
Qu'est ce qui se passe ?

Je mets un fichier en pièce jointe, c'est le datasheet des WS2812b (leds avec 4 pattes), je ne sais pas si c'est ce que tu veux !

A+

Re: Contrôler leds Neopixels (WS2812b) avec un bouton pousso

Posté : lun. 23 févr. 2015 20:52
par willmodelisme
J'essaie de m'imprégner du code ADAFRUIT.
Je charge le sketch Standtest et j’essaie de piger les principaux codes.
J'arrive à modifier les variables, pas de soucis.
J'essaye aussi de faire des sketch avec une seules variation (rainbow,crawling, chase etc...)
Mais j'y arrive pas.
Je pige pas (par exemple) le code

Code : Tout sélectionner

void theaterChase(uint32_t c, uint8_t wait)
A quoi il sert ?

Je continue à trifouiller :hehe:

Re: Contrôler leds Neopixels (WS2812b) avec un bouton pousso

Posté : lun. 23 févr. 2015 21:24
par Tomdu38
Ok, tu t'es arrêté trop tôt lol

Code : Tout sélectionner

//Theatre-style crawling lights.
void theaterChase(uint32_t c, uint8_t wait) {
  for (int j=0; j<10; j++) {  //do 10 cycles of chasing
    for (int q=0; q < 3; q++) {
      for (int i=0; i < strip.numPixels(); i=i+3) {
        strip.setPixelColor(i+q, c);    //turn every third pixel on
      }
      strip.show();
     
      delay(wait);
     
      for (int i=0; i < strip.numPixels(); i=i+3) {
        strip.setPixelColor(i+q, 0);        //turn every third pixel off
      }
    }
  }
}
C'est une fonction, il faut regarder tout le code entre { }
La fonction à cette syntaxe : void NomDeLaFonction(Paramètre,Paramètre,...){code de la fonction...}

En clair :

Code : Tout sélectionner

theaterChase(uint32_t c, uint8_t wait)...
est une fonction qui prend en entrée 2 paramètres.

uint32_t c et uint8_t wait.

Dans le code, cette fonction est codée à la fin du fichier, mais elle est utilisée avant dans :

Code : Tout sélectionner

theaterChase(strip.Color(127, 127, 127), 50); // White
theaterChase(strip.Color(127,   0,   0), 50); // Red
theaterChase(strip.Color(  0,   0, 127), 50); // Blue
Elle est utilisée 3 fois (chaque ligne) tu reconnais le nom de la fonction "theaterChase" (sans le "void" devant). Entre parenthèse tu as les 2 paramètres.

On en déduit que :

uint32_t c = strip.Color(127, 127, 127) => qui détermine la couleur de bande de led (R,G,B) avec des valeurs allant de 0 à 255 entre chaque ","
uint8_t wait = 50 => "wait", je suppose qu'il s'agit d'un délay en milliseconde.

En espérant que ça te fasse avancer.

A+

Tom

Re: Contrôler leds Neopixels (WS2812b) avec un bouton pousso

Posté : lun. 23 févr. 2015 21:30
par willmodelisme
C'est tout du papier mâché dans ma tête.....
Je vais faire une pause et ça ira mieux demain :mdr1:

Re: Contrôler leds Neopixels (WS2812b) avec un bouton pousso

Posté : lun. 23 févr. 2015 21:35
par Tomdu38
Pour compléter avec d'autres explications plus générales :

http://eskimon.fr/86-arduino-106-le-lan ... -22#461108

Re: Contrôler leds Neopixels (WS2812b) avec un bouton pousso

Posté : mar. 24 févr. 2015 17:06
par Jean des Biolles
Salut, j'ai trouvé une librairie qui sers aussi à piloter les WS2812:
Fastled.

Si ça peut aider. . . .

Re: Contrôler leds Neopixels (WS2812b) avec un bouton pousso

Posté : mar. 24 févr. 2015 17:57
par attafr
Jean des Biolles a écrit :Salut, j'ai trouvé une librairie qui sers aussi à piloter les WS2812:
Fastled.

Si ça peut aider. . . .
L O,
Si tu avais un lien, je suis sûr que cela pourrait aider !
A+

Re: Contrôler leds Neopixels (WS2812b) avec un bouton pousso

Posté : mar. 24 févr. 2015 18:48
par willmodelisme
Certainement FASTLed.
https://github.com/FastLED/FastLED/wiki/Basic-usage" onclick="window.open(this.href);return false;

Re: Contrôler leds Neopixels (WS2812b) avec un bouton pousso

Posté : mar. 24 févr. 2015 19:37
par Jean des Biolles
Désolé pour le lien je suis sur le Natel. Et je voulais répondre tous de suite. Mais je comprend ta frustration ;).
Je vois que will fait les chose bien mieux et plus rapidement que moi! Merci.

Re: Contrôler leds Neopixels (WS2812b) avec un bouton pousso

Posté : mar. 24 févr. 2015 20:49
par willmodelisme
:mdr3: Je suis dedans, c'est facile pour moi :amen: :super:

Re: Contrôler leds Neopixels (WS2812b) avec un bouton pousso

Posté : mar. 24 févr. 2015 21:00
par Tomdu38
@willmodelisme : tu as résolu ton problème ? c'est bon !?

Re: Contrôler leds Neopixels (WS2812b) avec un bouton pousso

Posté : mar. 24 févr. 2015 21:06
par willmodelisme
Oui, petit à petit je vais y arriver.
J'ai ton tuto aussi qui m'aide pas mal, avec le bouton poussoir.
J'ai pas de projet concret, je veux juste comprendre pour l'instant.

J'ai mis un peu de coté les Neopixel car je suis sur un autre projet, un déclencheur pour APN pour les photos d'éclairs, efficace de jour comme de nuit. :gene:

Re: Contrôler leds Neopixels (WS2812b) avec un bouton pousso

Posté : ven. 6 mars 2015 18:31
par willmodelisme
J'ai testé ton code.
Ça marche parfaitement.
Je voudrais me faire un petit appareil pour le lightpainting et je me demandais si il existait un code avec toutes les variations possibles (en tout cas le plus fameuses) que l'on changerait et ferait délier avec un bouton-poussoir ?

Sinon je vais modifier ton code pour y arriver.

Re: Contrôler leds Neopixels (WS2812b) avec un bouton pousso

Posté : ven. 6 mars 2015 19:45
par Tomdu38
Toutes les variations possibles, ça à en fait un bon paquet !!!

Après sur mon code, comme tu as pu le voir, j'ai fait que 7 modes, tu peux en rajouter le nombre que tu veux !

Dans ton application tu pourrais même arriver à écrire des choses juste en déplaçant horizontalement les leds. Par contre, pour coder ça ! c'est un plus le bordel !

Bon weekend !

Tom

Re: Contrôler leds Neopixels (WS2812b) avec un bouton pousso

Posté : mar. 10 mars 2015 07:33
par florentf31

Re: Contrôler leds Neopixels (WS2812b) avec un bouton pousso

Posté : mar. 10 mars 2015 07:55
par willmodelisme
Ah ouai.... 40 pattern ça c'est cool.... :super:
On dirait un attiny... Faut juste lire le code....

Re: Contrôler leds Neopixels (WS2812b) avec un bouton pousso

Posté : mar. 10 mars 2015 08:50
par Tomdu38
Hello,
Juste une petite remarque, j'utilise la librairie Adafruit pour les Neopixels (led WS 2821 B), j'ai voulu tester mon programme avec un Attiny85 20Mhz....

J'ai une erreur sur le compilateur arduino : CPU speed ...... En fait, la librairie ne permet pas d'utiliser les leds à plus de 16Mhz donc un Attiny85 8Mhz et 16Mhz devraient fonctionner.

Cela dit, je vais voir s'il n'y a pas un moyen de tricher... je n'ai que des Attiny85 en 20Mhz à la maison :pleur4:

Je vous tiens au courant.

Bonne journée.

Tom