Go Down

Topic: Une chaîne de Caractère dans un switch case ? (Serrure codée) GONE WRONG (Read 1 time) previous topic - next topic

ThePurpleOne_

Salut à tous,

J'essaie de réaliser un petit projet pas trop complexe mais je suis tombé sur un problème(enfin je crois),
J'ai fait un petit montage sur Breadboard avec 5 boutons poussoirs, 3 LEDs et un Arduino nano, je compte faire une serrure codée, mais le problème c'est que j'ai que des boutons poussoirs, J'ai donc pensé à un "mode" programmation qui est activé quand on appuie sur le premier bouton et qui enregistre le code rentré en code valide! Le problème n'est pas là, comment puis-je lire le code sur les quatres autres boutons? j'ai essayé d'additionner les
Code: [Select]
(digitalRead(BUTTONx) + (digitalRead(BUTTONx)
et ça fonctionne, sauf que ça me donne un entier entre 0 et 4 quoi, le code peut donc être soit le premier soit le deuxième, soit le troisième etc. Alors j'ai pensé à des équivalences, j'ai donc créé une fonction qui change la valeur que donne chaque boutons pour avoir des codes différents à chaque fois:
 
Code: [Select]
int Transform(char whichone)
{
  int result;
  switch (whichone)
  {
    case 'digitalRead(BUTTON2)':
      result = 5;
      break;
    case 'digitalRead(BUTTON3)':
      result = 10;
      break;
    case 'digitalRead(BUTTON4)':
      result = 100;
      break;
    case 'digitalRead(BUTTON5)':
      result = 1000;
      break;
  }
  return result;
    
}


Mais en fait ça ne marche pas, je ne sais donc pas trop comment m'y prendre...


Des idées? Des corrections du code?(ya surement des erreurs j'ai pas finis mais cette partie m'embête quoi)
je vous mets le code entier au cas ou  X) X)

Code: [Select]
#define BUTTON1 6
#define BUTTON2 9
#define BUTTON3 12
#define BUTTON4 2
#define BUTTON5 3
#define LED_BLEU 13
#define LED_VERTE 11
#define LED_ROUGE 7
#define ETAT_AUTRE 42
#define ETAT_CODEBON 69  
int code_bon;
int etat;
int compteur;

int Transform(char whichone)
{
  int result;
  switch (whichone)
  {
    case 'digitalRead(BUTTON2)':
      result = 5;
      break;
    case 'digitalRead(BUTTON3)':
      result = 10;
      break;
    case 'digitalRead(BUTTON4)':
      result = 100;
      break;
    case 'digitalRead(BUTTON5)':
      result = 1000;
      break;
  }
  return result;
    
}

  
void setup() {
  // put your setup code here, to run once:
  pinMode(LED_BLEU, OUTPUT);
  pinMode(LED_VERTE, OUTPUT);
  pinMode(LED_ROUGE, OUTPUT);
  pinMode(BUTTON1, INPUT_PULLUP);
  pinMode(BUTTON2, INPUT_PULLUP);
  pinMode(BUTTON3, INPUT_PULLUP);
  pinMode(BUTTON4, INPUT_PULLUP);
  pinMode(BUTTON5, INPUT_PULLUP);
  code_bon = 110;
  compteur = 500;
  Serial.begin(9600);
}

