Pages: [1]   Go Down
Author Topic: J'ai une pt question au sujet de l'usage de "case/switch"  (Read 710 times)
0 Members and 1 Guest are viewing this topic.
Belgium
Offline Offline
Newbie
*
Karma: 1
Posts: 12
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Bonjour la communauté,

Je suis tout nouveau .... Grâce à vos écris  XDje me débrouille jusqu'ici très bien ...  
Mais je cale avec les subtilités ou limites de l'usage de "case".

L'usage d'un simple case fonctionne parfaitement, maintenant, j'essaye de les imbriqués.
Le soucis, il semble qu'il rentre bien dans la sélection mais il break et reviens à l'attente de l'entrée principal.

Pour mieux comprendre :

Code:
int incomingByte;
int incomingByted;
int incomingBytec;
int incomingByteca;
int incomingBytecn;
void loop()
{
while (Serial.available() > 0)  {
    Serial.println("H or h For Help command");
    Serial.println("Ready !");
    incomingByte = Serial.read();
    switch (incomingByte) {
case 'd':  
case 'D':
Serial.print("D Fonction selected");
Serial.println(" - Select Channel Type ?");
incomingByted = Serial.read();
switch (incomingByted) {
case 'a':  
case 'A':
Serial.print("Analogique type selected");
Serial.println(" - Select Channel number");
incomingByteca = Serial.read();
switch (incomingByteca) {
case '1':
break;
// MaFonctionD(A1);
case '2':
break;
// MaFonctionD(A2);
case '3':
break;
// MaFonctionD(A3);
case '4':
break;
// MaFonctionD(A4);
case '5':
break;
// MaFonctionD(A5);
case '6':
break;
// MaFonctionD(A6);
case '7':
break;
// MaFonctionD(A7);
default:
Serial.println("Error Please select analogique channel 1 to 7");
break;
}


case 'n':  
case 'N':
delay(100);
Serial.print("Numerique Type selected");
Serial.println(" - Select Channel number");
incomingBytecn = Serial.read();
switch (incomingBytecn) {
case '1':
MaFonctionD(30);
break;
case '2':
MaFonctionD(31);
break;
case '3':
// MaFonctionD(3);
break;
case '4':
// MaFonctionD(4);
break;
case '5':
// MaFonctionD(5);
break;
case '6':
// // MaFonctionD(6);
break;
case '7':
// MaFonctionD(7);
break;
default:
Serial.println("Error Please select Numeric channel 1 to 7");
break;
}

default:
Serial.println(incomingByted);
Serial.println("Error please select N fo Numeric or A for analogique");
break;    
}
break;    

    case 'v':
case 'V':
      Serial.println(incomingByte);
      Serial.println("Nano - 1.0");
      break;

    case 'o':
    case 'O':
      Serial.println(incomingByte);
      OKLED();
      break;

    case 'n':
    case 'N':
      Serial.println(incomingByte);
      NOOKLED();
      break;

  case 'h':    
    case 'H':
      Serial.println(incomingByte);
      Serial.println("Internal Fonction:");  
      Serial.println("H Help");
      Serial.println("V Version");
      Serial.println("O Led Vert OK On");
      Serial.println("N Led Rouge ON");
      Serial.println("D Fonction menu");
    break;
default:
      Serial.println(incomingByte);
      Serial.print("Error:");
      Serial.println("Unreconize command");
      Serial.println("For all command please command H");
    break;
    }
  }
}    

Quand je presse O ou N pas de soucis, il s’exécute sans problème. Par contre quand je sélectionne D c'est comme si il passait       
Code:
incomingByted = Serial.read();
 Il affiche donc le message d'erreur par défaut mais en plus il break et renvois vers le case supérieur ...
Code:
Serial.println("Error please select N fo Numeric or A for analogique");

D'ailleurs, je n'arrive jamais à
Code:
switch (incomingByteca)
...

J'ai essayer en retirant les break des sous combinaisons sans résultat et si je retire tout les breaks pas mieux. ...  J'ai tenter plusieurs combinaisons avec ou sans break, mais le résultat n'est pas celui espérer !

Un Arduineur pour peut être m'éclairer ?
Ou je devrait peut être mixé if dans un case ?

Merci pour votre aide,
Bonne journée,
« Last Edit: January 26, 2013, 07:25:16 am by sdnatcher » Logged

Ile-de-France (92 sud), France
Offline Offline
Edison Member
*
Karma: 24
Posts: 2055
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

- En l'absence de break, l'exécution continue sur le case suivante
- Un break sort du switch courant au niveau de la } fermante

