Switch Case et boucle infinie?

Bonjour!

Je ne suis pas expert en programmation, mais avec les exemples, j'arrive généralement à mes fins.
Or, cette fois si je bloque sur un détails qui me semble simplement stupide...

Dans mon programme, j'utilise un clavier 12 touches (vu que je l'avais déjà en stock ^^) pour choisir différent mode de fonctionnement dans le prog. 6 modes (touche 1 à 6) et 1 stop (touche 0). Le tout contrôlé par la librairie keypad.h
Ce que je cherche à faire, c'est que lorsque je rentre dans une des 6 fonctions (le stop peu être envoyé une seule fois, peu m'importe) celle-ci soie éffectué en boucle infini jusqu'à ce que je presse une autre touche du clavier.

Or, dans le moment, ce que j'arrive à faire est une seule lecture du case et le programme revient au départ pour attendre une nouvelle touche. J'ai tester quelques méthodes avec des if, des do/while, if else, changé le break de place, mettre une conditions sur le break, mais au final, sois le programme s'effectue une fois, ou il ne veut plus sortir de la boucle.

J'ai joint ici un programme vraiment de base mais qui revient au même que mon programme complet. Et surtout, 30 lignes c'est plus rapide à analysé que 550 lignes :stuck_out_tongue:
Pour info, le keypad fonctionne bien, chaque "sous-programme" correspondant à chaque case fonctionne bien lorsqu'il sont utilisé séparément. C'est juste le fait de faire tourner le case en boucle infinie qui me pose problème.

Voila! J'espère avoir expliqué assez éfficacement, je n'est pas l'habitude d'expliquer mes programmes ^^' juste le produit final une fois fonctionnel...

#include <Keypad.h>

const byte ROWS = 4; //four rows
const byte COLS = 3; //three columns
char keys[ROWS][COLS] = {
  {'1','2','3'},
  {'4','5','6'},
  {'7','8','9'},
  {'#','0','*'}
};
byte rowPins[ROWS] = {5, 4, 3, 2}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {8, 7, 6}; //connect to the column pinouts of the keypad

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

void setup(){
  Serial.begin(19200);
}
  
void loop(){
  char key = keypad.getKey();
  
  if (key != NO_KEY){
    
    switch (key) {
      case '1' : Serial.println("Accelerometre"); break;
      case '2' : Serial.println("Accelerometre avec moteur dc"); break;
      case '3' : Serial.println("Accelerometre pour bras"); break;
      case '4' : Serial.println("Joystique"); break;
      case '5' : Serial.println("Joystique avec moteur dc"); break;
      case '6' : Serial.println("Joystique pour bras"); break;
      case '0' : Serial.println("Stop"); break;
      }
  }
}
char key = NO_KEY;
void loop(){
  char new_key = keypad.getKey();
  
  if (new_key != NO_KEY )
	  key = new_key;
    
  switch (key) {
    case '1' : Serial.println("Accelerometre"); break;
    case '2' : Serial.println("Accelerometre avec moteur dc"); break;
    case '3' : Serial.println("Accelerometre pour bras"); break;
    case '4' : Serial.println("Joystique"); break;
    case '5' : Serial.println("Joystique avec moteur dc"); break;
    case '6' : Serial.println("Joystique pour bras"); break;
    case '0' : Serial.println("Stop"); 
                  key = NO_KEY; // pour que stop ne soit fait qu'une seul fois
                  break;
    }
}

pas sorcier pourtant.

Et ben non :confused:

Il ne fait qu'afficher une seule fois le serial println et revient au début en attente de la prochaine touche presser.

Je suis entrain de regarder si je peu faire quelque chose en vérifiant l'état du clavier.
En fait je pense que c'est dans le fonctionnement de la librairie qui fait que c'est pas si facile de faire mes boucle infinies... je planche la dessus!

D'après http://www.arduino.cc/playground/code/Keypad

Je lit :

char getKey()
Returns the key that is pressed, if any. This function is non-blocking.