void loop() {
  // put your main code here, to run repeatedly:
  if(digitalRead(BUTTON1)!= HIGH)//Le Bouton du mode programmation est-il pressé?
  {
    digitalWrite(LED_BLEU, HIGH);//allumer la led de programmation
    digitalWrite(LED_ROUGE, LOW);//éteindre les autres
    digitalWrite(LED_VERTE, LOW);//éteindre les autres
    code_bon = transform(digitalRead(BUTTON2))+transform(digitalRead(BUTTON3))+transform(digitalRead(BUTTON4))+transform(digitalRead(BUTTON5))//mettre le code entré en code bon
    etat = ETAT_AUTRE;//mettre l'etat à "autre"
    compteur = 500;//compteur = 500
    if(compteur != 0)//le compteur est-il different de zero?
    {
      compteur = compteur - 1;//compteur = compteur -1
      digitalWrite(LED_VERTE, HIGH);//Allumer la led de porte
      delay(1);//delay 1ms
    }
      else
      {
        digitalWrite(LED_VERTE, LOW);//éteindre la led de porte  
      }
  }

  else
  {
    if(code_bon == (transform(digitalRead(BUTTON2))+transform(digitalRead(BUTTON3))+transform(digitalRead(BUTTON4))+transform(digitalRead(BUTTON5)))//le code est-il bon?
    {
      digitalWrite(LED_BLEU, LOW);//éteindre les autres
      digitalWrite(LED_ROUGE, LOW);//éteindre les autres
      etat = ETAT_CODEBON;//mettre l'etat à "codebon"
      compteur = 500;//compteur = 500
    }
    else
    {
      etat = ETAT_AUTRE;//mettre l'etat à "autre"
      digitalWrite(LED_BLEU, LOW);//éteindre les autres
      digitalWrite(LED_ROUGE, LOW);//éteindre les autres.
      digitalWrite(LED_VERTE, LOW);//éteindre les autres
      
      if(compteur != 0)//le compteur est-il different de zero?
      {
        compteur = compteur - 1;//compteur = compteur -1
        digitalWrite(LED_VERTE, HIGH);//Allumer la led de porte
        delay(1);//delay 1ms
      }
      else
      {
        digitalWrite(LED_VERTE, LOW);//éteindre la led de porte  
      }
    }
  }
  
  //Serial.println(buttonState);

  }


Merci à vous! Bonne Journée!


                ThePurpleOne_


bricofoy

ton switch/case ne fonctionne pas car il n'est pas écrit correctement. Il est impossible de faire ce que tu essaye de faire de cette manière : les valeurs que tu donnes à chaque case divent être des valeurs possible de la variable qui est passée à switch(variable), donc ici "wichone", c'est cette variable qui doit avoir différente valeurs. La tu testes la valeur de cette variable en la comparant dans chaque case avec une valeur qui est la valeur de retour d'une lecture de pin, donc qui d'une part peut changer, et d'autre part ne peut prendre que deux valeurs réelle : 1 ou 0 (HIGH ou LOW)

Donc en gros ce que tu as écrit c'est que tu teste la valeur lue sur la pin de chaque bouton avec cette même valeur, tu ne sortira jamais du premier choix du case.

ce que tu pourrais faire c'est faire ce que tu a voulu faire dans le case mais directement à la lecture des boutons :
Code: [Select]

result = 5*digitalRead(BUTTON2)+10*digitalRead(BUTTON3)+100*digitalRead(BUTTON4)+1000*digitalRead(BUTTON5)


Mais un meilleur codage au lieu d'employer 5, 10, 100 etc serait d'employer des puissances de deux. De la sorte chaque bouton correspondra à un bit de la variable qui sera à un ou zero, ça te permet de savoir ensuite bien plus facilement quel bouton est appuyé.

donc :
Code: [Select]

result = 1*digitalRead(BUTTON2)+2*digitalRead(BUTTON3)+4*digitalRead(BUTTON4)+8*digitalRead(BUTTON5)


et ensuite si tu veux savoir si par exemple le bouton 3 à été appuyé tu peux tester très simplement le bit de valeur 2 avec :

Code: [Select]
if (result & 2)
{
    fais;
    un;
    truc;
}


ensuite tu peux aussi faire un #define pour chaque valeur attribuée aux boutons comme ça c'est plus clair dans code
Code: [Select]
if (result & BUTTONVAL2)
{
    fais;
    un;
    truc;
}
-tu savais que si tu passe le CD de windows à l'envers, tu entends une chanson satanique ?
-non, mais il y a pire : à l'endroit, ça l'installe !

iznobe

Bonjour , je suis tout a fait d' accord avec le principe des puissances de 2 .

Tu peux simplement attribué le bouton 1 a une variable qui vaut 1
le bouton 2 a une variable qui vaut 2
le bouton 3 a une variable qui vaut 4
le bouton 4 a une variable qui vaut 8

l ' avantage de ce principe est aussi de pouvoir identifié n ' importe quelle combinaison de boutons
grace a une simple addition qui donne chaque fois un resultat unique peu importe l' ordre .

ensuite grace a cette valeur de la variable tu peux y associer la chaine de caractere que tu desires  grace a un : switch  : case .

Je te conseille vivement la lecture de ce tuto ecrit par @J-M-L sur le forum Programmation Automate fini / Machine à état .

au final ce n ' est pas compliqué , juste de l ' apprentissage et de la patience .

ca donnerait un truc du style :

Code: [Select]
enum {0,1, 2, 4, 8} valeurVariable;


switch (valeurVariable) {
   case 0: // on est au repos
   // on ne fait rien
     break;

   case 1:
    // on a appuyé sur le bouton 1
    // on fait des trucs
     break;

   case 2:
     break;
   
   case 4:
     break;

   case 8:
     break;

   case 3: // 1er et 2eme bouton
     break;

   case 5: // 1er et 3eme bouton
     break;

   case 9: // 1er et 4eme bouton
     break;

   case 7: // 1er + 2eme et 3 eme bouton
     break;

etc ...

Ce code ne marche absolument pas , c ' est juste pour faire voir le principe .
serveur relais volets arrosage heures creuse : https://forum.arduino.cc/index.php?topic=493039.0

bricofoy

ce code fonctionnerait si la variable est un int et non une enum. Je ne comprends pas l'intéret de vouloir utiliser une enum ici...
-tu savais que si tu passe le CD de windows à l'envers, tu entends une chanson satanique ?
-non, mais il y a pire : à l'endroit, ça l'installe !

fdufnews

Bonjour , je suis tout a fait d' accord avec le principe des puissances de 2 .

Tu peux simplement attribué le bouton 1 a une variable qui vaut 1
le bouton 2 a une variable qui vaut 2
le bouton 3 a une variable qui vaut 4
le bouton 4 a une variable qui vaut 8

l ' avantage de ce principe est aussi de pouvoir identifié n ' importe quelle combinaison de boutons
grace a une simple addition qui donne chaque fois un resultat unique peu importe l' ordre .
Ben non justement. 1+2+4 fera toujours 7 quelque soit l'ordre dans lequel tu appuieras sur les boutons.

Pour que cela fonctionne, il faut que chaque touche ait une valeur unique et que l'ordre d'appui donne un facteur multiplicateur.
Si tu veux rester en binaire, tu alloues 1,2,4,8 aux boutons et à chaque saisie tu multiplies la nouvelle valeur saisie par 16 et là tu récupéreras une valeur unique pour chaque combinaison de touches.

J-M-L

ça ce n'est pas une bonne idée en effet
Code: [Select]
enum {0,1, 2, 4, 8} valeurVariable;
On utilise des enum justement pour donner des jolis noms aux différents éléments
Hello - Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums.
Bonjour Pas de messages privés SVP, postez dans le forum directement pour que ça profite à tous

Go Up