using if inside case

septillion:
Because it isn't anymore. The 'e' case is now inside a "conditional jump". But I guess (yes, I have to because no Arduino on hand :slight_smile: ) it is valid to have cases inside an if() instead of more conventional other way around.

No, I am talking about the way the C++ language sees the body of a switch.

For C++ language the the body of a switch is just one continuous statement. You can place case labels anywhere inside that statement: inside inner if's, inside inner cycles. Anywhere.

There's nothing unusual about the original OP's code form the language's point of view.

The thing that's counterintuitive is that switch case looks highly structured such that each case has its own block of code but it really doesn't.

In reality, the switch uses the case labels as targets to jump to, so you can have all sorts of convoluted stuff in there with case labels in the middle of other constructs. Usually, you don't, because it would be a hideous thing to do and because every example you see makes you think that there is something neatly structured about a switch. Apart from fall through of course :wink:

wildbill:
The thing that's counterintuitive is that switch case looks highly structured such that each case has its own block of code but it really doesn't.

In reality, the switch uses the case labels as targets to jump to, so you can have all sorts of convoluted stuff in there with case labels in the middle of other constructs. Usually, you don't, because it would be a hideous thing to do and because every example you see makes you think that there is something neatly structured about a switch. Apart from fall through of course :wink:

Exactly. Moreover, we usually use {} statement as body of a switch. But we don't have to. It can be any statement. One can use a continuous if-statement as switch body like this

switch (code)
       if (0) case 0: printf("Code zero\n");
  else if (0) case 1: printf("Code one\n");
  else if (0) case 2: printf("Code two\n");

And the functional beauty of this is that it naturally prevents fallthrough :slight_smile:

The thing that's counterintuitive is that switch case looks highly structured such that each case has its own block of code but it really doesn't.

Have you tried declaring a variable inside a case ? It does not work unless you put { and } around the code for the case

Does that tell us anything about whether each case has its own code block ?

UKHeliBob:
Have you tried declaring a variable inside a case ? It does not work unless you put { and } around the code for the case

No. That is a false and/or misleading statement.

Try this in C++

  int code = 2;    
  switch (code)
  {
    case 0:
      int a;
    case 1:
      double b;
    case 2:
      char c[20];
  }

Report back to the forum.

  • In C you can declare variables "inside a case" without any restrictions. Just remember that in C declarations are not statements - you can't attach labels to them.

  • In C++ you can freely declare variables "inside a case" as long as these variables don't require initialization.

If you meet these requirements, you can freely declare variables anywhere inside switch body without any additional {}.

In C++ the governing rule is: don't jump into variable scope bypassing its initialization. This rule applies to all kind of jumps, not only to switch/case. As long as you meet this requirement, you are OK. Your assumption that in this case "{} around a case" is somehow "required" is incorrect. The {} is just one way to resolve the problem when it arises. It is definitely the most appropriate way to resolve it, but it is not a requirement.

More details.

The Gold Standard for switch/case obfuscation

evanmars:

void loop() {

//here is where you get your input
  if (Serial.available() > 0) {
    int inByte = Serial.read();  // 'd' has been entered

switch (inByte) {  // using 'd'

// cases a-c

case 'd':       
        digitalWrite(5, HIGH);

// you never do a Serial.read() again, so inByte has not changed from 'd'
    if (inByte == "1") {digitalWrite(5, LOW);

break;

i get your point please tell me how i can do serial read again here?

In addition:

abhixs:
Hi sir,
i tried my best but not able to write correct code for me, please help me sir

i want to run a servo motor after sending '1' via serial monitor inside case 'd'.

required program is :

when i send 'a' case 'a' will execute

when i send 'b' case 'a' will execute

and when i send 'd' after that only '1' should work to move servo inside case 'd'

Like I said, make it remember (hint variable :wink: ) it was a 'd' you saw last.

You don't want in IN the case of 'd'. The Arduino is fast! And there is absolutely no guarantee the next character even is received yet!

One approach would be to make a case for '1' as well but only execute that is you saw a 'd' last time.

[off topic] Yeah, the switch does look more structured than it really is indeed. Makes me like it less I have to say...

what is wrong with case c here, if is not working for case c, please help

#include <Wire.h>
#include <LiquidCrystal.h>

LiquidCrystal lcd(13, 12, 11, 10, 9, 8);


void setup() {
  // initialize serial communication:
  Serial.begin(9600);
  // initialize the LED pins:
  for (int thisPin = 2; thisPin < 7; thisPin++) {
    pinMode(thisPin, OUTPUT);
  }
}

void loop()

{
  // read the sensor:
  if (Serial.available() > 0) {
    int inByte = Serial.read();
    int state = Serial.parseInt();
    char data = Serial.read();

    switch (inByte) {


      case 'a':
        digitalWrite(6, LOW);
        digitalWrite(5, LOW);
        digitalWrite(4, LOW);
        digitalWrite(3, LOW);
        digitalWrite(2, HIGH);

        lcd.setCursor(0, 0);
        lcd.print("Step-1");

        break;


      case 'b':
        digitalWrite(6, LOW);
        digitalWrite(5, LOW);
        digitalWrite(4, LOW);
        digitalWrite(3, HIGH);
        digitalWrite(2, LOW);
        lcd.setCursor(0, 0);
        lcd.print("Step-2");

        break;


      case 'c':
        digitalWrite(6, LOW);
        digitalWrite(5, LOW);
        digitalWrite(4, HIGH);
        digitalWrite(3, LOW);
        digitalWrite(2, LOW);
        lcd.setCursor(0, 0);
        lcd.print("Step-3");


        { if (data == 'z')
            lcd.setCursor(0, 0);   //this is not working
          lcd.print("START");   //this is not working
          break;





        case 'd':
          digitalWrite(6, LOW);
          digitalWrite(5, HIGH);
          digitalWrite(4, LOW);
          digitalWrite(3, LOW);
          digitalWrite(2, LOW);

          lcd.setCursor(0, 0);
          lcd.print("Step-5");


          break;


        case 'e':
          digitalWrite(6, HIGH);
          digitalWrite(5, LOW);
          digitalWrite(4, LOW);
          digitalWrite(3, LOW);
          digitalWrite(2, LOW);


          lcd.setCursor(0, 0);
          lcd.print("Step-6");

          break;






          //        default:
          //        // turn all the LEDs off:
          //        for (int thisPin = 2; thisPin < 7; thisPin++) {
          //          digitalWrite(thisPin, LOW);










        }
    }
  }

How many more copies of this topic can we expect?

Thread merged

what is wrong with case c here, if is not working for case c, please help

#include <Wire.h>
#include <LiquidCrystal.h>

LiquidCrystal lcd(13, 12, 11, 10, 9, 8);


void setup() {
  // initialize serial communication:
  Serial.begin(9600);
  // initialize the LED pins:
  for (int thisPin = 2; thisPin < 7; thisPin++) {
    pinMode(thisPin, OUTPUT);
  }
}

void loop()

{
  // read the sensor:
  if (Serial.available() > 0) {
    int inByte = Serial.read();
    int state = Serial.parseInt();


    switch (inByte) {


      case 'a':
        digitalWrite(6, LOW);
        digitalWrite(5, LOW);
        digitalWrite(4, LOW);
        digitalWrite(3, LOW);
        digitalWrite(2, HIGH);

        lcd.setCursor(0, 0);
        lcd.print("Step-1");

        break;


      case 'b':
        digitalWrite(6, LOW);
        digitalWrite(5, LOW);
        digitalWrite(4, LOW);
        digitalWrite(3, HIGH);
        digitalWrite(2, LOW);
        lcd.setCursor(0, 0);
        lcd.print("Step-2");

        break;


      case 'c':
        digitalWrite(6, LOW);
        digitalWrite(5, LOW);
        digitalWrite(4, HIGH);
        digitalWrite(3, LOW);
        digitalWrite(2, LOW);
        lcd.setCursor(0, 0);
        lcd.print("Step-3");


        { if (inByte == 'z')
            lcd.setCursor(0, 0);   //this is not working
          lcd.print("START");   //this is not working
          break;





        case 'd':
          digitalWrite(6, LOW);
          digitalWrite(5, HIGH);
          digitalWrite(4, LOW);
          digitalWrite(3, LOW);
          digitalWrite(2, LOW);

          lcd.setCursor(0, 0);
          lcd.print("Step-5");


          break;


        case 'e':
          digitalWrite(6, HIGH);
          digitalWrite(5, LOW);
          digitalWrite(4, LOW);
          digitalWrite(3, LOW);
          digitalWrite(2, LOW);


          lcd.setCursor(0, 0);
          lcd.print("Step-6");

          break;






          //        default:
          //        // turn all the LEDs off:
          //        for (int thisPin = 2; thisPin < 7; thisPin++) {
          //          digitalWrite(thisPin, LOW);










        }
    }
  }

AWOL:
How many more copies of this topic can we expect?

Thread merged

really sorry for that sir, that was due to an error... i will continue here only

        { if (data == 'z')
            lcd.setCursor(0, 0);   //this is not working
          lcd.print("START");   //this is not working
          break;

You are putting the curly bracket in the wrong place. It should be

          if (data == 'z'){
             lcd.setCursor(0, 0);   //this is not working
             lcd.print("START");   //this is not working
          }
          break;

assuming you want to include in that if both of the statements.

i updated as you suggested , but if is not working in case c

If you don't read again inByte from the serial input it will never be 'z'.
So you have to read again with another Serial.read() before checking the 'z' condition.
Also, why are you storing the 'state' variable that you never use?

  if (Serial.available() > 0)
  {
    int inByte = Serial.read();
    int state = Serial.parseInt();
    char data = Serial.read();

How do you know that 3 bytes of data are available to read ?
Have you tried printing what you read ?
Does the code ever get into case 'c' ?

Your code as posted does not compile. Probably a simple copy/paste error but who knows ?