Problème de boutons pour coder un Simon

Bonjour à tous,
Je suis nouvelle sur ce forum (et sur les forums en général d'ailleurs !...) donc je m'excuse si tout n'est pas fait dans les règles de l'art ou si le vocabulaire n'est très rigoureux !
Je suis en 1ère et pour cette fin d'année, nous devons créer un projet. J'ai choisi de coder le célèbre jeu Simon avec Arduino. Ne connaissant rien d'Arduino il y a 3 semaines mes capacités sont assez limitées mais je souhaite apprendre !
Donc voici mon problème :
Il faut que l'utilisateur répète la séquence affichée à l'aide des boutons poussoirs. Cependant, la boucle while (pour remplir le tableau de réponses lorsque l'appui sur un bouton est détecté) "tourne" trop vite. Ainsi un appui trop long sur un bouton comptera deux fois celui-ci. Et inversement, en essayant de résoudre le problème, parfois la boucle est dans un "autre if" ce qui ne comptabilise pas l'appui du bouton.
Au début j'ai essayé de résoudre le problème à l'aide des delay, cela marchait mieux mais ce n'est clairement pas la solution adéquate. Après quelques heures de lecture sur des forums j'ai découvert que les bibliothèques pouvaient éventuellement résoudre ce problème (d'où l'état actuel de mon code). Cependant, malgré avoir essayé toutes les possibilités, le problème ne se résout pas.
Sinon, je suis consciente que des codes pour faire un Simon existent déjà mais si j'essaie de m'inspirer de leurs techniques pour les boutons, il faut que je revoie complètement toute la logique de mon code.
Connaitriez-vous alors une solution pour résoudre ce problème ?
Merci d'avance pour vos réponses

#include "simpleBouton.h"

int ledPinY = 12;
int ledPinB = 11;
int ledPinR = 10;
int ledPinG = 9;

int compteur = 0;
int cptbouton = 0;

simpleBouton buttonYpin(7);
simpleBouton buttonBpin(6);
simpleBouton buttonRpin(5);
simpleBouton buttonGpin(3);

int Enchainement[20];  //Créer la liste avec l'enchainement des couleurs


void setup() {
  pinMode(ledPinY, OUTPUT);
  pinMode(ledPinB, OUTPUT);
  pinMode(ledPinR, OUTPUT);
  pinMode(ledPinG, OUTPUT);


  pinMode(buttonYpin, INPUT_PULLUP);
  pinMode(buttonBpin, INPUT_PULLUP);
  pinMode(buttonRpin, INPUT_PULLUP);
  pinMode(buttonGpin, INPUT_PULLUP);
}


void loop() {
  randomSeed(analogRead(0));  //Générer un nombre aléatoire entre 1 et 4
  int Couleur = random(1, 5);

  int Reponse[20];  //Créer une liste vide pour stocker les réponses du joueur

  Enchainement[compteur] = Couleur;  //Ajoute la couleur générée aléatoirement à l'enchainement

  compteur = compteur + 1;
  cptbouton = 0;

  buttonYpin.actualiser();
  buttonBpin.actualiser();
  buttonGpin.actualiser();
  buttonRpin.actualiser();


  // Permet d'afficher l'enchainement des couleurs
  for (byte i = 0; i < compteur; i = i + 1) {
    if (Enchainement[i] == 1) {
      digitalWrite(ledPinY, HIGH);
      delay(1000);
      digitalWrite(ledPinY, LOW);
      delay(1000);
    }
    if (Enchainement[i] == 2) {
      digitalWrite(ledPinB, HIGH);
      delay(1000);
      digitalWrite(ledPinB, LOW);
      delay(1000);
    }
    if (Enchainement[i] == 3) {
      digitalWrite(ledPinR, HIGH);
      delay(1000);
      digitalWrite(ledPinR, LOW);
      delay(1000);
    }
    if (Enchainement[i] == 4) {
      digitalWrite(ledPinG, HIGH);
      delay(1000);
      digitalWrite(ledPinG, LOW);
      delay(1000);
    }
  }


  //enregistrer les réponses de l'utilisateur
  while (cptbouton != compteur) {
    if (buttonYpin.estEnfonceDepuisAuMoins(100)) {
      Reponse[cptbouton] = 1;
      cptbouton = cptbouton + 1;
    }
    if (buttonBpin.estEnfonceDepuisAuMoins(100)) {
      Reponse[cptbouton] = 2;
      cptbouton = cptbouton + 1;
    }
    if (buttonRpin.estEnfonceDepuisAuMoins(100)) {
      Reponse[cptbouton] = 3;
      cptbouton = cptbouton + 1;
    }
    if (buttonGpin.estEnfonceDepuisAuMoins(100)) {
      Reponse[cptbouton] = 4;
      cptbouton = cptbouton + 1;
    }
  }


  //Comparer les réponses du joueur avec les couleurs de l'ordinateur
  for (byte i = 0; i < compteur; i = i + 1) {
    if (Reponse[i] != Enchainement[i]) {  //si l'utilisateur ne rentre pas la bonne combinaison, tout afficher puis tout éteindre
      digitalWrite(ledPinY, HIGH);
      digitalWrite(ledPinB, HIGH);
      digitalWrite(ledPinR, HIGH);
      digitalWrite(ledPinG, HIGH);
      delay(1000);
      digitalWrite(ledPinY, LOW);
      digitalWrite(ledPinB, LOW);
      digitalWrite(ledPinR, LOW);
      digitalWrite(ledPinG, LOW);
      exit(0);
    }
  }
}

This may give you some ideas:
An Easy ‘Simon’ Game – Arduino++ (wordpress.com)

hello
il ne faut prendre en compte un appui sur un BP que si celui ci était relaché avant.
ex:
BP relaché, flag du BP=true
si BP enfoncé et flag du BP==true alors prise en compte, et remise à false du flag du BP

à la boucle suivante, l'appui ne sera pas pris en compte puisque le flag est à zéro.

le flag ne repassera à true qu'au relachement du BP

à la boucle suivante, si le BP est enfoncé, comme le flag est true , l'appui sera pris en compte

nota: je n'ai pas testé

#include "simpleBouton.h"

int ledPinY = 12;
int ledPinB = 11;
int ledPinR = 10;
int ledPinG = 9;

int compteur = 0;
int cptbouton = 0;

simpleBouton buttonYpin(7);
simpleBouton buttonBpin(6);
simpleBouton buttonRpin(5);
simpleBouton buttonGpin(3);

int Enchainement[20];  //Créer la liste avec l'enchainement des couleurs

bool BP_repos[5] = {true, true, true, true, true};

void setup() {
  pinMode(ledPinY, OUTPUT);
  pinMode(ledPinB, OUTPUT);
  pinMode(ledPinR, OUTPUT);
  pinMode(ledPinG, OUTPUT);


  pinMode(buttonYpin, INPUT_PULLUP);
  pinMode(buttonBpin, INPUT_PULLUP);
  pinMode(buttonRpin, INPUT_PULLUP);
  pinMode(buttonGpin, INPUT_PULLUP);
}


void loop() {
  randomSeed(analogRead(0));  //Générer un nombre aléatoire entre 1 et 4
  int Couleur = random(1, 5);

  int Reponse[20];  //Créer une liste vide pour stocker les réponses du joueur

  Enchainement[compteur] = Couleur;  //Ajoute la couleur générée aléatoirement à l'enchainement

  compteur = compteur + 1;
  cptbouton = 0;

  buttonYpin.actualiser();
  buttonBpin.actualiser();
  buttonGpin.actualiser();
  buttonRpin.actualiser();


  // Permet d'afficher l'enchainement des couleurs
  for (byte i = 0; i < compteur; i = i + 1) {
    if (Enchainement[i] == 1) {
      digitalWrite(ledPinY, HIGH);
      delay(1000);
      digitalWrite(ledPinY, LOW);
      delay(1000);
    }
    if (Enchainement[i] == 2) {
      digitalWrite(ledPinB, HIGH);
      delay(1000);
      digitalWrite(ledPinB, LOW);
      delay(1000);
    }
    if (Enchainement[i] == 3) {
      digitalWrite(ledPinR, HIGH);
      delay(1000);
      digitalWrite(ledPinR, LOW);
      delay(1000);
    }
    if (Enchainement[i] == 4) {
      digitalWrite(ledPinG, HIGH);
      delay(1000);
      digitalWrite(ledPinG, LOW);
      delay(1000);
    }
  }

  if (buttonYpin.vientDEtreRelache()) Serial.println("Relache"); {
    BP_repos[0] = true;
  }
  if (buttonBpin.vientDEtreRelache()) Serial.println("Relache"); {
    BP_repos[1] = true;
  }
  if (buttonRpin.vientDEtreRelache()) Serial.println("Relache"); {
    BP_repos[2] = true;
  }
  if (buttonGpin.vientDEtreRelache()) Serial.println("Relache"); {
    BP_repos[3] = true;
  }

  //enregistrer les réponses de l'utilisateur
  while (cptbouton != compteur) {
    if (buttonYpin.estEnfonceDepuisAuMoins(100) && (BP_repos[0] == true))
    {
      BP_repos[0] == false;
      Reponse[cptbouton] = 1;
      cptbouton = cptbouton + 1;
    }
    if (buttonBpin.estEnfonceDepuisAuMoins(100) && (BP_repos[1] == true))
    {
      BP_repos[1] == false;
      Reponse[cptbouton] = 2;
      cptbouton = cptbouton + 1;
    }
    if (buttonRpin.estEnfonceDepuisAuMoins(100) && (BP_repos[2] == true))
    {
      BP_repos[2] == false;
      Reponse[cptbouton] = 3;
      cptbouton = cptbouton + 1;
    }
    if (buttonGpin.estEnfonceDepuisAuMoins(100) && (BP_repos[3] == true))
    {
      BP_repos[3] == false;
      Reponse[cptbouton] = 4;
      cptbouton = cptbouton + 1;
    }
  }


  //Comparer les réponses du joueur avec les couleurs de l'ordinateur
  for (byte i = 0; i < compteur; i = i + 1) {
    if (Reponse[i] != Enchainement[i]) {  //si l'utilisateur ne rentre pas la bonne combinaison, tout afficher puis tout éteindre
      digitalWrite(ledPinY, HIGH);
      digitalWrite(ledPinB, HIGH);
      digitalWrite(ledPinR, HIGH);
      digitalWrite(ledPinG, HIGH);
      delay(1000);
      digitalWrite(ledPinY, LOW);
      digitalWrite(ledPinB, LOW);
      digitalWrite(ledPinR, LOW);
      digitalWrite(ledPinG, LOW);
      exit(0);
    }
  }
}

La bibliothèque simplebouton de @bricoleau dispose d'une méthode qui indique si un bouton est relâché.

Bonjour à tous,
Merci beaucoup pour toutes vos réponses, j'avais déjà essayé avec la bibliothèque de @bricoleau mais cela n'a pas fonctionné (peut être que je m'y suis mal prise). J'ai en effet regardé cette histoire de flag et j'ai finalement réussi avec une bibliothèque qui appelle Bounce2 !! Tout marche parfaitement ! Maintenant plus qu'à rajouter du son et un écran.
Encore merci à tous pour votre aide !

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.