addition de 2 commandes pour une action

Bonjour. Nous sommes débutants sur Arduino. Nous tentons de programmer un sketch pour faire les actions suivantes:

1-entrer un code secret sur un clavier
2-si le bon code est entré, faire clignoter la Led en attendant que…
3-un touch sensor soit activé pour finalement
4-garder la led allumée et déverrouiller la porte

Toutefois, nous n’arrivons pas à cumuler l’action du code et du sensor pour déverrouiller l’aimant solenoid de la porte

si quelqu’un peut nous éclairer, ce serait gentil. merci.

tester2.ino (1.41 KB)

Si le mot de passe est 159 et que je tape 159 alors position vaut 3

vous testez ensuite dans la boucle la valeur retournée par getKey() avec ce qu'il y a dans password[3] qui est le \0 de fin de chaîne

Le soucis c'est que si aucune touche n'est enfoncée, getKey() retourne une valeur par défaut qui est NO_KEY... qui manque de bol est déclaré comme '\0' aussi

Donc comme '\0' == '\0' est vrai vous passez à position = 4 et votre code ne fonctionne plus

Qques commentaires

Vous devez aussi vous posez la question de ce qu'il se passe si le mot de passe est 111 et que j'appuie juste sur 1... Je suis prêt à parier que j'aurais trouvé le mot de passe parce que le temps que je relâche le 1 le code aura largement eu le temps de passer 3 fois dans la boucle et comme vous ne testez pas l'attente de relâchement de la touche, il va relire un '1' et passer au caractère suivant et trouver le mot de passe.

ce serait plus clean de déclarer char password[] = "159"; car vous l'utilisez comme un tableau

La façon de le trouver le mot de passe est toute simple puisqu'il suffit d'appuyer sur toutes les touches (sauf * et #) 3 fois de suite vu la façon dont c'est codé

Il vous faut donc être plus rigoureux dans la gestion du clavier: tester si la valeur renvoyée par getKey() n'est pas NO_KEY avant de faire quoi que ce soit, sans doute remettre position à zéro si j'ai tapé un mauvais caractère (sinon trop simple à trouver le code) et tester le relâchement de la touche (cf getState() ou keyStateChanged() ) avant de considérer que c'est un nouvel appui

Un immense merci J-M.L
Soyez sûr, que nous prenons la note et allons nous y attaquer.

pour l’instant, notre problématique initiale reste la même
soit le cumul de deux actions pour obtenir un résultat,
dans notre cas: taper code sur clavier, ensuite toucher un sensor pour déclencher un solénoïde

notre squelette étant:

input: keypad + touch sensor
output: solenoide + led

  1. état 1: solénoïde HIGH + led LOW
  2. action 1: taper code clavier
  3. état 2: si code bon, solénoïde HIGH, mais led BLINK ( + mise en attente prochaine action ?)
  4. action 2: toucher sensor
  5. état 3: solénoïde LOW + led HIGH

nous n’avons pas compris l’erreur de notre premier croquis ( peut-être toute simple ???)
mais entretemps, nous en avons travailler un deuxième, avec l’utilisation de: switch case

nous avons construit au préalable la suite “taper bon code sur keypad fait flasher lumière”(testé et qui marchait)
pourtant lorsque nous l’utilisons dans le croquis actuel: le terme key n’est plus reconnu

KeySensSol2:42: error: ‘key’ was not declared in this scope
if (key == ‘*’ || key == ‘#’)
^
KeySensSol2:47: error: ‘key’ was not declared in this scope
if (key == password[position])

notre bibliothèque keypad étant à jour nous déduisons que nous avons fait une erreur de logique :))

si erreur de débutant (certainement: laquelle ?)

sinon, est ce que le premier croquis était une meilleure piste ?

sincèrement

#include <Keypad.h>

#define ENTERING_CODE 0
#define WAITING_SENSOR 1

int state=ENTERING_CODE;

