Branchement neopixel avec interrupteur

Bonjour,
j'ai acheté un neopixel rond

que je n'ai toujours pas reçu et en attendant je me pose une question:

Dans mon montage je dois couper l'éclairage du neopixel; sachant qu'il y a 3fils (5v GND, fil de donnée)

Pour mon câblage le plus simple serait de mettre un interrupteur sur le fil de donnée; mais si j'ouvre l'interrupteur, donc pas de donné sur le neopixel va t il être éteint ou allumé vue qu'il sera quand même alimenté en 5v.
D'ou ma question puis je mettre mon inter sur le fil de donné ou dois je coupé le 5v qui alimente le neopixel?

Merci

pourquoi ne pas simplement éteindre les LEDs ?

Bonjour,

+1 avec J-M-L, mais en plus la doc des neopixels précise bien de ne pas connecter le fil de données sans que les neopixels soient alimentés.
Si tu coupes le fil de données, les leds vont rester dans l'état ou elles sont.

Bonjour J-M-L, je suis la personne qui fabrique une mini cuisine pour sa fille.
En faite je cherche à simuler la plaque de cuissons avec le neopixel qui sera gérée par un potentiomètre pour éclairer plus ou moins rouge.alors deux choix se propose à moi:
Soit je dis à l'arduino que lorsque le potentiomètre a une valeur nul il éteint le neopixel
Soit je rajoute un bouton interrupteur à côté du potentiomètre pour que ma fille allume la plaque de cuisson puis gère l'intensité du neopixel avec le potentiomètre

Je préfère la deuxième solution ou ma fille allume sa plaque puis tourne le bouton. Mais pour cela je dois couper l'alimentation du neopixel. Vaut il mieux couper le fil de donnée ou le fil d'alimentation 5v?

MiniZ:
Mais pour cela je dois couper l'alimentation du neopixel. Vaut il mieux couper le fil de donnée ou le fil d'alimentation 5v?

Ni l'un ni l'autre. Tu connectes ton interrupteur sur une entrée et tu éteins/allumes les leds par programme quand l'interrupteur bascule.

Ok kamilly, mais cela me complique le câblage et me prend des entrées sur ma carte arduino!
Pourquoi penses tu que couper un des fils de l'alim ne soit pas la bonne solution?

J'ai lu (je ne sais plus ou) qu'il était déconseillé de connecter les données avant l'alimentation. Edit: dans ce document

C'est beaucoup plus souple de connecter l'inter sur l'arduino. Je ne pense pas que ça complique le cablage, mais effectivement ça prend une entrée.

Si vous ne voulez qu'un seul fil vers l'Arduino alimentez le potentiomètre et éventuellement les Néopixels par le bouton on/off de l'alimentation de la plaque et lisez sur une broche analogique la tension du potentiomètre comme ça vous aurez 0 tant que la plaque n'est pas allumée et la valeur de tension du potentiomètre (éventuellment telle que laissée la dernière fois) dès qu'il est alimenté

Les neopixels tirent beaucoup de courant à l'allumage il est même conseillé de mettre un bon condensateur entre les + et - de l'alimentation pour gérer la phase d'appel de courant et les pics de tensions potentiellement associés

Cela dit l'intérêt de piloter l'alimentation par l'Arduino c'est de pouvoir tout couper par programme éventuellement

Merci J-M-L, je pense faire comme tu dis, mettre mon inter en tête et à partir de la alimenter le potentiomètre et le neopixel.
Par contre je vais avoir un petit souci d'alimentation électrique: j'ai 6 neopixels de 24 Leds chacun soit 144 leds x 20mA/1000 soit 2,88Ampere d'après la notice adafruit + un petit moteur pap + un écran lcd + un afficheur 4 digits + 2 cartes arduino mega. Je dois prendre quoi en type d'alim et en calibre 5v à votre avis?

3 ampères sans doute ou deux alims séparées avec les GND communs

En pratique les 20mA sont un max pour une couleur à fond - vous pouvez n'allumer qu'une led sur deux ou trois en alternance et aléatoirement par exemple être avec un peu de bleu ou de jaune pour simuler un feu, ça créera du mouvement tout en diminuant la conso - ou alors tout en rouge mais ne pas mettre la luminosité plein pot et ça baissera votre consommation électrique

Bonjour J-M-L,
J’ai bien avancé dans ma cuisine, j'ai pratiquement fini la partie construction comme tu peux le voir.

