Creer un mot de passe avec 2 boutons poussoirs

Bonjour, je débute avec arduino et je voudrai savoir comment je pourrais m'y prendre (niveau code) pour faire en sorte qu'une certaine combinaison
de pression sur mes 2 boutons poussoirs permettent d'allumer une led si la combinaison est correcte et qu'il y ait une réinitialisation de la
combinaison enregistrée si celle-ci est fausse .
Merci.

Bonjour,

Tu peut utiliser une interruption (attachInterrupt()) pour détecter l'appui sur les boutons.
(Attention : il faudra intégré un anti-rebond, logiciel ou matériel)

Ensuite pour le "mot de passe" tu peut faire une "machine à états finis".
(c'est un switch sur une variable, chaque état correspond à un "case" du switch et suivant les actions prises tu passes d'un état à un autre)

Si ton mot de passe est conditionné par le temps (intervalle entre deux appuis) avec millis() tu peut gérer cela.

D'accord mais comment faire pour stocker les differentes valeurs de chaque case les une a la suite des autres pour les faire correspondre
avec un enchainement qui constitue le bon mot de passe (que je ne sais pas creer non plus).

Pour stocker ton mot de passe de peux utiliser l'EEPROM qui est une mémoire morte (les informations reste stockées même après un reset). Par exemple une chaine de boolean (puisque tu as deux bouton) :

boolean Password[]={0,1,1,0,0}; // 0 = bouton n°1, et 1 = bouton n°2

Et tu la stock en mémoire. Ensuite lorsque l'utilisateur essaye de taper un code, il suffit de remplir un autre tableau de boolean suivant l'appui sur les boutons, puis de le comparer à celui en mémoire.

byte NombreAppui = 0;
boolean CodeEnCours[5];
boolean Password[5];

void setup(){
//Routine pour remplir Password[] avec le mot de passe stocké en mémoire
}

void loop(){
if(digitalRead(Bouton1)==HIGH){
delay(50); // permet d'éviter les effets de rebonds
CodeEncours[NombreAppui++]=0;
}

if(digitalRead(Bouton2)==HIGH){
delay(50); // permet d'éviter les effets de rebonds
CodeEncours[NombreAppui++]=1;
}

If(NombreAppui>4){
//routine pour comparer les deux tableaux Password et CodeEnCours
NombreAppui=0;
}
}

Merci beaucoup, tu me sauves la vie :slight_smile:

Pour stocker le mot de passe dans la mémoire, c'est bien EEPROM.write(password);

Et je ne vois pas comment faire pour remplir Password[] avec le mot de passe stocké en mémoire

Ensuite pour remplir CodeEnCours, je propose ça, qu'est ce que t'en penses ?

