Switch statement only entering case 1:

Was this problem figured out? I am having a similar issue.

Split from an old thread

Please give full details of your problem and, in particular, post your code using the advice in

Read this before posting a programming question

Hi,
Welcome to the forum.

Please read the post at the start of any forum , entitled "How to use this Forum".
OR
http://forum.arduino.cc/index.php/topic,148850.0.html.
Then look down to item #7 about how to post your complete code.
It will be formatted in a scrolling window that makes it easier to read.

Thanks.. Tom.. :slight_smile:

Thanks Tom, I was planning on doing some more googling before I posted here but since I already made a splash, here we go.

Basically I am using a switch case to run different codes but it only will enter the 1st case. I am using the same variable in the printmainmenu function and I can scroll through the different menus just fine but when I try to run the different cases in the main loop it just sits there…except for case 1.

#define y A1
#define x A0
#define sw 11

LiquidCrystal lcd(6, 8, 9, 10, 13, 12);
AccelStepper slider(1, 2, 3);

int menuselect = 1;
int menuselectold = 1;

long long posa;
long posb;
unsigned long runtime;
unsigned long framerate;
unsigned long shutterspeed;

int sliderspeed = 1000;

void setup() {
  Serial.begin(2000000);
  lcd.begin(16, 2);
  pinMode(sw, INPUT_PULLUP);

  slider.setMaxSpeed(1000);
  slider.setAcceleration(1000);
  delay(500);
  printmainmenu();
}

void loop() {

  if (analogRead(y) > 850) {
    menuselect++;
    waitjoyrelease();
  }
  if (analogRead(y) < 200) {
    menuselect--;
    waitjoyrelease();
  }
  if (menuselect < 1) menuselect = 6;
  if (menuselect > 6) menuselect = 1;

  if (menuselect != menuselectold) {
    printmainmenu();
    menuselectold = menuselect;
  }

  if (!digitalRead(sw)) {
    waitjoyrelease();
    switch (menuselect) {
      case 1:
        bool posaselect = false;
        lcd.clear();
        lcd.setCursor(3, 0);
        lcd.print("Position A");
        while (posaselect == false) {
          lcd.setCursor(5, 1);
          lcd.print("        ");
          lcd.setCursor(5, 1);
          lcd.print(slider.currentPosition());
          moveslider();
          if (!digitalRead(sw)) {
            posa = slider.currentPosition();
            posaselect = true;
            printmainmenu();
            waitjoyrelease();
          }
        }
        break;

      case 2:
        bool posbselect = false;
        lcd.clear();
        lcd.setCursor(3, 0);
        lcd.print("Position B");
        while (posbselect == false) {
          lcd.setCursor(5, 1);
          lcd.print("        ");
          lcd.setCursor(5, 1);
          lcd.print(slider.currentPosition());
          moveslider();
          if (!digitalRead(sw)) {
            posb = slider.currentPosition();
            posbselect = true;
            printmainmenu();
            waitjoyrelease();
          }
        }
        break;
      case 3:
        bool runtimeselect = false;
        lcd.clear();
        lcd.setCursor(4, 0);
        lcd.print("Runtime");
        while (runtimeselect == false) {
          runtime = timesetup();
          if (!digitalRead(sw)) {
            runtimeselect = true;
            printmainmenu();
            waitjoyrelease();
          }
        }
        break;

      case 4:
        bool framerateselect = false;
        lcd.clear();
        lcd.setCursor(3, 0);
        lcd.print("Framerate");
        while (framerateselect == false) {
          framerate = timesetup();
          if (!digitalRead(sw)) {
            framerateselect = true;
            printmainmenu();
            waitjoyrelease();
          }
        }
        break;

      case 5:
        bool shutterspeedselect = false;
        lcd.clear();
        lcd.setCursor(1, 0);
        lcd.print("Shutter Speed");
        do {
          shutterspeed = timesetup();

          if (!digitalRead(sw)) {
            shutterspeed = shutterspeed * 1000;
            if (shutterspeed == 0) shutterspeed = 100;
            shutterspeedselect = true;
            printmainmenu();
            waitjoyrelease();
          }
        } while (shutterspeedselect == false);
        break;

      case 6:
        lcd.clear();
        lcd.setCursor(7, 0);
        lcd.print("TEMP");
        for (int i = 0; 1 < 10; i++) {
          lcd.setCursor(4, 1);
          lcd.print("Running");
          delay(1000);
          lcd.setCursor(4, 1);
          lcd.print("       ");
          delay(1000);
        }
        printmainmenu();
        break;
    }
  }
}

void printmainmenu() {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("Timelapse Slider");
  lcd.setCursor(1, 1);
  switch (menuselect) {
    case 1:
      lcd.print("Set Position A");
      break;
    case 2:
      lcd.print("Set Position B");
      break;
    case 3:
      lcd.print("Set Runtime");
      break;
    case 4:
      lcd.print("Set Frame Rate");
      break;
    case 5:
      lcd.print("Shutter Speed");
      break;
    case 6:
      lcd.print("Run");
      break;
  }
}