voir pièces jointes

Je suis en train de taper le code, je possède un bouton rotatif si tu te souviens qui gères l'afficheur LCD; de plus j'ai un neopixel dans la machine à laver qui est géré par un potentiomètre.

Je souhaiterais faire tourner comme un chenillard les leds du neopixel en changeant la couleur quand j’agis sur le potentiomètre. Le problème c'est que j'ai trouvé un bout de code qui permet de faire un effet sympa (simule le mouvement rotatif du tambour de machine à laver). Mais lorsque le programme rentre dans la boucle pour faire tourner les leds du neopixel je ne peux plus gérer mon bouton rotatif tant que je suis dans la boucle snifffffff

Aurais-tu une idée pour résoudre mon problème? Sachant que je ne me suis pas encore occupé de changer la couleur du neopixel en fonction du potentiomètre vue que je n'arrive déjà pas à faire fonctionner ma boucle "neopixel" et mon bouton rotatif...

Voici le code que j'ai trouvé pour simuler mon tambour de machine à laver

//Theatre-style crawling lights with rainbow effect
void theaterChaseRainbow(uint8_t wait) {
  for (int j=0; j < 256; j++) {     // cycle all 256 colors in the wheel
    for (int q=0; q < 3; q++) {
      for (uint16_t i=0; i < strip.numPixels(); i=i+3) {
        strip.setPixelColor(i+q, Wheel( (i+j) % 255));    //turn every third pixel on
      }
      strip.show();

      delay(wait);

      for (uint16_t i=0; i < strip.numPixels(); i=i+3) {
        strip.setPixelColor(i+q, 0);        //turn every third pixel off
      }
    }
  }
}

// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
  WheelPos = 255 - WheelPos;
  if(WheelPos < 85) {
    return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  }
  if(WheelPos < 170) {
    WheelPos -= 85;
    return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
  WheelPos -= 170;
  return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}

IMG_2879.JPG

IMG_2880.JPG

Voici le code raccourci pour te montrer mon exemple; quand je passe en position 5 je reste bloqué jusqu’à la fin de programme qui fait tourner les leds du neopixel; comment faire pour que je puisse sortir du programme quand je change de position le bouton rotatif?

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
#include "U8glib.h"                       //Inclut la librairei U8G
#include "image_bitmap.h"


//Déclaration Neopixel 

Adafruit_NeoPixel NEOPIXELLAVELINGE = Adafruit_NeoPixel(24, 1, NEO_GRB + NEO_KHZ800); //neopixel lavelinge


//Cablage LCD
U8GLIB_ST7920_128X64 u8g(4,3,2, U8G_PIN_NONE); //Cablage en SPI  4-E-FIL BLANC 3-R/W-FIL ROSE 2-RS-FIL BLEU



/* Fonction permettant de redessiner TOUT l'écran */
void updateToDisp1(void);
void updateToDisp2(void);
void updateToDisp3(void);
void updateToDisp4(void);
void updateToDisp5(void);
void updateToDisp6(void);
void updateToDisp7(void);
void updateToDisp8(void);

void drawDisp1(void);
void drawDisp2(void);
void drawDisp3(void);
void drawDisp4(void);
void drawDisp5(void);
void drawDisp6(void);
void drawDisp7(void);
void drawDisp8(void);


// Fonction pour mettre à jour l'écran sur position 1
void updateToDisp1(void) {
    u8g.firstPage();
    do  {
        draw();
    } while( u8g.nextPage() );
}

// Fonction de dessin de l'écran position 1
void draw(void) {
    /*u8g.setFont(u8g_font_unifont);
    u8g.drawStr( 0, 22, "Position1!");*/
    u8g.drawBitmapP(0, 0, 16, 64, image_bitmap);
}



// Fonction pour mettre à jour l'écran sur position 2
void updateToDisp2(void) {
    u8g.firstPage();
    do  {
        drawDisp2();
    } while( u8g.nextPage() );
}

// Fonction de dessin de l'écran position 2
void drawDisp2(void) {
    u8g.setFont(u8g_font_unifont);
    u8g.drawStr( 0, 22, "Position2!");
}



// Fonction pour mettre à jour l'écran sur position 3
void updateToDisp3(void) {
    u8g.firstPage();
    do  {
        drawDisp3();
    } while( u8g.nextPage() );
}

