Leds strip/Projet phares arrière. Problème code pour clignoteur

Merci encore pour toutes ces explications. Mon exemple de code que vous avez modifier m'aide énormément a comprendre comment cela fonctionne. J'ai bien les 0 et les 1 qui défilent quand j'appuie sur les boutons.(c'est bien fait d'ailleurs) mais ca ne fonctionne que si je passe le serial.begin a 9600. Pouvez vous me dire pourquoi? l'autre petit souci c'est que mes leds ne s'allume pas, croyez vous que c'est a cause de la bibliothèque adafruit neopixel qui n'est pas présente?

mais ca ne fonctionne que si je passe le serial.begin a 9600

Sans doute parce que dans le pop up associé à la console série vous avez choisi 9600 —> passer ça à 115200

Bien sûr c’est une démo sans LEDs... je vous montre comment gérer cela dans un tableau et l’imprimer —> à adapter à votre code, mettre les librairies pour les pixels et modifier à la fois potentiellement la gestion du tableau et la fonction d'affichage pour adapter à votre cas

Je vous assure que je fais tout pour comprendre et faire fonctionner tout ca, mais ou bout d'un moment, je mélange tout. La seul chose que je sais faire, c'est recopier un code qui correspond plus ou moins a mon montage, et le modifier tant bien que mal pour avoir un résultat plus ou moins espérer. Pour moi, c'est comme un jeu d'échec ou il faudrait avoir 100 coups d'avance pour pouvoir gagné, ce qui pour moi, est impossible. Allumé une led et la faire clignoter, ok, c'est dans mes cordes mais je suis arrivé a un stade ou je ne comprend plus rien. Svp pourriez vous modifier mon code pour que mes bandes leds fonctionnent comme dans le serial moniteur ?

Remplacez mes tableaux par vos tableaux de LEDs et modifiez la fonction afficherPixels() pour qu’elle appelle la fonction d’allumage des bandeaux au lieu d’imprimer sur le port série

je n'y arrive pas.

postez votre essai...

je ne comprend pas comment il faut procéder.

#include <simpleBouton.h> // http://forum.arduino.cc/index.php?topic=375232.0
#include <Adafruit_NeoPixel.h>

const byte NUMPIXELS  = 5;

Adafruit_NeoPixel clignoGauche = Adafruit_NeoPixel(NUMPIXELS, 5, NEO_RGBW + NEO_KHZ800);
Adafruit_NeoPixel clignoDroit = Adafruit_NeoPixel(NUMPIXELS, 6, NEO_RGBW + NEO_KHZ800);

byte clignoDroit[NUMPIXELS];
byte clignoGauche[NUMPIXELS];
enum : byte {ETEINT, ALLUME};

const byte pin_ClignoGauche = 2;
const byte pin_ClignoDroit = 7;

simpleBouton boutonGauche(pin_ClignoGauche); //Cablage : pin---BP---GND (le bouton sera en INPUT_PULLUP)
simpleBouton boutonDroite(pin_ClignoDroit); //Cablage : pin---BP---GND (le bouton sera en INPUT_PULLUP)

enum : byte {REPOS, CLIGNOTE_GAUCHE, CLIGNOTE_DROITE} etat;

unsigned long chrono;
const unsigned long periodeClignotement = 1000ul; // ici 1s pour qu'on voit ce qu'il se passe, 20ul pour 20ms

void afficherPixels()
{

  for (int i = NUMPIXELS - 1; i >= 0 ; i--)
    if (clignoGauche[i] == ETEINT) {
      clignoGauche.setPixelColor(i, clignoGauche.Color(0, 0, 0));
      clignoGauche.show();
    }
    else
    {
      clignoGauche.setPixelColor (i, clignoGauche.Color(80, 255, 0));
      clignoGauche.show();
    }




for (int i = 0; i < NUMPIXELS; i++)
  if (clignoDroit[i] == ETEINT)
  {
    clignoDroit.setPixelColor(i, clignoDroit.Color(0, 0, 0));
    clignoDroit.show();
  }

  else
  {
    clignoDroit.setPixelColor (i, clignoDroit.Color(80, 255, 0));
    clignoDroit.show();
  }

}

