sérrure codée avec 2poussoirs

Bonjour, je suis débutant et je voudrais réaliser une serrure codée avec 2 poussoirs, qui fait briller la Led L1 si le code est bon. Il dot respecter la séquence suivante:
Pour allumer la Led L1, il faudra successivement :

  • appuyer sur P1
  • relâcher P1
  • appuyer à nouveau sur P1
  • appuyer sur P2 (sans relâcher P1)
  • relâcher P2
  • relâcher P1. C'est alors que L1 devra s'allumer durant trois seconde.

La vitesse d'exécution de la séquence n'est pas importante. Toute autre manipulation est considérée comme fausse.
Après une séquence (juste au fausse) le programme doit :

  • attendre jusqu'à ce que plus aucune touche ne soit pressée
  • attendre encore d'une seconde.
  • reprendre sa détection.

J'ai proposé un code mais, il accepte d'autres séquence, j'ai besoin de votre aide SVP.
Mon code

//statique des poussoirs.ino
 #define Led1 4  // actif à 1
 #define Led1On  digitalWrite (Led1,1);    //  Allume Led1
 #define Led1Off digitalWrite (Led1,0);    //  Eteint Led1
 #define Pous1 2  // actif à 0
 #define Pous2 3  // actif à 0
 #define Pous1On (digitalRead (Pous1)==0) //  actif à 0V
 #define Pous2On (digitalRead (Pous2)==0) //  actif à 0V

 void setup() {
    pinMode (Pous1, INPUT_PULLUP); 
    pinMode (Pous2, INPUT_PULLUP);  
    pinMode (Led1,OUTPUT);
 }

void loop () {
if (Pous1On) {
   delay(10);
  while (Pous1On) {delay (10); }
   delay(10);
  while (!Pous1On) {delay (10); }
   delay(10);
  while (!Pous2On) {delay (10); }
   delay(10);
  while (Pous2On) {delay (10); }
   delay(10);
  while (Pous1On) {delay (10); }
    Led1On; delay(3000); Led1Off;
    }
    else {Led1Off;delay(3000);
}
}

je pense que tu n'utilises pas la bonne méthode ...

dans ton programme tu progresses pas à pas mais il n'y a pas d’arrêt si le code est mal rentré ... le code avance d'un pas quand le bon bouton est pressé ou relaché, mais ils ne bloque pas si on presse le mauvais bouton ...

il faut donc revoir la méthode ...

j'assemblerai un code au fur et à mesure que l'utilisateur appuie ou non sur un bouton (indice : à chaque changement d'état par rapport au précédent)
appui bouton 1 = 1
appui bouton 2 = 2
appui bouton 1 et 2 = 3
aucun bouton appuyé = 0

ton code se traduirait donc par :

  • appuyer sur P1 .........1
  • relâcher P1 .........0 (aucun bouton appuyé)
  • appuyer à nouveau sur P1 ............1
  • appuyer sur P2 (sans relâcher P1)...3 (P1 est appuyé et P2 aussi)
  • relâcher P2 ..............1 (P1 toujours appuyé)
  • relâcher P1. ..............0
    soit la séquence 101310

dans ce cas un mauvais appui entraine un mauvais code ...

NB attention au traitement des rebonds !!!

Ton besoin correspond typiquement à l'usage d'une machine à états.
Au départ la machine est en attente, en fonction d'une action externe elle change d'état. Si l'action était bien celle attendue elle passe dans un nouvel état sinon elle revient à l'état de départ.

Au début de ton programme, tu définis les états que tu utiliseras puis ensuite tu traites tous les cas possibles dans loop. Petit exemple d'une machine à états ci-dessous. Bien évidemment dans chaque branche des if tu mettre du code qui gère des LED ou déclenche d'autres actions. Le principe tel qu'exposé n'est pas bloquant la boucle loop tourne en permanence en attente d'une action.

enum etat {
  ATTENTE, PAS1,PAS2,PAS3,SUCCES};

unsigned char etat_courant;

void setup() {
  // put your setup code here, to run once:
  etat_courant=ATTENTE;
}

void loop() {
  // put your main code here, to run repeatedly: 
  unsigned char entree1 = digitalRead(3);
  unsigned char entree2 = digitalRead(4);
  switch(etat_courant){
  case ATTENTE:
    if (entree1==1 && entree2==0){
      etat_courant = PAS1;
    };
    break;
  case PAS1:
    if (entree1==0 && entree2==0){
      etat_courant = PAS2;
    }
    else{
      etat_courant=ATTENTE;
    };
    break;
  case ......


   .......
  default:
    etat_courant=ATTENTE;
  }
}