// Fonction de dessin de l'écran position 3
void drawDisp3(void) {
    u8g.setFont(u8g_font_unifont);
    u8g.drawStr( 0, 22, "Position3!");
}



// Fonction pour mettre à jour l'écran sur position 4
void updateToDisp4(void) {
    u8g.firstPage();
    do  {
        drawDisp4();
    } while( u8g.nextPage() );
}

// Fonction de dessin de l'écran position 4
void drawDisp4(void) {
    u8g.setFont(u8g_font_unifont);
    u8g.drawStr( 0, 22, "Position4!");
}



// Fonction pour mettre à jour l'écran sur position 5
void updateToDisp5(void) {
    u8g.firstPage();
    do  {
        drawDisp5();
    } while( u8g.nextPage() );
}

// Fonction de dessin de l'écran position 5
void drawDisp5(void) {
    u8g.setFont(u8g_font_unifont);
    u8g.drawStr( 0, 22, "Position5!");
}



// Fonction pour mettre à jour l'écran sur position 6
void updateToDisp6(void) {
    u8g.firstPage();
    do  {
        drawDisp6();
    } while( u8g.nextPage() );
}

// Fonction de dessin de l'écran position 6
void drawDisp6(void) {
    u8g.setFont(u8g_font_unifont);
    u8g.drawStr( 0, 22, "Position6!");
}



// Fonction pour mettre à jour l'écran sur position 7
void updateToDisp7(void) {
    u8g.firstPage();
    do  {
        drawDisp7();
    } while( u8g.nextPage() );
}

// Fonction de dessin de l'écran position7
void drawDisp7(void) {
    u8g.setFont(u8g_font_unifont);
    u8g.drawStr( 0, 22, "Position7!");
}



// Fonction pour mettre à jour l'écran sur position 8
void updateToDisp8(void) {
    u8g.firstPage();
    do  {
        drawDisp8();
    } while( u8g.nextPage() );
}

// Fonction de dessin de l'écran position 8
void drawDisp8(void) {
    u8g.setFont(u8g_font_unifont);
    u8g.drawStr( 0, 22, "Position8!");
}



//cablage broche bouton rotatif
const int broche_2 = 13;       //rien de branché sur la broche 1
const int broche_3 = 12;
const int broche_4 = 11;
const int broche_5 = 10;
const int broche_6 = 9;
const int broche_7 = 8;


void setup() {
 
  Serial.begin(9600);
// This is for Trinket 5V 16MHz, you can remove these three lines if you are not using a Trinket
  #if defined (__AVR_ATtiny85__)
    if (F_CPU == 16000000) clock_prescale_set(clock_div_1);
  #endif
  // End of trinket special code
  NEOPIXELLAVELINGE.begin();
  NEOPIXELLAVELINGE.show(); // Initialize all pixels to 'off'


  //initialisation LCD 
  u8g.setColorIndex(1); // Affichage en mode N&B

  //initialisation des broches bouton rotatif
  pinMode(broche_2, OUTPUT);
  pinMode(broche_3, OUTPUT);
  pinMode(broche_4, INPUT_PULLUP);
  pinMode(broche_5, INPUT_PULLUP);
  pinMode(broche_6, INPUT_PULLUP);
  pinMode(broche_7, INPUT_PULLUP);

  digitalWrite(broche_2, HIGH);
  digitalWrite(broche_3, HIGH);
 
}