Exemple 1:
Code:
a = 2;
switch( a )
{
case 1:
  Serial.println("a=1");
  break;
case 2:
  Serial.println("a=2");
  break;
case 3:
  Serial.println("a=3");
  break;
}
Serial.println("fin switch");
Affichera :
Quote
a=2
fin switch

En supprimant les breaks :
Code:
a = 2;
switch( a )
{
case 1:
  Serial.println("a=1");
case 2:
  Serial.println("a=2");
case 3:
  Serial.println("a=3");
}
Serial.println("fin switch");
Affichera :
Quote
a=2
a=3
fin switch

En cas d'imbrication
Code:
a=1;
b=1;
switch( a )
{
case 1:
  switch ( b )
  {
  case 1:
    Serial.println("a=1 et b=1");
    break; // break appartenant au switch (b ), fin du case b=1
  case 2:
    Serial.println("a=1 et b=2");
    break; // break appartenant au switch (b ), fin du case b=2
  }
  Serial.println("fin switch b dans a=1");
  break;   // break appartenant au switch (a), fin du case a=1

case 2:
  switch ( b )
  {
  case 1:
    Serial.println("a=2 et b=1");
    break; // break appartenant au switch (b ), fin du case b=1
  case 2:
    Serial.println("a=2 et b=2");
    break; // break appartenant au switch (b ), fin du case b=2
  }
  Serial.println("fin switch b dans a=2");
  break;   // break appartenant au switch (a), fin du case a=2
}
Serial.println("fin switch a");
Affichera
Quote
a=1 et b=1
fin switch b dans a=1
fin switch a

Dans ton code, dans les cas 'd' et 'D' du 1er switch(incomingByte), tu as un 2nd switch(incomingByteca), tu n'as pas de break après la fermeture de } du switch(incomingByteca)
Donc l'exécution continue sur le case 'n'/'N' du 1er switch.
Est-ce voulu ?
Logged

Barbuduino: Arduino sur Breadboard & VinciDuino: Clone Leonardo // WR703: Mini-routeur hacké // LauchPad MSP430 et Stellaris // Panda II Arduino-like .NetMF sous VisualC#
RTFC: Read That F.....g Code / RTFD: Read That F.....g Doc / RTFDS: Read That F.....g DataSheet / RTFS: Read That F.....g Schematic / Wot da ya wanna D.I.Y. today ?

France
Offline Offline
Faraday Member
**
Karma: 38
Posts: 3508
There is an Arduino for that
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
Quand je presse O ou N pas de soucis, il s’exécute sans problème. Par contre quand je sélectionne D c'est comme si il passait       
Code:
incomingByted = Serial.read();

C'est peut être qu'il n'a pas encore reçu le caractère en question.
Il faudrait peut être mettre un while (!Serial.available()); avant de faire la lecture. ATTENTION quand même cette fonction est bloquante!!
Logged

Belgium
Offline Offline
Newbie
*
Karma: 1
Posts: 12
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Merci pour vos réponses réactive,

Etant dimanche, je me plonge sur vos solutions smiley
Concernant le break, oublier sur le case "D fonction", j'ai le même résultat avec et sans ... (viens d'essayer pour le pas dire de bêtises)

Donc, j'ai bien :
Quand j'appuis sur D, il semble rentrée dans le swtich car je vois :
Code:
Serial.print("D Fonction selected");
Serial.println(" - Select Channel Type ?");
Mais alors, il ne marque pas l'arrêt pour attendre le Serial.read(), il passe directement au default :
Code:
Serial.println("Error please select N fo Numeric or A for analogique");
Quand j'appuis sur N, il exectue N du premier switch ...

 
Code:
   case 'n':
  case 'N':
     Serial.println(incomingByte);
      NOOKLED();
      break;

Ce qui me laisse pensez, qu'il passe le Serial.read() du Case "D fonction" exécute le "default" et le break dans le default renvois vers le switch principal incomingByte ... Sauf quand supprimant le break dans default, il se rend quand même au swtich principal sur incomingBute ... comprend plus rien...

J'ai cru lire sur internet qu'il était "utile" de ne pas mettre certain break dans le cadre de case imbriqué.

Concernant la réponse de Fdunews, merci et en effet, je vais regarder maintenant pour ajouter un while  car je confirme qu'il n'attends pas de recevoir le second switch. Pour dé-bug, j'ai fait un print des valeurs et j’obtiens : -1 

Je reviens ...
Bonne journée et merci pour vos réponses,


Logged

Belgium
Offline Offline
Newbie
*
Karma: 1
Posts: 12
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