void etapeSuivante(byte bandeDePixel[])
{
  int unPixel;

  for (unPixel = 0; unPixel < NUMPIXELS; unPixel++)
    if (bandeDePixel[unPixel] == ALLUME) break;

  if (unPixel == NUMPIXELS) bandeDePixel[0] = ALLUME;  // s'ils sont tous éteint c'est qu'on commence
  else {
    // si le premier pixel est allumé et pas le dernier c'est qu'on "monte"
    if ((bandeDePixel[0] == ALLUME) && (bandeDePixel[NUMPIXELS - 1] == ETEINT)) {
      // on cherche le premier pas allumé et on l'allume
      for (unPixel = 0; unPixel < NUMPIXELS; unPixel++) {
        if (bandeDePixel[unPixel] == ETEINT) {
          bandeDePixel[unPixel] = ALLUME;
          break;
        }
      }
    } else {
      // c'est qu'on descend
      // on cherche le premier allumé et on l'éteint
      for (unPixel = 0; unPixel < NUMPIXELS; unPixel++) {
        if (bandeDePixel[unPixel] == ALLUME) {
          bandeDePixel[unPixel] = ETEINT;
          break;
        }
      }
    }
  }
  // on rend visible notre modif
  afficherPixels();
}

void mettreAuRepos()
{
  for (byte i = 0; i < NUMPIXELS; i++) {
    clignoDroit[i] = ETEINT;
    clignoGauche[i] = ETEINT;
  }
  afficherPixels();
  etat = REPOS;
}

void actualiserLesBoutons()
{
  boutonGauche.actualiser();
  boutonDroite.actualiser();
}

void setup() {
  
  mettreAuRepos();
}

void loop() {

  // on teste les boutons
  actualiserLesBoutons();

  // on prend une décision
  switch (etat) {
    case REPOS:
      if (boutonGauche.estEnfonce()) {
        chrono = millis();
        etapeSuivante(clignoGauche);
        etat = CLIGNOTE_GAUCHE;
      }
      else if (boutonDroite.estEnfonce()) {
        chrono = millis();
        etapeSuivante(clignoDroit);
        etat = CLIGNOTE_DROITE;
      }
      break;

    case CLIGNOTE_GAUCHE:
      if (boutonGauche.vientDEtreRelache()) mettreAuRepos();
      else if (millis() - chrono >= periodeClignotement) {
        etapeSuivante(clignoGauche);
        chrono += periodeClignotement;
      }
      else if (boutonDroite.vientDEtreEnfonce()) {
        mettreAuRepos();
        chrono = millis();
        etapeSuivante(clignoDroit);
        etat = CLIGNOTE_DROITE;
      }
      break;

    case CLIGNOTE_DROITE:
      if (boutonDroite.estRelache()) mettreAuRepos();
      else if (millis() - chrono >= periodeClignotement) {
        etapeSuivante(clignoDroit);
        chrono += periodeClignotement;
      }
      else if (boutonGauche.vientDEtreEnfonce()) {
        mettreAuRepos();
        chrono = millis();
        etapeSuivante(clignoGauche);
        etat = CLIGNOTE_GAUCHE;
      }
      break;
  }
}

les 2 tableaux

byte clignoDroit[NUMPIXELS];
byte clignoGauche[NUMPIXELS];

ne doivent plus exister.

il faut directement utiliser

Adafruit_NeoPixel clignoGauche = Adafruit_NeoPixel(NUMPIXELS, 5, NEO_RGBW + NEO_KHZ800);
Adafruit_NeoPixel clignoDroit = Adafruit_NeoPixel(NUMPIXELS, 6, NEO_RGBW + NEO_KHZ800);

et remplacer là où je mets vrai ou faux dans le tableau par des couleurs (avec clignoGauche.setPixelColor() ou clignoDroit.setPixelColor()) et tester la couleur (allumé ou éteint)

Une fois que c'est fait le code d'affichage est alors simplement

void afficherPixels()
{
    clignoGauche.show();
    clignoDroit.show();
}

les pixels qu'on allume

si vous voulez garder à la fois mes tableaux ET la mémoire associée aux LEDs, alors oui il faut recopier l'état des LEDS avant de faire l'affichage sans doute un

void afficherPixels()
{

  for (int i = NUMPIXELS - 1; i >= 0 ; i--)
    if (clignoGauche[i] == ETEINT) {
      clignoGauche.setPixelColor(i, clignoGauche.(Color(0, 0, 0));
    } else {
      clignoGauche.setPixelColor (i, clignoGauche.Color(80, 255, 0));
    }
  clignoGauche.show();

  for (int i = 0; i < NUMPIXELS; i++)
    if (clignoDroit[i] == ETEINT)
    {
      clignoDroit.setPixelColor(i, clignoDroit.Color(0, 0, 0));
    } else {
      clignoDroit.setPixelColor (i, clignoDroit.Color(80, 255, 0));
    }
  clignoDroit.show();

}

mais c'est un peu bête.. autant utiliser la mémoire du ruban directement

comme ceci ?

#include <simpleBouton.h> // http://forum.arduino.cc/index.php?topic=375232.0
#include <Adafruit_NeoPixel.h>

const byte NUMPIXELS  = 5;

Adafruit_NeoPixel clignoGauche = Adafruit_NeoPixel(NUMPIXELS, 5, NEO_RGBW + NEO_KHZ800);
Adafruit_NeoPixel clignoDroit = Adafruit_NeoPixel(NUMPIXELS, 6, NEO_RGBW + NEO_KHZ800);


enum : byte {ETEINT, ALLUME};

const byte pin_ClignoGauche = 2;
const byte pin_ClignoDroit = 7;

simpleBouton boutonGauche(pin_ClignoGauche); //Cablage : pin---BP---GND (le bouton sera en INPUT_PULLUP)
simpleBouton boutonDroite(pin_ClignoDroit); //Cablage : pin---BP---GND (le bouton sera en INPUT_PULLUP)

enum : byte {REPOS, CLIGNOTE_GAUCHE, CLIGNOTE_DROITE} etat;

unsigned long chrono;
const unsigned long periodeClignotement = 1000ul; // ici 1s pour qu'on voit ce qu'il se passe, 20ul pour 20ms

void afficherPixels()
{

  clignoGauche.show();
    clignoDroit.show();

}

void etapeSuivante(byte bandeDePixel[])
{
  int unPixel;

  for (unPixel = 0; unPixel < NUMPIXELS; unPixel++)
    if (bandeDePixel[unPixel] == ALLUME) break;

  if (unPixel == NUMPIXELS) bandeDePixel[0] = ALLUME;  // s'ils sont tous éteint c'est qu'on commence
  else {
    // si le premier pixel est allumé et pas le dernier c'est qu'on "monte"
    if ((bandeDePixel[0] == ALLUME) && (bandeDePixel[NUMPIXELS - 1] == ETEINT)) {
      // on cherche le premier pas allumé et on l'allume
      for (unPixel = 0; unPixel < NUMPIXELS; unPixel++) {
        if (bandeDePixel[unPixel] == ETEINT) {
          bandeDePixel[unPixel] = ALLUME;
          break;
        }
      }
    } else {
      // c'est qu'on descend
      // on cherche le premier allumé et on l'éteint
      for (unPixel = 0; unPixel < NUMPIXELS; unPixel++) {
        if (bandeDePixel[unPixel] == ALLUME) {
          bandeDePixel[unPixel] = ETEINT;
          break;
        }
      }
    }
  }
  // on rend visible notre modif
  afficherPixels();
}

void mettreAuRepos()
{
  
  
  afficherPixels();
  etat = REPOS;
}

void actualiserLesBoutons()
{
  boutonGauche.actualiser();
  boutonDroite.actualiser();
}

void setup() {
  
  mettreAuRepos();
}

void loop() {


  // on teste les boutons
  actualiserLesBoutons();

  // on prend une décision
  switch (etat) {
    case REPOS:
      if (boutonGauche.estEnfonce()) {
        chrono = millis();
        Adafruit_NeoPixel clignoGauche = Adafruit_NeoPixel(NUMPIXELS, 5, NEO_RGBW + NEO_KHZ800);
        clignoGauche.setPixelColor ( clignoGauche.Color(0, 0, 0));
        etat = CLIGNOTE_GAUCHE;
      }
      else if (boutonDroite.estEnfonce()) {
        chrono = millis();
        Adafruit_NeoPixel clignoDroit = Adafruit_NeoPixel(NUMPIXELS, 6, NEO_RGBW + NEO_KHZ800);
        clignoDroit.setPixelColor( clignoDroit.Color(0, 0, 0));
        etat = CLIGNOTE_DROITE;
      }
      break;

    case CLIGNOTE_GAUCHE:
      if (boutonGauche.vientDEtreRelache()) mettreAuRepos();
      else if (millis() - chrono >= periodeClignotement) {
        Adafruit_NeoPixel clignoGauche = Adafruit_NeoPixel(NUMPIXELS, 5, NEO_RGBW + NEO_KHZ800);
        clignoGauche.setPixelColor ( clignoGauche.Color(0, 0, 0));
        chrono += periodeClignotement;
      }
      else if (boutonDroite.vientDEtreEnfonce()) {
        mettreAuRepos();
        chrono = millis();
        Adafruit_NeoPixel clignoGauche = Adafruit_NeoPixel(NUMPIXELS, 5, NEO_RGBW + NEO_KHZ800);
        clignoGauche.setPixelColor ( clignoGauche.Color(80, 255, 0));
        
        etat = CLIGNOTE_DROITE;
      }
      break;

    case CLIGNOTE_DROITE:
      if (boutonDroite.estRelache()) mettreAuRepos();
      else if (millis() - chrono >= periodeClignotement) {
        Adafruit_NeoPixel clignoDroit = Adafruit_NeoPixel(NUMPIXELS, 6, NEO_RGBW + NEO_KHZ800);
        clignoDroit.setPixelColor( clignoDroit.Color(0, 0, 0));
        
        chrono += periodeClignotement;
      }
      else if (boutonGauche.vientDEtreEnfonce()) {
        mettreAuRepos();
        chrono = millis();
        Adafruit_NeoPixel clignoDroit = Adafruit_NeoPixel(NUMPIXELS, 6, NEO_RGBW + NEO_KHZ800);
        clignoDroit.setPixelColor( clignoDroit.Color(80, 255, 0));
       
        etat = CLIGNOTE_GAUCHE;
      }
      break;
  }
}

Non...

pourquoi vous avezAdafruit_NeoPixel clignoGauche = Adafruit_NeoPixel(NUMPIXELS, 5, NEO_RGBW + NEO_KHZ800);dans le

  switch (etat) {
    case REPOS:....

vous devriez mettre le projet de côté et lire un tuto sur le langage C et les bases du C++

En essayant au hasard vous n'arrivez à rien

j'abandonne tout cour

N"abandonne pas : apprends à ta vitesse avec des tutos sur d'autres sujets qui te permettront de bien comprendre le langage C et reviens sur ton projet lorsque tu te sentiras plus à l'aise. Tu sais déjà les points sur lesquels tu dois t'améliorer : switch / case, machine d'états, etc.

Toinit:
j'abandonne tout court

Si on l'ecrit Pour vous vous n'aurez rien appris... Faut batailler. Et quand vous aurez votre premier programme perso fonctionnel vous serez super content!

allez pour vous aider à avancer, jetez un oeil sur ce code: j'ai simplement conservé ma structure de code ci dessus et remplacé la lecture des pixels dans le tableau par la lecture de leur couleur dans la bande. j'ai tapé cela ici, je ne sais même pas si ça compile et encore moins si ça va fonctionner. à vous de creuser

#include <simpleBouton.h> // http://forum.arduino.cc/index.php?topic=375232.0
#include <Adafruit_NeoPixel.h>

const byte NUMPIXELS  = 5;

Adafruit_NeoPixel pixelsClignoGauche = Adafruit_NeoPixel(NUMPIXELS, 5, NEO_RGBW + NEO_KHZ800);
Adafruit_NeoPixel pixelsClignoDroit = Adafruit_NeoPixel(NUMPIXELS, 6, NEO_RGBW + NEO_KHZ800);

uint32_t noir, vert;
const byte pin_ClignoGauche = 2;
const byte pin_ClignoDroit = 7;

simpleBouton boutonGauche(pin_ClignoGauche); //Cablage : pin---BP---GND (le bouton sera en INPUT_PULLUP)
simpleBouton boutonDroite(pin_ClignoDroit); //Cablage : pin---BP---GND (le bouton sera en INPUT_PULLUP)

enum : byte {REPOS, CLIGNOTE_GAUCHE, CLIGNOTE_DROITE} etat;

unsigned long chrono;
const unsigned long periodeClignotement = 1000ul; // ici 1s pour qu'on voit ce qu'il se passe, 20ul pour 20ms

void afficherPixels()
{
  pixelsClignoGauche.show();
  pixelsClignoDroit.show();
}

void etapeSuivante(Adafruit_NeoPixel& bandeDePixel)
{
  int unPixel;

  for (unPixel = 0; unPixel < NUMPIXELS; unPixel++)
    if (bandeDePixel.getPixelColor(unPixel) != noir) break; // on en a trouvé un allumé

  if (unPixel == NUMPIXELS) bandeDePixel.setPixelColor(0, vert); // allumé s'ils sont tous éteint c'est qu'on commence
  else {
    // si le premier pixel est allumé et pas le dernier c'est qu'on "monte"
    if ((bandeDePixel.getPixelColor(0) != noir) && (bandeDePixel.getPixelColor(NUMPIXELS - 1) == noir)) {
      // on cherche le premier pas allumé et on l'allume
      for (unPixel = 0; unPixel < NUMPIXELS; unPixel++) {
        if (bandeDePixel.getPixelColor(unPixel) != noir) {
          bandeDePixel.setPixelColor(unPixel, vert); // allumé
          break;
        }
      }
    } else {
      // c'est qu'on descend
      // on cherche le premier allumé et on l'éteint
      for (unPixel = 0; unPixel < NUMPIXELS; unPixel++) {
        if (bandeDePixel.getPixelColor(unPixel) != noir) {
          bandeDePixel.setPixelColor(unPixel, noir); //éteint
          break;
        }
      }
    }
  }
  // on rend visible notre modif
  afficherPixels();
}

void mettreAuRepos()
{
  pixelsClignoGauche.clear();
  pixelsClignoDroit.clear();
  etat = REPOS;
  afficherPixels();
}

void actualiserLesBoutons()
{
  boutonGauche.actualiser();
  boutonDroite.actualiser();
}

void setup() {
  Serial.begin(115200);
  pixelsClignoGauche.begin();
  pixelsClignoDroit.begin();
  noir = pixelsClignoGauche.Color(0, 0, 0);
  vert = pixelsClignoGauche.Color(80, 255, 0);
  mettreAuRepos();
}

void loop() {

  // on teste les boutons
  actualiserLesBoutons();

  // on prend une décision
  switch (etat) {
    case REPOS:
      if (boutonGauche.estEnfonce()) {
        chrono = millis();
        etapeSuivante(pixelsClignoGauche);
        etat = CLIGNOTE_GAUCHE;
      }
      else if (boutonDroite.estEnfonce()) {
        chrono = millis();
        etapeSuivante(pixelsClignoDroit);
        etat = CLIGNOTE_DROITE;
      }
      break;

    case CLIGNOTE_GAUCHE:
      if (boutonGauche.vientDEtreRelache()) mettreAuRepos();
      else if (millis() - chrono >= periodeClignotement) {
        etapeSuivante(pixelsClignoGauche);
        chrono += periodeClignotement;
      }
      else if (boutonDroite.vientDEtreEnfonce()) {
        mettreAuRepos();
        chrono = millis();
        etapeSuivante(pixelsClignoDroit);
        etat = CLIGNOTE_DROITE;
      }
      break;

    case CLIGNOTE_DROITE:
      if (boutonDroite.estRelache()) mettreAuRepos();
      else if (millis() - chrono >= periodeClignotement) {
        etapeSuivante(pixelsClignoDroit);
        chrono += periodeClignotement;
      }
      else if (boutonGauche.vientDEtreEnfonce()) {
        mettreAuRepos();
        chrono = millis();
        etapeSuivante(pixelsClignoGauche);
        etat = CLIGNOTE_GAUCHE;
      }
      break;
  }
}

Merci beaucoup de m'encourager. Je vais batailler et je vais y arriver. Merci encore a tout le monde.

Jetez un oeil sur le code ci dessus, avec un peu de chance il va tomber en marche

Le code fonctionne :smiley: :smiley: :smiley: . J'ai juste remplacer "noir" par "vert" dans la fonction "void etapeSuivante(...)" a la condition "on cherche le premier pas allumé et on l'allume".

Mais il y a un petit souci.

La fonction mettreAuRepos(); doit s'exécutée que si le bouton opposé est enfoncé, exemple :

Si bouton gauche enfoncé(le cycle de clignotement gauche commence). Si relaché, le cycle de clignotement continue jusqu'a ce que toutes les leds soient éteintes, puis ont passe a la fonction mettreAuRepos.

Si le cycle de clignotement (bouton gauche) n'est pas terminé et qu'on enfonce le bouton droit, la fonction mettreAuRepos doit s'exécuté. Le cycle de clignotement (bouton gauche) s'interrompt et le cycle de clignotement (bouton droit) doit commencer.

En conclusion, il me faut une fonction etapeSuivante dont son exécution commence au relachement des boutons et se termine quand la derniere leds est éteintes mais il faut que la fonction etapeSuivante soit interrompue si l'autre bouton est enfoncé.
Comment pourrais je faire ?

Si bouton gauche enfoncé(le cycle de clignotement gauche commence). Si relaché, le cycle de clignotement continue jusqu'a ce que toutes les leds soient éteintes, puis ont passe a la fonction mettreAuRepos.

Euh...sur ma voiture quand je désactive mon clignotant il s'éteint instantanément, il ne continue pas à clignoter " un peu" (sauf mode impulsion où il clignote trois fois).

Mais bon, ça veut dire qu'il faut créer des états supplémentaires, tout simplement.. au lieu de

    case CLIGNOTE_GAUCHE:
      if (boutonGauche.vientDEtreRelache()) mettreAuRepos();

il faut passer dans un état FINIR_CLIGNOTE_GAUCHE (idem à droite)

la notion de "finir le clignotement" n'étant pas définie pour le moment il faut par exemple modifier la fonction void etapeSuivante(byte bandeDePixel[]) pour qu'elle retourne un booléen qui dit si à la sortie tout est éteint. comme cela dans FINIR_CLIGNOTE_GAUCHE (et idem à droite) on testera s'il faut clignoter et si oui on testera si on a tout éteint et testant la valeur retournée par la fonction etapeSuivante() --> un truc du genre

      if (millis() - chrono >= periodeClignotement) {
        if (etapeSuivante(pixelsClignoGauche)) mettreAuRepos();
        else chrono += periodeClignotement;
      }

bien sûr dans cette étape il faut aussi tenir compte (éventuellement à vous de voir) de l'appui sur l'autre bouton donc on rajoutera comme dans l'état CLIGNOTE_GAUCHE la détection de l'appui sur droite

Pouvez vous faire le code Svp. Je ne suis pas encore prêt pour comprendre tout ça.

Doit je remplacer case CLIGNO GAUCHE par FINIR CLIGNO GAUCHE ? ou ajouter case FINIR CLIGNO GAUCHE dans enum état en plus de case CLIGNO GAUCHE?

Merci infiniment J-M-L, pour tout ce que vous avez fait pour m'aider. Vous devez être complètement épuisé de moi (tout a fait normal, je comprend)

C'est pour cela que je demande a quelqu'un d'autres pour m'aider a finir mon code svp.