char* password = “1234”;
int position = 0;
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
{‘1’,‘2’,‘3’,‘A’},
{‘4’,‘5’,‘6’,‘B’},
{‘7’,‘8’,‘9’,‘C’},
{’*’,‘0’,’#’,‘D’}
};

byte rowPins[ROWS] = { 8, 7, 6, 9 };
byte colPins[COLS] = { 5, 4, 3, 2 };
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

int solenoid = 11;
int sensor = 12;
int ledpin = A5;

void setup()
{

pinMode(ledpin, OUTPUT);
pinMode(solenoid, OUTPUT);
pinMode(sensor, INPUT);

}

void loop()
{
switch(state){
case ENTERING_CODE:

if (char key = keypad.getKey());
if (key == ‘*’ || key == ‘#’)
{
position = 0;

}
if (key == password[position])
{
position ++;
}
if (position == 4)
{
while(1);
state=WAITING_SENSOR;
digitalWrite(solenoid, HIGH);
digitalWrite(ledpin, HIGH);
delay(250);
digitalWrite(ledpin, LOW);
delay(250);
}
else

{
digitalWrite(ledpin, LOW);
digitalWrite(solenoid, HIGH);

}break;

case WAITING_SENSOR:
digitalRead(sensor);
if(sensor==HIGH);
digitalWrite(solenoid, LOW);
digitalWrite(ledpin, HIGH);
}}

prenez l’habitude de mettre votre code ici dans les tag de code. et de faire un ctrl-T dans l’éditeur avant de le copier pour qu’il soit intenté correctement

votre post devrait ressembler à cela

#include <Keypad.h>

#define ENTERING_CODE 0
#define WAITING_SENSOR 1

int state = ENTERING_CODE;

char* password = "1234";
int position = 0;
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};

byte rowPins[ROWS] = { 8, 7, 6, 9 };
byte colPins[COLS] = { 5, 4, 3, 2 };
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

int solenoid = 11;
int sensor = 12;
int ledpin = A5;

void setup()
{
  pinMode(ledpin, OUTPUT);
  pinMode(solenoid, OUTPUT);
  pinMode(sensor, INPUT);
}

void loop()
{
  switch (state) {
    case ENTERING_CODE:

      if (char key = keypad.getKey());
      if (key == '*' || key == '#') {
        position = 0;
      } if (key == password[position]) {
        position ++;
      } if (position == 4) {
        while (1);
        state = WAITING_SENSOR;
        digitalWrite(solenoid, HIGH);
        digitalWrite(ledpin, HIGH);
        delay(250);
        digitalWrite(ledpin, LOW);
        delay(250);
      } else {
        digitalWrite(ledpin, LOW);
        digitalWrite(solenoid, HIGH);
      } break;

    case WAITING_SENSOR:
      digitalRead(sensor);
      if (sensor == HIGH);
      digitalWrite(solenoid, LOW);
      digitalWrite(ledpin, HIGH);
  }
}

l’approche par une machine à état est une bonne idée mais vous êtes à côté au niveau de l’implémentation.

L’erreur de compilation vient de ce que vous faites      if (char key = keypad.getKey()); ce qui a pour effet de définit une variable key qui n’a comme portée qu’un rayonnement très limité au bloc actuel donc dans le if suivant key n’est plus défini.

il faut définir char key; au début de la loop() pour qu’il soit connu dans toute la boucle.

Comment pensez vous que votre code sortira de cette boucle?

        while (1);

vous rentrez dans une boucle infinie… qui va planter le processeur (il y a un watchdog qui réinitialise le programme automatiquement)

la première ou seconde approche ne sont pas mauvaises - il faut en choisir une et organiser votre code en conséquence.

nous n'avons pas compris l'erreur de notre premier croquis ( peut-être toute simple ????)

il y en avait plusieurs... dont la plus grosse était que vous ne détectiez pas la remontée des touches et que vous testiez ce que vous retourne getKey() dans votre tableau de mot de passe sans vous soucier de la longueur du mot de passe.