En effet, l'ajout du while à résolu le problème :-)
Cependant avec quelques effet toujours aussi "strange" il n'attends pas la seconde valeur ... va trop vite.
Du coup, j'ai ajouter des delay() et relancer le serial ... du coup il y a moyen de parser manuellement ou via script la commande.
A l'occurence, DN1 pour Fonction D mode numérique sur channel 1 (signifie pin N1).

Code:
int incomingByte;
int incomingByted;
int incomingBytec;
int incomingByteca;
int incomingBytecn;
void loop()
{

while (Serial.available() > 0)  {
    Serial.println("H or h For Help command");
    Serial.println("Ready !");
    incomingByte = Serial.read();
    switch (incomingByte) {
case 'd':  
case 'D':
        delay(1000);
        Serial.begin(9600);
while (Serial.available() > 0)  {
Serial.print("DHT Fonction selected");
Serial.println(" -Select Channel Type");
incomingByted = Serial.read();
switch (incomingByted) {

case 'a':  
case 'A':
delay(3000);
            Serial.begin(9600);
Serial.print("D Analogique Fonction selected");
Serial.println(" - Select Channel number");
while (Serial.available() > 0)  {
incomingByteca = Serial.read();
switch (incomingByteca) {
case '1':
MaFonctionD(A1);
break;

case '2':
MaFonctionDA2);
break;

case '3':
MaFonctionD(A3);
break;

case '4':
MaFonctionD(A4);
break;

case '5':
MaFonctionD(A5);
break;

case '6':
MaFonctionD(A6);
break;

case '7':
MaFonctionD(A7);
break;

default:
Serial.println("Error Please select analogique channel 1 to 7");
break;
}
break;
}
break;

case 'n':  
case 'N':
delay(1000);
            Serial.begin(9600);
Serial.print("D Numerique Fonction selected");
Serial.println(" - Select Channel number");
while (Serial.available() > 0)  {
incomingBytecn = Serial.read();
switch (incomingBytecn) {
case '1':
MaFonctionD(30);
break;
case '2':
MaFonctionD(31);
break;
case '3':
MaFonctionD(3);
case '4':
MaFonctionD(4);
break;
case '5':
MaFonctionD(5);
break;
case '6':
MaFonctionD(6);
break;
case '7':
MaFonctionD(7);
break;
default:
Serial.println("Error Please select Numeric channel 1 to 7");
break;
}
break;
}
break;

default:
Serial.println(incomingByted);
Serial.println("Error please select N fo Numeric or A for analogique");
break;

}
break;
}
break;        

    case 'v':
case 'V':
      Serial.println(incomingByte);
      Serial.println("Nano - 1.0");
      break;

    case 'o':
    case 'O':
      Serial.println(incomingByte);
      OKLED();
      break;

    case 'n':
    case 'N':
      Serial.println(incomingByte);
      NOOKLED();
      break;

  case 'h':    
    case 'H':
      Serial.println(incomingByte);
      Serial.println("Internal Fonction:");  
      Serial.println("H Help");
      Serial.println("V Version");
      Serial.println("O Led Vert OK On");
      Serial.println("N Led Rouge ON");
      Serial.println("D Fonction menu");
    break;
default:
      Serial.println(incomingByte);
      Serial.print("Error:");
      Serial.println("Unreconize command");
      Serial.println("For all command please command H");
    break;
    }
  }
}  

Peut être qu'il y a plus simple ou plus propre ...
Merci et bon dimanche,
« Last Edit: January 27, 2013, 07:58:21 am by sdnatcher » Logged

France
Offline Offline
Faraday Member
**
Karma: 38
Posts: 3508
There is an Arduino for that
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Quote
il n'attends pas la seconde valeur ... va trop vite.
C'est normal la ligne suivante n'attends pas la saisie.
Code:
while (Serial.available() > 0)  {
Elle s'exécute s'il y a une entrée sinon elle sort. Je t'avais proposé de mettre
Code:
while (!Serial.available());
Cette ligne attend jusqu'au moment ou il y aura une saisie. C'est d'ailleurs l'inconvénient que j'avais signalé la ligne est bloquante. S'il n'y a pas d'entrée elle restera à attendre.
Si cela ne te gène pas tu laisses comme ça. Sinon il faut ajouter une variable liée au temps dans la condition du while.
Logged

Belgium
Offline Offline
Newbie
*
Karma: 1
Posts: 12
View Profile
 Bigger Bigger  Smaller Smaller  Reset Reset

Super,

merci en effet, il attends, mais c'est totalement ce que je cherche.

Bonne soirée,


Logged

Pages: [1]   Go Up
Jump to: