Go Down

Topic: Leds strip/Projet phares arrière. Problème code pour clignoteur (Read 1 time) previous topic - next topic


lesept

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.
A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

J-M-L

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

Code: [Select]
#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;
  }
}
Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

Toinit

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

J-M-L

Jetez un oeil sur le code ci dessus, avec un peu de chance il va tomber en marche
Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

Toinit

Le code fonctionne :D  :D  :D . 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 ?







J-M-L

Quote
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
Code: [Select]
    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
Code: [Select]
      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

Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

Toinit

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

Toinit

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?

Toinit

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.


lesept

Pas facile de reprendre un code écrit par quelqu'un d'autre, fut-ce J-M-L... ;)
Poste le code en l'état et explique bien ce que tu veux en plus, comme si tu commençais un nouveau fil de discussion.
A force d'essayer on finit par réussir... Donc, plus ça rate, plus on a de chances que ça marche (proverbe Sharduinok).

J-M-L

J'ai pas répondu parce que j'aimerai bien que vous essayez de faire la modif...
Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

Toinit

 

Code: [Select]

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

const byte NUMPIXELS  = 18;

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 {FINIR_CLIGNOTE_DROITE, FINIR_CLIGNOTE_GAUCHE, REPOS} etat;

unsigned long chrono;
const unsigned long periodeClignotement = 30ul; // 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) != vert) {
          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 = FINIR_CLIGNOTE_GAUCHE;
      }
      else if (boutonDroite.estEnfonce()) {
        chrono = millis();
        etapeSuivante(pixelsClignoDroit);
        etat = FINIR_CLIGNOTE_DROITE;
      }
      break;

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

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


Pour l'instant, quand je lache le bouton, les leds s'éteignent toutes en meme temps.
J'aimerais que quand je lache le bouton,  les leds s'éteignent comme elles se sont allumées.(avec du dynamisme).
Dans le futur, j'aimerais ajouter au code, la fonction (frein), (marche arrière), (4 cligno warning) (dynamisme des cligno et des phares lors du verrouillage et deverouillage)...   mais ce sera dans un futur lointain a mon avis.

j'ai fait la modif FINIR_CLIGNO. Je pense que c'est bon, mais pour la fonction void etatpeSuivante() je comprend pas comment faire.



Go Up