3 boutons - 4 leds : comportement étrange...

bonjour

je suis sur un projet sur arduino UNO comportant 3 boutons - 4 leds. Le but est que chaque bouton allume une led (et éteigne les autres) et que deux pressions successives sur le même bouton allume une 4ème led (et éteigne les autres).
Je ne comprends pas pourquoi en appuyant successivement sur les 3 boutons, les 3 ou 4 premières fois cela fonctionne puis après ça allume la 4ème alors qu’aucun des boutons n’a été pressé deux fois de suite…

const byte pushButtons[] = {2,3,4};
const byte leds[] = {6,7,8};
int buttonPushCounter[] = {0,0,0};   // counter for the number of button presses
int buttonState[3];         // current state of the button

/**********************************************************************/
void setup()
{
  for(int l=0;l<3;l++)
  {
    pinMode(pushButtons[l], INPUT_PULLUP);
    pinMode(leds[l], OUTPUT);
  }
  pinMode(13, OUTPUT);
  digitalWrite(13, HIGH);
}
/**********************************************************************/

void resetAllLeds()
{
  for(int k=0; k<3; k++)
  {
    digitalWrite(leds[k], LOW);
   }
  digitalWrite(13, LOW);
}
/**********************************************************************/
void resetCounter()
{
  for(int j=0; j<3; j++)
  {
    buttonPushCounter[j]= 0;
  }
}  
/**********************************************************************/
void loop() //ok
{
  for(int i=0; i<3; i++)
  {
    buttonState[i] = digitalRead(pushButtons[i]); 
    switch (buttonState[i]) 
    {
      case HIGH:
        NULL;
        break;
      case LOW:
        buttonPushCounter[i]++;
        resetAllLeds();
        digitalWrite(leds[i], HIGH);
        delay(210);
        if(buttonPushCounter[i] > 1)
          {
            resetCounter();
            resetAllLeds();
            digitalWrite(13, HIGH);
           }
        break;
      }
  }
}

Si quelqu’un a une idée…

Bonjour,

Si c'est l'appui sur le bouton qui doit allumer une led, il faut que tu traites le changement d'état du bouton. Pour cela il faut que tu mémorises l'état précédent. Quand le bouton est enfoncé et n'était pas enfoncé au cycle précédent tu éclaires ta led et éteins les autres et incrémentes le compteur d'appui.

C’est pas le souci mais ça me choque:

const int push_A = 7;
const int push_B = 4;
const int push_C = 2;
const byte pushButtons[] = {push_A,push_B,push_C};

Pourquoi des int deviennent des byte ?? (les byte c’est mieux pour des N° de pin)

Ce serait mieux d’utiliser HIGH et LOW au lieu de 1 et 0 pour la lisibilité

Je dis peut-être une bêtise mais ne faudrait-il pas une gestion des rebonds des interrupteurs en plus ?

Oui Il y a un délai assez long lors d’un appui donc ça gomme les rebonds. Le risque est au relâchement

Ce serait mieux d'utiliser HIGH et LOW au lieu de 1 et 0 pour la lisibilité

à quel niveau ?

carranen: à quel niveau ?