void loop() {
  digitalWrite (broche_2, LOW);           //lecture et affichage sur le LCD de l'état du bouton rotatif position 5 6 7 8
  digitalWrite (broche_3, HIGH);
  
if (digitalRead(broche_4) == LOW)
{
  Serial.println("position5");
    updateToDisp5(); 
    theaterChaseRainbow(50); 
}

if (digitalRead(broche_5) == LOW)
{
  Serial.println("position6");
  updateToDisp6();
}

if (digitalRead(broche_6) == LOW)
{
  Serial.println("position7");
   updateToDisp7();
}

if (digitalRead(broche_7) == LOW)
{
  Serial.println("position8");
   updateToDisp8();
}

{
  digitalWrite (broche_2, HIGH);        //lecture et affichage sur le LCD de l'atat du bouton rotatif position 4 3 2 1
  digitalWrite (broche_3, LOW);
}

if (digitalRead(broche_4) == LOW)
{
   Serial.println("position4");
   updateToDisp4();
}

if (digitalRead(broche_5) == LOW)
{
   Serial.println("position3");
    updateToDisp3();
}

if (digitalRead(broche_6) == LOW)
{
   Serial.println("position2");
    updateToDisp2();
    theaterChaseRainbow(50);
}

if (digitalRead(broche_7) == LOW)
{
   Serial.println("position1");
   updateToDisp1();
}

   



//Neopixel pour simuler le tambour tournant du lave linge

//Theatre-style crawling lights with rainbow effect
void theaterChaseRainbow(uint8_t wait) {
  for (int j=0; j < 256; j++) {     // cycle all 256 colors in the wheel
    for (int q=0; q < 3; q++) {
      for (uint16_t i=0; i < NEOPIXELLAVELINGE.numPixels(); i=i+3) {
        NEOPIXELLAVELINGE.setPixelColor(i+q, Wheel( (i+j) % 255));    //turn every third pixel on
      }
      NEOPIXELLAVELINGE.show();

      delay(wait);

      for (uint16_t i=0; i < NEOPIXELLAVELINGE.numPixels(); i=i+3) {
        NEOPIXELLAVELINGE.setPixelColor(i+q, 0);        //turn every third pixel off
      }
    }
  }
}

// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
  WheelPos = 255 - WheelPos;
  if(WheelPos < 85) {
    return NEOPIXELLAVELINGE.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  }
  if(WheelPos < 170) {
    WheelPos -= 85;
    return NEOPIXELLAVELINGE.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
  WheelPos -= 170;
  return NEOPIXELLAVELINGE.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}

MiniZ:
...

Dans mon montage je dois couper l'éclairage du neopixel; sachant qu'il y a 3fils (5v GND, fil de donnée)
...
Pour mon câblage le plus simple ...

Bonsoir
Il y a aussi la solution soft simple de mettre les RVB à 0 8)

Je souhaiterais faire tourner comme un chenillard les leds du neopixel en changeant la couleur quand j'agis sur le potentiomètre. Le problème c'est que j'ai trouvé un bout de code qui permet de faire un effet sympa (simule le mouvement rotatif du tambour de machine à laver). Mais lorsque le programme rentre dans la boucle pour faire tourner les leds du neopixel je ne peux plus gérer mon bouton rotatif tant que je suis dans la boucle snifffffff

la fonction chenillard ne fait rien d'autre que de boucler avec un délai établi dans le code en dur par       delay(wait);... donc il faut casser la boucle incluse dans la fonction pour ne faire qu'une seule étape et revenir au code principal. Et bien sûr dans la loop il faut appeler la fonction souvent, si vous n'avez qu'un chevillard à gérer alors vous pouvez avoir une variable static locale à votre fonction qui se souvient quelle était l'heure de la dernière action et tant que wait ne s'est pas écoulé, vous ne faites rien, sinon vous effectuez la prochaine action

Voici un petit exemple pratique sur comment faire.

Ce premier code a une fonction bloquante un peu similaire à la votre qui fait clignoter la LED intégrée (pin 13 généralement) 5 fois

void clignote5fois_FonctionBloquante(unsigned int dureeAttente)
{
  for (int i = 0; i < 10; i++) {
    digitalWrite(LED_BUILTIN, digitalRead(LED_BUILTIN) == LOW ? HIGH : LOW);
    delay(dureeAttente);
  }
}

void setup() {
  Serial.begin(115200);
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);
  clignote5fois_FonctionBloquante(250);
}

void loop() {
}

comme vous pouvez le voir, le code est tout simple, il ya une boucle de 10 étapes avec attente active dans la fonction

Voici un autre code qui n'est pas loin du premier mais qui casse la boucle for de la fonction. On appelle une fois avec go = true pour dire démarrage de la fonction, et ensuite on se contente d'appeler dans la boucle et c'est la fonction qui sait quand elle doit faire la bascule, avec la méthode de gestion du temps type blink without delay

void clignote5fois_FonctionNonBloquante(unsigned int dureeAttente, boolean go)
{
  static int etape = 0;
  static unsigned long chrono;

  if (go) {
    // c'est un lancement initial de la fonction
    digitalWrite(LED_BUILTIN, HIGH);
    chrono = millis();
    etape = 1;
  } else if (etape < 10) { // est-ce qu'on a fini la séquence ?
    if (millis() - chrono >= dureeAttente) { // on vérifie si c'est le moment de clignoter
      digitalWrite(LED_BUILTIN, digitalRead(LED_BUILTIN) == LOW ? HIGH : LOW); // si oui on clignote
      chrono += dureeAttente; // et on définit le prochain moment
      etape++; // on se souvient qu'on a fait une étape en plus
    }
  }
}