Ils nous auraient menti ?

Si c'est la lib qui bloque, il faut changer le code de la lib.
Tu es sur d'avoir la bonne version ?

Ah bha oui, avoir la version à jour va surment aidé :sweat_smile:

Aller hop! de la 1.8 à la 3.0 ^^'

3.0 2012-07-12 - Mark Stanley : Modified pin functions to support Keypad_I2C
3.0 2012-07-12 - Stanley & Young : Fix for multiple keypad objects.
3.0 2012-07-12 - Mark Stanley : Fixed bug that caused shorted pins.
2.0 2011-12-29 - Mark Stanley : Added Nick Gammon's changes.
2.0 2011-12-29 - Mark Stanley : Added waitForKey()
2.0 2011-12-23 - Mark Stanley : Rewrote state machine
2.0 2011-12-23 - Mark Stanley : Significant speed improvements.
1.8 2011-11-29 - Tom Putzeys : Enabled internal pull-ups on non-active columns
1.8 2011-11-21 - Mark Stanley : Added test for version 1.0 of the IDE
1.8 2009-07-08 - Alexander Brevig : Added no restrictions on sizes or keymaps

Apparemment ca a du se passer dans la 2.0 quand ils ont ajouté waitForKey() qui n'aurait pas eu de sens autrement

La description du comportement de ton programme correspond bien à ce qui est codé.
Loop
teste si une touche est appuyée
si une touche est appuyée tu exécutes une action (une fois)
si pas de touche appuyée tu ne fais rien
retour au début

Si j'ai bien compris toi tu voudrais ça:

Loop
teste si une touche est appuyée
si une touche est appuyée on mémorise la touche en question
exécute l'action associée à la touche
retour au début

Dans le premier code, si la touche est relâchée on ne fait plus rien
Dans le second code, comme la valeur de la dernière touche appuyée est mémorisée même après le relâché de la touche on continue à exécuter l'action.

Loop
teste si une touche est appuyée
si une touche est appuyée on mémorise la touche en question
exécute l'action associée à la touche
retour au début

Ouais en gros, au détail que je veux exécuter l'action associée à la touche jusqu'à ce que je presse une autre touche.

J'ai fait quelque test avec uniquement le keypad (ttoujours le plus simple de trouver le problème avec le moins de code possible :slight_smile: ) et je n'arrive pas encore à faire afficher en continue la touche choisi.
À chaque fois la touche s'affiche une seule fois....
Même en vérifiant l'état tu clavier, en isolant la variable key ailleur...
Je continu les recherches!

Knaar:
Loop
teste si une touche est appuyée
si une touche est appuyée on mémorise la touche en question
exécute l'action associée à la touche
retour au début

Ouais en gros, au détail que je veux exécuter l'action associée à la touche jusqu'à ce que je presse une autre touche.

C'est bien ce que je décris puisqu'à l'étape 2 dans la boucle je mémorise la touche appuyée donc l'action s'exécutera jusqu'à l'appui sur une autre touche (et d'ailleurs je l'écris à la ligne en dessous).

Dans le second code, comme la valeur de la dernière touche appuyée est mémorisée même après le relâché de la touche on continue à exécuter l'action.

J'aurais du être plus clair.

Loop
teste si une touche est appuyée
si une touche est appuyée on mémorise la touche en question
exécute l'action associée à la touche mémorisée
retour au début

J'ai souvent eu des bugs avec la lib keypad, ce qui m'a poussé à gérer moi-même le clavier. Le meilleur, était une touche qui faisait une double frappe sur la touche d'à côté, je n'ai jamais compris pourquoi...

Il serait temps que je me mette à écrire des libs moi-même, notamment une avec la gestion des PCINT sur le clavier, en 3/4 lignes de code sans faire un scan des rows / cols, on peut lire la touche du clavier, et via les PCINT, tenir une variable reflétant la touche actuellement pressée (ou NO_KEY), voire même tenir un buffer avec les différentes touches qui fonctionnerait comme la lib serial...