void waitjoyrelease() {
  while (!digitalRead(sw)) {}
  while (analogRead(y) > 600) {}
  while (analogRead(y) < 350) {}
}

This is what I got, both switch cases, one that works fine the other…not so much. There is more functions but I’d hate to post super long code, let me know if you need to see everything.

Thanks for any help you can give.

    switch (menuselect) {
      case 1:
        bool posaselect = false;
//rest of case

If you define a variable inside a switch case the compiler doesn't know what its scope is and this causes unexpected behaviour, such as missing switch cases. The solution is to specify the scope of the variable with a pair of {} for the switch case it belongs to.

      case 1:
        { // Here
        bool posaselect = false;
        lcd.clear();
        lcd.setCursor(3, 0);
        lcd.print("Position A");
        while (posaselect == false) {
          lcd.setCursor(5, 1);
          lcd.print("        ");
          lcd.setCursor(5, 1);
          lcd.print(slider.currentPosition());
          moveslider();
          if (!digitalRead(sw)) {
            posa = slider.currentPosition();
            posaselect = true;
            printmainmenu();
            waitjoyrelease();
          }
        }
        break;
        }  // And here

In answer to the question you have not asked, which is why is your code slow and unresponsive, it’s because of the blocking while() loops. The code gets stuck at each of your while() statements. You will find the following helpful in writing non-blocking code:
Demonstration for several things at the same time

Hi,
Can I suggest you read ALL your inputs at the start of the loop and assign them to variables.
Then use the variables throughout your code.

In other words take a snapshot of your project and act on that data, then go back to the top of the loop and read again.

As has been pointed out, using delay() is blocking your code.

When you have delay(1000), you are getting your code to STOP for 1 second, in that time it does nothing but wait, it does not read any inputs, write any outputs or run any code.

Thanks.. Tom.. :slight_smile:

Thanks for the feedback guys. Perry, I will try the curly cues, tbh I was thinking about putting those booleans elsewhere anyway, I just didn’t know they were causing me issues where I left them.

I guess I didn’t explain what this is supposed to do very well (it was very early in the morning after a 6 hour coding session.) This is for a timelapse slider with an LCD menu. My input is a joystick (X,Y, and Switch) Each case runs different code so the user can input the variables. so in the “main” menu when the user hits the joystick it will scroll through the different options (set position a, set position b, set framerate…etc…)

 if (analogRead(y) > 850) {
    menuselect++;
    waitjoyrelease();
  }
  if (analogRead(y) < 200) {
    menuselect--;
    waitjoyrelease();
  }
  if (menuselect < 1) menuselect = 6;
  if (menuselect > 6) menuselect = 1;

  if (menuselect != menuselectold) {
    printmainmenu();
    menuselectold = menuselect;
  }

This part of the code loops until the switch is hit the joystick controls what menuselect is and the lcd will update if menuselect changes.

 if (!digitalRead(sw)) {
    waitjoyrelease();
    switch (menuselect) {
      case 1:
        bool posaselect = false;
        lcd.clear();
        lcd.setCursor(3, 0);
        lcd.print("Position A");
        while (posaselect == false) {
          lcd.setCursor(5, 1);
          lcd.print("        ");
          lcd.setCursor(5, 1);
          lcd.print(slider.currentPosition());
          moveslider();
          if (!digitalRead(sw)) {
            posa = slider.currentPosition();
            posaselect = true;
            printmainmenu();
            waitjoyrelease();
          }
        }
        break;

if the switch is pushed then the code executes based on what menuselect is, each case has its own while loop because the user has to be happy with the setting. So the user in this case will use the joystick to run a stepper motor(moving the camera slider) and when they are happy they hit the button again to exit the while loop(that’s what the booleans are for.)

So basically it is doing exactly what I want it to do, its not clunky or slow at all(at least when I fix the variables.) I am open to ideas on how to do it better/cleaner but it has to be at least as smart as the user.

It might well do what you want it to do now, but writing code that stops like that is a dead end and will not serve you well in future. Read the tutorial I liked to above and also this one:
Using millis for timing

You wouldn’t expect this when you go into a restaurant:
A waiter meets you at the door, takes you to a table, gives you a menu then waits by your table while you decide what to order. The waiter takes your order, goes to the kitchen and waits there while the chef cooks your food. When the food is ready the waiter brings it to your table then waits by your table while you eat it. When you’ve finished eating the waiter takes your plates away and returns to ask if you want anything else. This continues until you leave. No one else gets served. This is how your code is working at the moment.
I’m not going to describe what really happens in a restaurant as you already know. A waiter uses exactly the same system as a state machine to serve people when they need serving and check to see who needs serving next between dealing with customers. You can build functions for the different tasks a waiter does such as:

void takeOrder();
void bringFoodToTable();

You call these from loop(); While in loop the waiter checks to see if any tables need attention, and if they do s/he goes to find out what they need. If not, then s/he keeps checking until someone needs something. Computer code should be written along the same principals.