Can someone tell me what's wrong with my switch case statement?

Hello, i'm working on a project that requires me to use a button to switch between a RGB LED, a buzzer, and a DC motor, all of which will be controlled by an ultrasonic sensor. I have got the sensor working and it controls each individual component.
However, the switch case statement doesn't seem to be working, it works with the first press which activates the buzzer but any more presses after that don't seem to make it move onto the other components, it just stays on the buzzer.

Any help would be appreciated.

**button = digitalRead(buttonPin);**
**  if(button == 1){**
**    delay(50);**
**    button=digitalRead(buttonPin);**
**    if(button == 0){**
**      currState = prevState +1;**
**    }}**
**    else{**
**      delay(100);**
**    }**
**    switch(currState) {**
**      case 1: **
**    if (distance <= 0) {**
**      distance = 0;**
**    }**

**    else if (distance >= 2 && distance <= 7) {**
**      tone(buzzerPin, 20000, 400);**
**    } else if (distance >= 8 && distance <= 13) {**
**      tone(buzzerPin, 10000, 400);**
**    } else if (distance >= 14 && distance <= 19) {**
**      tone(buzzerPin, 5000, 400);**
**    } else if (distance >= 20 && distance <= 25) {**
**      tone(buzzerPin, 2500, 400);**
**    }**
**    prevState = currState;**
**      break;**
**  **

**      **
**      case 2: **
**      **
**    if (distance >= 1 && distance <= 10) {**
**      RGB_color(255, 0, 0);**
**    } else if (distance >= 11 && distance <= 20) {**
**      RGB_color(0, 255, 0);**
**    } else if (distance >= 21 && distance <= 30) {**
**      RGB_color(0, 0, 255);**
**    } else if (distance >= 31 && distance <= 40) {**
**      RGB_color(255, 255, 0);**
**    }**
**  **
**      prevState = currState;**
**      break;**

**      case 3: {**
**       if (distance >= 1 && distance <= 10) {**
**      analogWrite(motorPin,100);**
**    } else if (distance >= 11 && distance <= 20) {**
**      analogWrite(motorPin,150);**
**    } else if (distance >= 21 && distance <= 30) {**
**      analogWrite(motorPin,200);**
**    } else if (distance >= 31 && distance <= 40) {**
**      analogWrite(motorPin,255);**
**    }**
**  }**
**      prevState = currState;**
**      break;**


**      default:**
**      prevState=0;**
**      break;**
**    }**
**}** 

`

type or paste code here

`

What’s this supposed to do? Detect the state Change and handle bouncing?

The stars make it very Impractical to read…

Please post the entire code.

How is prevState declared?

Is this is the complete code I doubt ?

I think the problem is that you only look at isolated 50-millisecond intervals for a button press. If the button press occurs any other time you don't see it.

You should look at the State Change Detection example in the iDE.

The double "}}" looks odd here.

Remove the stars and try an Arduino/Tools/Autoformat.

With so many nested parentheses, the indentation could be misleading your understanding, and the autoformat and indentation might help highlight a mistake in the structure.

Where did thy come from? :astonished:

OP probably set the Bold flag before adding code tags

button = digitalRead(buttonPin);
  if(button == 1){
    delay(50);
    button=digitalRead(buttonPin);
    if(button == 0){
      currState = prevState +1;
    }}
    else{
      delay(100);
    }
    switch(currState) {
      case 1: 
    if (distance <= 0) {
      distance = 0;
    }

    else if (distance >= 2 && distance <= 7) {
      tone(buzzerPin, 20000, 400);
    } else if (distance >= 8 && distance <= 13) {
      tone(buzzerPin, 10000, 400);
    } else if (distance >= 14 && distance <= 19) {
      tone(buzzerPin, 5000, 400);
    } else if (distance >= 20 && distance <= 25) {
      tone(buzzerPin, 2500, 400);
    }
    prevState = currState;
      break;
  

      
      case 2: 
      
    if (distance >= 1 && distance <= 10) {
      RGB_color(255, 0, 0);
    } else if (distance >= 11 && distance <= 20) {
      RGB_color(0, 255, 0);
    } else if (distance >= 21 && distance <= 30) {
      RGB_color(0, 0, 255);
    } else if (distance >= 31 && distance <= 40) {
      RGB_color(255, 255, 0);
    }
  
      prevState = currState;
      break;

      case 3: {
       if (distance >= 1 && distance <= 10) {
      analogWrite(motorPin,100);
    } else if (distance >= 11 && distance <= 20) {
      analogWrite(motorPin,150);
    } else if (distance >= 21 && distance <= 30) {
      analogWrite(motorPin,200);
    } else if (distance >= 31 && distance <= 40) {
      analogWrite(motorPin,255);
    }
  }
      prevState = currState;
      break;


      default:
      prevState=0;
      break;
    }
}

I'm assuming that you have the buttonPin connected to 5v through a resistor or something like that and then the button connects it to ground which makes the digitalRead return 0. You could use the interrupt function which is only on pins 2 and 3 for the Uno. Interrupt just means as soon as that button is pressed it detects it and interrupts the code to go do whatever things were listed in the interrupt function. For the most part I've not had a need for interrupt so I'm not that familiar with it but I'm pretty sure something like this would work.

int count = 1;
void setup() {
attachInterrupt(digitalPinToInterrupt(2),A,FALLING);//A will call the void A 
//and FALLING means when pin 2 goes from high to low
}

void loop() {
if(count == 1){
  //play Speaker
}
if(count == 2){
  //play LED
}
if(count == 3){
  //play motor
}
}
void A(){
  if(count==3){
    count = 1;
  }
  else{
  count ++;
  }
}

Again not that familiar with interrupt so something might be wrong but it's pretty basic code. While I don't think interrupt is really necessary it doesn't seem like scanning the switch every 50 milliseconds is working for you and maybe this will.

The logic for reading the button is a problem. The button is read, if it is HIGH then there is a 50mS delay and the button is read again. Only when the button changes from HIGH to LOW within that 50mS interval will the value of currState be incremented. Not so much of a problem when currState is zero, because the code is doing nothing but reading the button input and seeing if it is HIGH, but once the buzzer is going the button input is only read at 400mS intervals, at which time if the button input is HIGH then the transition to LOW must occur within the next 50mS or it will not be checked again for 500mS.