void setup() {
  Serial.begin(115200);
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);
  clignote5fois_FonctionNonBloquante(250, true); // true quand on veut activer un cycle
}

void loop() {
  clignote5fois_FonctionNonBloquante(250, false); // on va voir de temps en temps, false pour dire que ce n'est pas un redéclenchement
}

Merci J-M-L, je test cela dans la semaine.
Par contre à chaque fois je me demande comment tu fais pour savoir faire tout ça ( tu m'impresssionnes)

Je te redis une fois testé.

MiniZ:
Merci J-M-L, je test cela dans la semaine.
Par contre à chaque fois je me demande comment tu fais pour savoir faire tout ça ( tu m'impresssionnes)

moi je ne serai pas capable de faire une jolie cuisine comme la votre! On a tous des talents

J-M-L merci pour ton commentaire;

Penses tu que ton code me permettra de faire l'effet de cette vidéo situé entre 2minutes25 et 3minutes?
Je trouve que cette effet simulerait bien un tambour de machine à laver qui tourne...
et encore merci pour ton aide apporté a mon projet.

le code que j'avais donné était le principe, voici votre code d'exemple (de l'autre post) modifié pour être sans attente.

mettez la console à 115200 bauds, branchez la strip comme il faut et elle devrait faire l'animation tout en imprimant dans la console la valeur de micros() pour vous montrer que c'est non bloquant

je n'ai pas de NeoPixel sous la main donc je n'ai pas pu tester - dites moi si ça fonctionne, mais en gros c'est le principe.

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

#define PIN A5

Adafruit_NeoPixel strip = Adafruit_NeoPixel(24, PIN, NEO_GRB + NEO_KHZ800);

void setup() {
  Serial.begin(115200);
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
}

void loop() {
  theaterChaseRainbow(50);
  Serial.println(micros()); // pour montrer que c'est non bloquant vous aurez micros() qui défile dans la console
}


void theaterChaseRainbow(uint8_t wait) {
  static unsigned long chrono = 0;
  static unsigned int j = 0;
  static byte q;
  static boolean turnedOn = false;

  if (chrono == 0) chrono = millis() - wait; // pour déclencher au premier appel

  if (millis() - chrono >= wait) {  // on vérifie si c'est le moment de faire l'animation
    // le délai est expiré
    if (turnedOn) {
      for (uint16_t i = 0; i < strip.numPixels(); i = i + 3) {
        strip.setPixelColor(i + q, 0);      //turn every third pixel off
      }
    } else {
      for (uint16_t i = 0; i < strip.numPixels(); i = i + 3) {
        strip.setPixelColor(i + q, Wheel( (i + j) % 255)); //turn every third pixel on
      }
    }
    strip.show();
    turnedOn = !turnedOn;

    // on passe au q et j suivant
    if (++q >= 3) {
      q = 0;
      if (++j >= 255) j = 0;
    }

    chrono += wait; // on définit le prochain moment
  }
}


// Input a value 0 to 255 to get a color value.
// The colours are a transition r - g - b - back to r.
uint32_t Wheel(byte WheelPos) {
  WheelPos = 255 - WheelPos;
  if (WheelPos < 85) {
    return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  }
  if (WheelPos < 170) {
    WheelPos -= 85;
    return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
  WheelPos -= 170;
  return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}

Merci J-M-L, je test demain.
J'ai essayé de comprendre un peu le code mais je bute sur pas mal de chose; mais pour commencer:

#include <avr/power.h>
Je suppose que c'est pour gérer le temps et on en a besoin pour le wait??? Le wait ça correspond à quoi?

Uint8_t c'est quoi? Toujours lié au temps je suppose?

Merci pour les explications.

#include <avr/power.h>

C'était dans votre code... je l'ai laissé. à mon avis ce n'est pas nécessaire

le wait c'est le paramètre passé à la fonction

uint8_t c'est un type de base du langage C/C++ qui veut dire type unsigned integer sur 8 bit. c'est la même chose que d'utiliser byte, un nombre entier entre 0 et 255 stocké sur 1 octet

Vous Regardez mon second code? c'est celui qui sera le plus adapté pour votre besoin