Interférence de clignotement de LED avec bouton

Un fade serait fait avec une boucle sur la luminosité (par exemple) :

  // Task 3: Neopixels s'allument en jaune
  strip.fill(strip.Color(255, 128, 0), 0, 2);// pixel color set to yellow
  for (int bright = 200; bright = 0; bright --) {
      strip.setBrightness(bright); 
  strip.show();
  delay(random(0,200)); // random delay for flicker effect
}

Mais il y a un delay...
Pour faire sans le delay, c'est un peu plus compliqué.

Tu peux déjà commencer par mettre les deux premières tâches dans des fonctions et vérifier si ça marche correctement.

J'ai carrément enlever cette ligne de code et l'effet de vacillement est toujours là sur Tinkercad... Parfait!

Le fade serait pour la LED orange, mais pour le Neopixel.

Alors tu fais la même chose (la boucle) avec strip.setBrightness

Lorsque tu auras un peu avancé dans ton code, poste une version stabilisée, pour qu'on puisse t'aider à continuer.

merci

Voici le code à peu près terminé. Je n'ai pas mis le BTN en INPUT_PULLUP parce que la LED Rouge n'arrêtait pas de clignoter au lieu de ne le faire que 4 fois. La Verte fait un FADE si on lâche le bouton. Si on le garde enfoncé, elle reste allumée. Je n'ai pas encore trouvé comment régler ça.

#include <Adafruit_NeoPixel.h>
#define PIN 9
#define NUM_LEDS 2

// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   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     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, PIN, NEO_GRB + NEO_KHZ800);

#define BT 4
#define BTN 2
#define Vert 6
#define Rouge 10
#define Blanc 11
#define Orange 12
#define Bleu 13

int Bleu_State = LOW;
int Orange_State = LOW;
int brightness = 0;

unsigned long prevTime_T1 = millis ();
unsigned long prevTime_T4 = millis ();

long interval_T1 = 1500;
long interval_T4 = 800;
    
void setup() {
  Serial.begin(9600);
  pinMode(PIN, OUTPUT);
  pinMode(Blanc, OUTPUT);
  pinMode(Rouge, OUTPUT);
  pinMode(Bleu, OUTPUT);
  pinMode(Vert, OUTPUT);
  pinMode(Orange, OUTPUT);
  pinMode(BTN, INPUT);
  pinMode(BT, INPUT_PULLUP);
  digitalWrite(Blanc, HIGH);
  strip.begin();
}

void loop() {
  
  unsigned long currentTime = millis();
  
  // Task 1 LED Orange clignote rapidement
  if (currentTime - prevTime_T4 > 800) {
    Orange_State = !Orange_State;
    digitalWrite(Orange, Orange_State);
    
    prevTime_T4 = currentTime;
  }
  
  // Task 2 LED bleu clignote lentement
  if (currentTime - prevTime_T1 > 1500) {
    Bleu_State = !Bleu_State;
    digitalWrite(Bleu, Bleu_State);
    
    prevTime_T1 = currentTime;
  }

  //Task 3 Neopixels s'allument en jaune et flicker 
  strip.fill(strip.Color(255, 153, 0), 0, 2);// pixel color set to yellow
  strip.setBrightness(random(150,255)); // random brightness adjust for flicker effect
  strip.show();

  // Task 4 LED Vert s'allume avec BT
  if (digitalRead(BT) == HIGH){
    delay(30);
    digitalWrite(Vert, LOW);
  } else {
    digitalWrite(Vert, HIGH);
  }

	for (int bright = 255; bright = 0; bright --) {
      strip.setBrightness(bright); 
 	  strip.show();
   }

  // Task 5 LED Rouge flashe 4 fois avec BTN
  if (digitalRead(BTN) == HIGH){
    for (int i=0; i<4; i=i+1) {
      digitalWrite (Rouge, HIGH);
      delay (100);
      digitalWrite (Rouge, LOW);
      delay (100);
     }
   }
    else{
      digitalWrite(Rouge, LOW);
   } 
}

Si vous préférz, voici le lien pour Tinkercad :

J'ai fait un petit wokwi avec ton programme, en ne reprenant que les LED sur la simulation matériel.
J'ai augmenter les intervalles de temps pour la LED, rouge pour bien montrer l'impacte des "delay"

Si tu veux pouvoir appuyer sur le bouton rouge pour lancer l'animation tout en continuant à avoir les animations sur les autres LEDS.
Il faut s'inspirer de ce que tu fait dans les tache de clignotement Task1 et Task2, mais il te faudra plus de variable, puisque ton animation dépend pas uniquement du temps.
Pour commencer, si tu pouvais juste transformer ton programme, pour qu'un appuis lance un clignotement de la LED rouge ?

Oui, la bonne question est : que veux-tu faire avec le bouton et la led rouge ?

J'ai repris ton code à ma manière, mais sans écrire la tâche 5 car elle est mal définie :

#include <Adafruit_NeoPixel.h>
#define PIN 9
#define NUM_LEDS 2

// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   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     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, PIN, NEO_GRB + NEO_KHZ800);

#define BT 4
#define BTN 2
#define Vert 6
#define Rouge 10
#define Blanc 11
#define Orange 12
#define Bleu 13

int brightness = 0;
const long interval_T1 = 1500;
const long interval_T4 = 800;


void setup() {
  Serial.begin(9600);
  pinMode(PIN,    OUTPUT);
  pinMode(Blanc,  OUTPUT);
  pinMode(Rouge,  OUTPUT);
  pinMode(Bleu,   OUTPUT);
  pinMode(Vert,   OUTPUT);
  pinMode(Orange, OUTPUT);
  pinMode(BTN,    INPUT);
  pinMode(BT,     INPUT_PULLUP);
  digitalWrite(Blanc, HIGH);
  strip.begin();
  strip.fill(strip.Color(255, 153, 0), 0, 2);// pixel color set to yellow
}

void task1 (unsigned long duration) {
  static unsigned long chrono = millis();
  static int Orange_State = LOW;
  if (millis() - chrono < duration) return;
  chrono = millis();
  Orange_State = !Orange_State;
  digitalWrite(Orange, Orange_State);
}

void task2 (unsigned long duration) {
  static unsigned long chrono = millis();
  static int Bleu_State = LOW;
  if (millis() - chrono < duration) return;
  chrono = millis();
  Bleu_State = !Bleu_State;
  digitalWrite(Bleu, Bleu_State);
}


void loop() {
  // Task 1 LED Orange clignote rapidement
  task1 (interval_T4);
  
  // Task 2 LED bleu clignote lentement
  task2 (interval_T1);

  //Task 3 Neopixels s'allument en jaune et flicker 
  strip.setBrightness(random(150,255)); // random brightness adjust for flicker effect
  strip.show();

  // Task 4 LED Vert s'allume avec BT
  int button_state = digitalRead(BT);
  digitalWrite(Vert, !button_state);
  delay(30);

  for (int bright = 255; bright = 0; bright --) {
    strip.setBrightness(bright); 
    strip.show();
   }

  // Task 5 LED Rouge flashe 4 fois avec BTN
  if (digitalRead(BTN) == HIGH){
    for (int i=0; i<4; i=i+1) {
      digitalWrite (Rouge, HIGH);
      delay (100);
      digitalWrite (Rouge, LOW);
      delay (100);
     }
   }
    else {
      digitalWrite(Rouge, LOW);
   } 
}

Je n'ai pas compilé, il peut y avoir des erreurs.

Donc explique ce que tu veux faire avec ce bouton est cette led rouge. Pour l'instant, tant que le bouton est enfoncé, la led va clignoter. Si tu relâches le bouton, elle finira de clignoter puis s'éteindra. Mais c'est une tâche bloquante : pendant les 800 ms du clignotement, rien d'autre n'est fait (les autres leds restent dans leur état actuel et donc peuvent dépasser leur durée d'allumage)

Autre chose : le FADE de la tâche 4 me semble très rapide, il n'y a aucun temps de pause. La led verte doit s'éteindre au moment où tu appuies sur le bouton, non ?

Voici le traitement de la tâche 5 :

#include <Adafruit_NeoPixel.h>
#define PIN 9
#define NUM_LEDS 2

// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   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     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, PIN, NEO_GRB + NEO_KHZ800);

#define BT 4
#define BTN 2
#define Vert 6
#define Rouge 10
#define Blanc 11
#define Orange 12
#define Bleu 13

int brightness = 0;
const long interval_T1 = 1500;
const long interval_T4 = 800;


void setup() {
    Serial.begin(9600);
    pinMode(PIN,    OUTPUT);
    pinMode(Blanc,  OUTPUT);
    pinMode(Rouge,  OUTPUT);
    pinMode(Bleu,   OUTPUT);
    pinMode(Vert,   OUTPUT);
    pinMode(Orange, OUTPUT);
    pinMode(BTN,    INPUT_PULLUP);
    pinMode(BT,     INPUT_PULLUP);
    digitalWrite(Blanc, HIGH);
    strip.begin();
    strip.fill(strip.Color(255, 153, 0), 0, 2);// pixel color set to yellow
}

void task1 (unsigned long duration) {
    static unsigned long chrono = millis();
    static int Orange_State = LOW;
    if (millis() - chrono < duration) return;
    chrono = millis();
    Orange_State = !Orange_State;
    digitalWrite(Orange, Orange_State);
}

void task2 (unsigned long duration) {
    static unsigned long chrono = millis();
    static int Bleu_State = LOW;
    if (millis() - chrono < duration) return;
    chrono = millis();
    Bleu_State = !Bleu_State;
    digitalWrite(Bleu, Bleu_State);
}

void task5 (unsigned long duration) {
    static unsigned long chrono = millis();
    static int Rouge_State = LOW;
    static int compteur = 0;
    static bool run = false;

    // Traitement de l'appui sur le bouton (INPUT_PULLUP)
    if (digitalRead(BTN) == LOW) {
        run = true;
        compteur = 0;
        Rouge_State = HIGH;
        digitalWrite (Rouge, Rouge_State);
        chrono = millis();
        delay(30); // debounce
        return;
    }

    // Traitement des conditions de sortie
    if (!run) return;
    if (millis() - chrono < duration) return;

    // Clignotement
    chrono = millis();
    Rouge_State = !Rouge_State;
    digitalWrite (Rouge, Rouge_State);
    ++ compteur;
    if (compteur == 7) run = false;    // 7 car 4 allumages et 3 extinctions
}


    void loop() {
    // Task 1 LED Orange clignote rapidement
    task1 (interval_T4);

    // Task 2 LED bleu clignote lentement
    task2 (interval_T1);

    //Task 3 Neopixels s'allument en jaune et flicker 
    strip.setBrightness(random(150,255)); // random brightness adjust for flicker effect
    strip.show();

    // Task 4 LED Vert s'allume avec BT
    int button_state = digitalRead(BT);
    digitalWrite(Vert, !button_state);
    delay(30);

    for (int bright = 255; bright = 0; bright --) {
        strip.setBrightness(bright);
        strip.show();
    }

    // Task 5 LED Rouge flashe 4 fois avec BTN
    task5 (100); 
}

Elle est un peu plus compliquée que les autres, car il faut gérer le clignotement. Mais le principe reste le même... Reste à traiter le FADE de la tâche 4

Je veux éclairer/animer une maquette de vaisseau spatial en vol. Les LEDs bleue, blanche et orange sont dans le cockpit. La LED Rouge simule des lasers et la LED Vert des torpilles. Un appui sur le bouton BTN déclenche une rafale de 4 tirs laser. Un appui sur le bouton BT lance une torpille (d'ou un éclat plus lent et qui diminue progressivement). Si on garde le doit sur BTN, c'est normale que les lasers continuent à tirer. Par contre il faut du temps pour recharger une torpille donc la LED Verte doit s'éteindre et rester éteinte. Ça la fout mal si à chaque tir le cockpit s'éteint... :joy: Mais je n'ai pas encore réussi à comprendre comment écrire ces commandes.
J'espère que c'est plus claire.

Sans avoir l'air de vouloir critiquer, si je garde le bouton enfoncé, la led reste allumée. Elle ne clignote que quand on le relâche. Sinon tout le reste fonctionne bien (une fois que j'ai recablé le BTN correctement... :wink: ).

Merci pour ton aide. Je ne suis encore pas très familier avec la fonction void autre que setup et loop mais ça va venir. J'ai encore pas mal à étudier sur le langage (j'ai d'autres projets similaires en tête...).

C'est normal, je galère sur la led rouge... Mais ça viendra.
J'ai mis les deux boutons en INPUT_PULLUP : il faut les câbler en conséquence.

Voici une version qui fonctionne sur le wokwi :

#include <Adafruit_NeoPixel.h>
#define PIN 9
#define NUM_LEDS 2

// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   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     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, PIN, NEO_GRB + NEO_KHZ800);

#define BT 4
#define BTN 2
#define Vert 6
#define Rouge 10
#define Blanc 11
#define Orange 12
#define Bleu 13

int brightness = 0;
const long interval_Bleu   = 1500;
const long interval_Orange = 800;
const long interval_Rouge  = 250;


void setup() {
    Serial.begin(9600);
    pinMode(PIN,    OUTPUT);
    pinMode(Blanc,  OUTPUT);
    pinMode(Rouge,  OUTPUT);
    pinMode(Bleu,   OUTPUT);
    pinMode(Vert,   OUTPUT);
    pinMode(Orange, OUTPUT);
    pinMode(BTN,    INPUT_PULLUP);
    pinMode(BT,     INPUT_PULLUP);
    digitalWrite(Blanc, HIGH);
    strip.begin();
    strip.fill(strip.Color(255, 153, 0), 0, 2);// pixel color set to yellow
}