for ( int i=1; i<5;i++)   
    {
if (      analogRead(BoutonPoussoir1,LOW) {
   CodeEnCour[i]=0; }
if (      analogRead(BoutonPoussoir1,LOW) {
   CodeEnCour[i]=1; }
    }

Et pour comparer les 2 tableaux je ferrai ça: (on doit pouvoir faire plus simple mais je vois pas comment):

int a=0; // variable qui stocke le nombre de similitude entre les 2 combinaisons
for ( int i=1; i<5;i++)   
    {if (password[i] == CodeEnCour[i]){
a+= a+1;
}

if (a==5){
digitalWrite(led,HIGH);
}

Et pour finir (oui désolé, je sais que sa fait beacoup de chose :cold_sweat: ), je ne comprend pas a quoi sert cette partie de ton code:

If(NombreAppui>4){
//routine pour comparer les deux tableaux Password et CodeEnCours
NombreAppui=0;
}

Oula tout ça ça ne va pas marcher.

Remplir codeencours jte l'avais fait. La tu fais une boucle qui va immédiatement s'executer. Il faut déclencher l'enregistrement uniquement lors d'un appui. En plus ta syntaxe des lectures est fausse, il faut un digitalRead() (et en plus la syntaxe de ton analogRead n'est pas bonne de toute façon).

Mise en mémoire : l'eeprom est organisé en byte (nombre de 0 à 255). A chaque adresse, un byte. On va se simplifier la vie pour chaque élément de Password, on va attribuer une mémoire. Il suffit donc de faire une boucle, et à chacune on enregistre un boolean du tableau, et on incrémente. Alors après, note que je me sers de l'eeprom, dans l'optique qu'au final l'utilisateur pourra changer le mot de passe sans avoir à reprogrammer l'arduino. Pour le moment tu peux te simplifier la vie et le définir comme une variable classique dans tes déclarations. On verra plus tard l'eeprom ...

La dernière partie permet de déclencher la comparaison de code une fois que 5 appui ont été enregistré, soit la routine que tu as écrite juste avant, qui n'est pas bonne non plus. Première erreur : un tableau commence à 0, pas à 1. Même si on déclare Tableau[5], les index iront de 0 à 4 (ce qui fait bien 5 index au total). Ensuite "a+= a+1;" ce n'est pas bon, la tu fais : ajoute à la variable a, la variable a + 1. Il faut ici "a++;" ou bien "a=a+1;". Enfin si tu résussis le code, ta LED ne s'éteindra jamais, il faut else qui l'éteint si le ocde n'est pas bon.

Je m'occuperai de l'eeprom quand mon programme de base marchera plutôt, sinon je vais aps m'en sortir :cold_sweat:

Donc j'ai suivi tes indications , j'ai un programme qui compille, mais la LED ne s'allume jamais.

int led = 13;
int Bouton1 =2;
int Bouton2 =3;
boolean password[4]={1,1,2,2};
boolean CodeEncours [4];
byte NombreAppui = 0;

void setup(){
  pinMode(led,OUTPUT);
  pinMode(Bouton1,INPUT);
  pinMode(Bouton2,INPUT);
  
}

void loop(){
if(digitalRead(Bouton1)==HIGH){
delay(50); 
CodeEncours[NombreAppui++]=0;
}

if(digitalRead(Bouton2)==HIGH){
delay(50); 
CodeEncours[NombreAppui++]=1;
}

if(NombreAppui>4){
  
int a=0; // variable qui stocke le nombre de similitude entre les 2 combinaisons
for ( int i=0; i<3;i++)    {
  if (password[i] == CodeEncours[i]){
a= a++;
}
    }
if (a==4){
digitalWrite(led,HIGH);
}
else{
  digitalWrite(led,LOW);
}
NombreAppui=0;

}
}

Normal regarde le type de variable pour ta clé et avec quels valeurs tu la déclares ...

Ah oui c'est vrai, les variables doivent être 0et1 et pas 1et2.
Mais même quand je change ça, sa ne marche pas.
D'ailleur je me demande si je devrais pas enlever boolean et le remplacer par int psk dans le tableau, on stocke
des chiffres et pas des true/false. (j'ai essayé mais il se passe toujours rien =( )

Dans ton tableau tu peux stocker des 0 et des 1..... soit des boléens également

Mais dans ce cas , le fait de remplacer les variables 1et2 par 0et1 (vu que 2 n'existe pas et que apparemment 0et1 sont des variables boolennes) aurait du faire fonctionner le programme.

T'as fait quoi comme montage ?

En plus tu n'écoutes absolument pas ce que je dis ... Pas "a=a++;", soit "a++;" soit "a=a+1;"

Sinon j'ai zappé une ligne ici :

if(digitalRead(Bouton1)==HIGH){
delay(50); 
CodeEncours[NombreAppui++]=0;
}

Et bien sur sur l'autre fonction pour le bouton 2. Il faut attendre que le bouton repasse à l'état "repos" :

if(digitalRead(Bouton1)==HIGH){
while(digitalRead(Bouton1)==HIGH); // boucle tant que le bouton reste appuyé
delay(50); 
CodeEncours[NombreAppui++]=0;
}

J'ai fais ça:
http://andyautuori.fr/insa/DSC_0434.jpg

Désolé du double post mais je comprends pas à quoi il sert ton while.
Il sert à faire tourner en boucle le delay tant que le bouton est pas relaché ou c'est autre chose ?
Et si c'est ça, pourquoi est ce qu'il n'y a pas les acollades qui englobent le delay ?

Oui c'est ça, mais le delay on s'en fout, le but c'est d'attendre que le bouton soit relâché, la ça va boucler dans le vide tant que c'est pas le cas.

Ca semble Ok niveau montage des boutons. Par contre le pin 13 a déjà une led sur la board et la tu risques de griller ta sortie sans résistance. Par contre c'est normal que ça marche pas, tes pins passent à l'état bas quand on appuie, pas à l'état haut ...

C'est bon j'ai remplacé les HIGH par LOW et j'utilise juste la led integrée sur la carte arduino comme temoin, mais toujours pas de réponse de la led...

Comme (une fois de plus) tu n'as pas suivi ce que je t'ai dit, tu as créer ta clé avec 4 chiffres ... Donc les conditions if(NombreAppui>4) va necessiter 5 appui, et la routine qui suit ne vont pas marcher.

Mais même avec un mot de passe a 5 chiffres et le " if NombreAppui>4 " ça marche pas.

Bon bin faut faire du debug alors : place des Serial.println() aux endroits clés (attention pas en dehors des conditions sinon ça va boucler toutes les ms. Exemple :

if(digitalRead(Bouton1)==LOW){
while(digitalRead(Bouton1)==LOW); // boucle tant que le bouton reste appuyé
delay(50); 
Serial.println("Appui sur le bouton 1");
CodeEncours[NombreAppui++]=0;
}

La même chose sur le bouton 2 et lorsque NombreAppui>4. Tu n'as plus qu'à regarder dans le moniteur série ce que tu reçois.

C'est bon, le code marche :P, c'est pas trop tôt.
Merci de ton aide et (surtout) de ta patience.
Je poste le code , si jamais sa interesse des gens:

int led = 13;
int Bouton1 =2;
int Bouton2 =3;
int password[5]={1,1,1,1,1};
int CodeEncours [5];
byte NombreAppui = 0;

void setup(){
  pinMode(led,OUTPUT);
  pinMode(Bouton1,INPUT);
  pinMode(Bouton2,INPUT);
  Serial.begin(9600);
  
}

void loop(){
if(digitalRead(Bouton1)==LOW){
while(digitalRead(Bouton1)==LOW);
Serial.println("Appui sur le bouton 2");
delay(50); 
CodeEncours[NombreAppui++]=0;
}

if(digitalRead(Bouton2)==LOW){
  while(digitalRead(Bouton2)==LOW);
  Serial.println("Appui sur le bouton 1");
delay(50); 
CodeEncours[NombreAppui++]=1;
}

if(NombreAppui>4){
  Serial.println("nbr appui=5");
  
int a=0; // variable qui stocke le nombre de similitude entre les 2 combinaisons
for ( int i=0; i<=4;i++)    {
  if (password[i] == CodeEncours[i]){
      
 

a= a+1;
Serial.print(a);

}


     
    }
if (a==5){
  
  
digitalWrite(led,HIGH);
delay (5000);
digitalWrite(led,LOW);
}
else{
  digitalWrite(led,LOW);
}
NombreAppui=0;

}
}

Et aussi pour l'améliorer, est ce que tu pourrais m'expliquer un peu comment ça se passe avec l'EEPROM ?