switch case statement break not working on button press

Can anyone help me figure out why this isn't working?
I have one button. When I click it once, it changes case. When I click it two times, I want it to stop the for loop counter, and switch to the next case statement. Any help is greatly appreciated.

int buttonState;
unsigned long timePress = 0;
unsigned long timePressLimit = 0;
int clicks = 0;
int mode = 0;
int break_out = 0;

void setup() {
  Serial.begin(115200);
  pinMode(buttonPin ,INPUT);
 
}

void loop() {
   // put your main code here, to run repeatedly: 
  buttonState = digitalRead(buttonPin);
 
  if (buttonState == HIGH){
    delay(200);   
    if (clicks == 0) {
    timePress = millis();
    timePressLimit = timePress + 500;   
    clicks = 1;
    }
    else if (clicks == 1 && millis() < timePressLimit){
      Serial.println("Button Pressed twice");   
      //some code goes here?
      mode = mode + 1;  // need to make it advance to next one.
      break_out = 1;
      Serial.println(mode);    
     //set variables back to 0
      timePress = 0;
      timePressLimit = 0;
      clicks = 0;     
    }   
  }

  if (clicks == 1 && timePressLimit != 0 && millis() > timePressLimit){
     Serial.println("Button Pressed Once");
     timePress = 0;
     timePressLimit = 0;
     clicks = 0;
     //some code goes here?
     mode = mode + 1;    
     Serial.println(mode);
     switch_shows(mode);      
  }  
}

void switch_shows(int new_mode){
  switch(new_mode) {           // Start the new animation...
    case 0:
      break;
    case 1:
       if (break_out == 1){
        break;        
       }      
      for (int i = 0; i < 100; i ++){
       Serial.println(i);    
       delay (100);             
      }       
    case 2:
      Serial.println("stop here");   
      break;
    case 3:
      break;
    case 4:
      break;
    case 5:
      break;
    case 6:
      break;
    case 7:   
      break;     
    case 8:
      break;
  }  
}

Off hand I see a few issues but I will have to look at the code closer later.

  1. If your button is wired the usual way where common is connected to the input when the button is pressed then you will need to specify INPUT_PULLUP when you call pinMode

  2. Given your button is wired the usual way then when the button is pressed you will get a HIGH to LOW transition. You need to save the last state of the button and check for a HIGH to LOW transition to detect a button push.

  3. After the print loop in case 1 of your switch you need to add a break otherwise it will fall directly into the case 2.

Hi, thanks for the reply. I changed it to INPUT_PULLUP. The button is wired the way you mentioned.
Here is the code for adding the break at the end of case 1. I'm not sure why it still isn't breaking out of the case before it completes the for loop. I want two button presses to break it out of the for loop before it is done counting to 99. How do I save the previous state of the button? I thought that was accomplished with the timer. Thanks for the help.

    case 1:     
      for (int i = 0; i < 100; i ++){
       Serial.println(i);    
       delay (100);  
       if (break_out == 1){
        break;        
       }                   
      }
      break;       
    case 2:
      Serial.println("stop here");   
      break;

SteveRogers:
Hi, thanks for the reply. I changed it to INPUT_PULLUP. The button is wired the way you mentioned.
Here is the code for adding the break at the end of case 1. I'm not sure why it still isn't breaking out of the case before it completes the for loop. I want two button presses to break it out of the for loop before it is done counting to 99. How do I save the previous state of the button? I thought that was accomplished with the timer. Thanks for the help.

Below is a version of your code that test for a HIGH to LOW transition on the button pin. By the way, in the code you posted you did not have buttonPin defined so I defined it so it would compile, but it may be different than the pin you chose.

I don't see any reason why it should break out of the for loop if you press a button. Are you assuming the function switch_shows executes concurrently with the for loop? It does not. If you want to break out of the for loop using a button push you will have to monitor the button in the for loop.

int buttonState;
int lastbuttonState;
unsigned long timePress = 0;
unsigned long timePressLimit = 0;
int clicks = 0;
int mode = 0;
int break_out = 0;
const byte buttonPin = 2;

void setup() {
  Serial.begin(115200);
  lastbuttonState = HIGH;
  pinMode(buttonPin, INPUT_PULLUP);

}

void loop() {
  // put your main code here, to run repeatedly:
  buttonState = digitalRead(buttonPin);

  if (lastbuttonState == HIGH && buttonState == LOW) {
    delay(200);
    if (clicks == 0) {
      timePress = millis();
      timePressLimit = timePress + 500;
      clicks = 1;
    }
    else if (clicks == 1 && millis() < timePressLimit) {
      Serial.println("Button Pressed twice");
      //some code goes here?
      mode = mode + 1;  // need to make it advance to next one.
      break_out = 1;
      Serial.println(mode);
      //set variables back to 0
      timePress = 0;
      timePressLimit = 0;
      clicks = 0;
    }
  }

  lastbuttonState = buttonState;
  
  if (clicks == 1 && timePressLimit != 0 && millis() > timePressLimit) {
    Serial.println("Button Pressed Once");
    timePress = 0;
    timePressLimit = 0;
    clicks = 0;
    //some code goes here?
    mode = mode + 1;
    Serial.println(mode);
    switch_shows(mode);
  }
}

void switch_shows(int new_mode) {
  switch (new_mode) {          // Start the new animation...
    case 0:
      break;
    case 1:
      for (int i = 0; i < 100; i ++){
       Serial.println(i);    
       delay (100);  
       if (break_out == 1){
        break;        
       }                   
      }
      break;       
    case 2:
      Serial.println("stop here");
      break;
    case 3:
      break;
    case 4:
      break;
    case 5:
      break;
    case 6:
      break;
    case 7:
      break;
    case 8:
      break;
  }
}

that makes sense. I thought it was checking the button in the loop already, while the loop was running. How would I check to see if the button is pressed within the for loop?

SteveRogers:
that makes sense. I thought it was checking the button in the loop already, while the loop was running. How would I check to see if the button is pressed within the for loop?

It is checking the button in loop() but you are calling switch_shows() from loop() and when switch_shows() finishes executing it returns to loop(). You understand calling a function does not mean concurrent execution, right?

Anyhow, you can check the button the same way I outlined in the code I posted. In the for loop read the pin and compare it to the previous state. When you see a HIGH to LOW transition then exit the loop.

that sort of makes sense. I tried the code you posted. It didn't break out of the for loop...I still seem to be missing something.

SteveRogers:
that sort of makes sense. I tried the code you posted. It didn't break out of the for loop...I still seem to be missing something.

It won't break out of the for loop until you check the button in the for loop.

Right, that I get. I guess I am just not seeing how to do that. thanks for all your help so far. Something will click soon.

SteveRogers:
Right, that I get. I guess I am just not seeing how to do that. thanks for all your help so far. Something will click soon.

Just read the button state and compare it.

      for (int i = 0; i < 100; i ++){
       buttonState = digitalRead(buttonPin);
       if (lastbuttonState == HIGH && buttonState == LOW) {
         delay(200); // delay for bouncing
         break;
       }
       lastbuttonState = buttonState;
       Serial.println(i);    
       delay (100);  
      }