void task_Orange (unsigned long duration) {
    static unsigned long chrono = millis();
    static int Orange_State = LOW;
    if (millis() - chrono < duration) return;
    chrono = millis();
    Orange_State = !Orange_State;
    digitalWrite(Orange, Orange_State);
}

void task_Bleu (unsigned long duration) {
    static unsigned long chrono = millis();
    static int Bleu_State = LOW;
    if (millis() - chrono < duration) return;
    chrono = millis();
    Bleu_State = !Bleu_State;
    digitalWrite(Bleu, Bleu_State);
}

void task_Vert (unsigned long duration) {
    static unsigned long chrono = millis();
    static int bright = 0;
    static bool run = false;

    // Traitement du bouton
    if (digitalRead(BT) == LOW) {
        run = true;
        bright = 255;
        analogWrite (Vert, bright);
        chrono = millis();
        delay(30); // debounce
        return;
    }

    // Traitement des conditions de sortie
    if (!run) return;
    if (millis() - chrono < duration) return;

    // Fade
    chrono = millis();
    bright -= 3;  // Augmenter pour accélérer le fade
    analogWrite (Vert, bright);
    if (bright <= 0) run = false;
}

void task_Rouge (unsigned long duration) {
    static unsigned long chrono = millis();
    static int Rouge_State = LOW;
    static int Button_State = HIGH;
    static int Button_State_old = HIGH;
    static int compteur = 0;
    static bool run = false;

    // Traitement du bouton
    Button_State = digitalRead(BTN);
    if (Button_State == LOW) {
        run = true;
        compteur = 0;
    }

    // Traitement des conditions de sortie
    if (!run) return;
    if (millis() - chrono < duration) return;

    // Cligno
    chrono = millis();
    Rouge_State = !Rouge_State;
    digitalWrite (Rouge, Rouge_State);
    ++ compteur;
    if (compteur == 7) {
        run = false;
        digitalWrite (Rouge, LOW);
    }
}

void loop() {
    // Task 1 LED Orange clignote rapidement
    task_Orange (interval_Orange);

    // Task 2 LED bleu clignote lentement
    task_Bleu (interval_Bleu);

    //Task 3 Neopixels s'allument en jaune et flicker 
    strip.setBrightness(random(150,255)); // random brightness adjust for flicker effect
    strip.show();

    // Task 4 LED Vert s'allume avec BT
    task_Vert (5);   // Augmenter pour ralentir le fade

    // Task 5 LED Rouge flashe 4 fois avec BTN
    task_Rouge (interval_Rouge); 
}

Dis-moi si ça correspond à ce que tu veux faire.

Petite modification de la tâche rouge :

void task_Rouge (unsigned long duration) {
    static unsigned long chrono = millis();
    static int Rouge_State = LOW;
    static int Button_State = HIGH;
    static int Button_State_old = HIGH;
    static int compteur = 0;
    static bool run = false;

    // Traitement du bouton
    Button_State = digitalRead(BTN);
    if (Button_State == LOW) { // Bouton enfoncé
        run = true;
        compteur = 0;
        if (Button_State_old == HIGH) {  // Début d'appui sur le bouton
            chrono = millis();
            delay(30);
            Rouge_State = HIGH;
            digitalWrite (Rouge, Rouge_State);
            run = true;
        }
    }
    Button_State_old = Button_State;

    // Traitement des conditions de sortie
    if (!run) return;
    if (millis() - chrono < duration) return;

    // Cligno
    chrono = millis();
    Rouge_State = !Rouge_State;
    digitalWrite (Rouge, Rouge_State);
    ++ compteur;
    if (compteur >= 7) {
        run = false;
        digitalWrite (Rouge, LOW);
    }
}

Si ça fonctionne, peux-tu poster une petite vidéo de la maquette ? Merci :grin:

Oui ! C'est tout à fait ça. Curieusement ça ne marche pas sur Tinkercad mais ça marche sur wokwi. Je vais devoir m'y inscrire si je veux rajouter les Néopixels.

Ce sera avec plaisir, mais il va falloir être patient. La maquette n'est pas encore montée et je suis en déplacement à l'étranger jusqu'à la fin mars. Mais promis, je te fais ça.

Heuu... on installe le son tout de suite ou on attend après la vidéo ? :joy::joy::joy:

On peut en profiter pour mettre le son, maintenant qu'on a l'image...

J'ai le temps d'ici fin mars de m'y intéresser puisque l'image est pratiquement au point.

Sur Tinkercad, si j'active les Neopixels, ça fiche en l'air le reste du code. Tout tourne au ralenti. Mais si elles sont désactiver tout fonctionne au poil.
Sur wokwi, je ne peux pas rajouter de librairie pour utiliser les Neopixels.

Sur wokwi ?
Il n'est pas nécessaire de s'inscrire à la différence de Tinkercad.