Ici

 {
   buttonState[i] = digitalRead(pushButtons[i]); 
   switch (buttonState[i]) 
   {
     case 1:
       NULL;
       break;
     case 0:

Mais le principal problème est qu'il faut traiter l'appui sur les boutons avec le changement d'état et non l'état du bouton comme je te l'ai dit au post #1.

Pour simplifier votre gestion des boutons, éventuellement utilisez la librairie de @bricoleau

J-M-L: Pour simplifier votre gestion des boutons, éventuellement utilisez la librairie de @bricoleau

ok, je vais regarder. Ce qui est étonnant c'est que l'ensemble fonctionne parfaitement du moment que chaque bouton soit appuyé deux fois consécutivement, ce qui donne en apparence l'impression que les boutons sont bien gérés... Merci pour toutes vos réponses.

salut.

Je ne sais pas si ça donne l'apparence que les boutons sont bien gérés, mais ce n'est pas le cas. D'ailleurs tu as du t'en apercevoir car tu as du mettre un délai de 210ms pour que le bouton ne soit pas pris en compte plusieurs fois. Que se passe t'il si l'appui dure 220ms?

kamill: Je ne sais pas si ça donne l'apparence que les boutons sont bien gérés, mais ce n'est pas le cas. D'ailleurs tu as du t'en apercevoir car tu as du mettre un délai de 210ms pour que le bouton ne soit pas pris en compte plusieurs fois. Que se passe t'il si l'appui dure 220ms?

eh bien l'état passe alternativement HIGH/LOW tous les ~210 ms. Ce qui est tout-à-fait normal étant donné le code. J'ai compris en allant m'informer sur le net qu'un appui est composé d'un enclenchement et d'un déclenchement et que c'est bien cette deuxième phase qu'il faut prendre en compte pour un décompte... Toutefois en téléchargeant la librairie "simple bouton" du bricoleur, je n'ai pas trouvé d'exemple dans l'IDE faisant état d'un même bouton pressé deux fois de suite. Je cherche encore.

voici la simulation de ce circuit sur Thinkercad :

tu peux modifier des trucs, j'ai une autre copie.

J’ai modifié comme ça:

const byte pushButtons[] = {2,3,4};
const byte leds[] = {6,7,8};
int buttonPushCounter[] = {0,0,0};   // counter for the number of button presses

/**********************************************************************/
void setup()
{
  for(int l=0;l<3;l++)
  {
    pinMode(pushButtons[l], INPUT_PULLUP);
    pinMode(leds[l], OUTPUT);
  }
  pinMode(13, OUTPUT);
  digitalWrite(13, HIGH);
}
/**********************************************************************/

void resetAllLeds()
{
  for(int k=0; k<3; k++)
  {
    digitalWrite(leds[k], LOW);
   }
  digitalWrite(13, LOW);
}
/**********************************************************************/
void resetCounter()
{
  for(int j=0; j<3; j++)
  {
    buttonPushCounter[j]= 0;
  }
}  
/**********************************************************************/
void loop() //ok
{
  static bool prevButtonState[3] = {};  // état précédent du bouton
  bool buttonState;
  for (byte i = 0; i < 3; i++)
  {
    buttonState = !digitalRead(pushButtons[i]); // ! pour raisonner en logique positive
    if (buttonState != prevButtonState[i])
    {
      // le bouton a changé dtétat
      prevButtonState[i] = buttonState;
      if (buttonState)
      {
        // on vient d'enfoncer le bouton
        if (buttonPushCounter[i] == 0)
        {
          // premier appui sur le bouton
          resetCounter();
          resetAllLeds();
          buttonPushCounter[i]++;
          digitalWrite(leds[i], HIGH);
        }
        else
        {
          // deuxième appui sur le bouton
          resetCounter();
          resetAllLeds();
          digitalWrite(13, HIGH);
        }
      }
      delay(20);  // anti rebond
    }
  }
}

Pourquoi tu as mis des diodes?

carranen: voici la simulation de ce circuit sur Thinkercad :

tu peux modifier des trucs, j'ai une autre copie.

au passage c'est nul de poster à 2 endroits du forum - même si c'est dans une autre langue...

kamill:
J’ai modifié comme ça:

const byte pushButtons[] = {2,3,4};

const byte leds = {6,7,8};
int buttonPushCounter = {0,0,0};  // counter for the number of button presses

//
void setup()
{
  for(int l=0;l<3;l++)
  {
    pinMode(pushButtons[l], INPUT_PULLUP);
    pinMode(leds[l], OUTPUT);
  }
  pinMode(13, OUTPUT);
  digitalWrite(13, HIGH);
}
/
/

void resetAllLeds()
{
  for(int k=0; k<3; k++)
  {
    digitalWrite(leds[k], LOW);
  }
  digitalWrite(13, LOW);
}
//
void resetCounter()
{
  for(int j=0; j<3; j++)
  {
    buttonPushCounter[j]= 0;
  }

/
/
void loop() //ok
{
  static bool prevButtonState[3] = {};  // état précédent du bouton
  bool buttonState;
  for (byte i = 0; i < 3; i++)
  {
    buttonState = !digitalRead(pushButtons[i]); // ! pour raisonner en logique positive
    if (buttonState != prevButtonState[i])
    {
      // le bouton a changé dtétat
      prevButtonState[i] = buttonState;
      if (buttonState)
      {
        // on vient d’enfoncer le bouton
        if (buttonPushCounter[i] == 0)
        {
          // premier appui sur le bouton
          resetCounter();
          resetAllLeds();
          buttonPushCounter[i]++;
          digitalWrite(leds[i], HIGH);
        }
        else
        {
          // deuxième appui sur le bouton
          resetCounter();
          resetAllLeds();
          digitalWrite(13, HIGH);
        }
      }
      delay(20);  // anti rebond
    }
  }
}



Pourquoi tu as mis des diodes?

WOW! j’aurais été bien incapable d’arriver à cela tout seul, merci pour tout ! Les diodes sont là pour éliminer un peu le bruit de rebond, ça se fait couramment dans les circuits similaires en électronique. Je les ai rajoutées à un moment en pensant que c’était un problème hardware mais effectivement elles n’ont plus vraiment lieu d’être bien que ça ne gêne en rien le fonctionnement général. Chaleureuses salutations.

J-M-L: au passage c'est nul de poster à 2 endroits du forum - même si c'est dans une autre langue...

Au contraire, ça maximise le nombre de réponses potentielles. Je l'ai rédigé d'abord en anglais mais n'étant pas vraiment à l'aise dans cette langue, et vu l'acceuil chaleureux des intervenants je me suis décidé à le poster ici. Cheers!

carranen: Au contraire, ça maximise le nombre de réponses potentielles.

C’est une vue bien égoïste.

Vous obtenez des doublons de réponses sans que les participants ne voient ce qui a déjà été proposé; c’est contraire aux règles (lisez les posts épinglés en début de forum) et à l’éthiques générale des forums - ce qui me surprend vu votre ranking en karma, vous devriez le savoir même si vous avez peu de post.

Les diodes sont là pour éliminer un peu le bruit de rebond, ça se fait couramment dans les circuits similaires en électronique.

ah bon ?? Vous avez lu/vu ça où ?

Bref - pas aligné sur votre vue, donc je vous laisse maximiser le temps des autres, je vais allouer le mien ailleurs