Stuck in loop, waiting for button press

Hi,

Just got my Arduino and started playing, now I'm stuck in a loop and I can't the Arduino to respond to a button press to break out of it. I don't know much code, so any suggestions are appreciated. Anyways, the button works until trying to get out of the if (state == 4) section of my code. No button presses work, but I'd like it to set it back to 0 (as you can probably see in the code below). Any suggestions on why it isn't responding?

//Turn one LED on in succession when a button is pressed
//Glow LED one at a time after, then turn off

#define BUTTON 2
#define RED 3
#define WHITE 4
#define BLUE 5

int val = 0;  //Counter to store state of input pin
int old_val = 0; //Previous value
int state = 0; //0 = all LED off, 1 = red LED on, 2 = white LED on, 3 = blue LED on
int ir = 0; //RED counter
int iw = 0; //WHITE counter
int ib = 0; //BLUE counter

void setup() {
//  Serial.begin(9600);
  pinMode(BUTTON,INPUT);
  pinMode(RED,OUTPUT);
  pinMode(WHITE,OUTPUT);
  pinMode(BLUE,OUTPUT);
}

void loop() {
  val = digitalRead(BUTTON); //Read input and store it
  if (val != old_val) {
    if (val == HIGH) {
    state++;
    delay(10);
    }
  }
  
  old_val = val;  //Stores old value
  
  if (state % 5 == 0 ) {
    state = 0;  //Sets state back to 0 after cycling through LEDs
  }
  
  if (state == 1) {
    digitalWrite(RED,HIGH); //turn RED on
//  Serial.println("RED is on");
  } else {
    digitalWrite(RED,LOW); //turn RED off
  }
  if (state == 2) {
    digitalWrite(WHITE,HIGH); //turn WHITE on
//    Serial.println("WHITE is on");
  } else {
    digitalWrite(WHITE,LOW); //turn WHITE off
  }
  if (state == 3) {
    digitalWrite(BLUE,HIGH); //turn BLUE on
//   Serial.println("BLUE is on");
  } else {
    digitalWrite(BLUE,LOW); //turn BLUE off
  }
// NOT RESPONDING TO BUTTON PRESS IN THIS SECTION
  if (state == 4) { 
    for (ir=0; ir<255; ir++) { //Fade RED in
      analogWrite(RED,ir);
      delay(5);
    }
    for (ir=255; ir>0; ir--) {
      analogWrite(RED,ir);
      delay(5);
    }
    for (iw=0; iw<255; iw++) { //Fade RED in
      analogWrite(WHITE,iw);
      delay(5);
    }
    for (iw=255; iw>0; iw--) {
      analogWrite(WHITE,iw);
      delay(5);
    }
    for (ib=0; ib<255; ib++) { //Fade RED in
      analogWrite(BLUE,ib);
      delay(5);
    }
    for (ib=255; ib>0; ib--) {
      analogWrite(BLUE,ib);
      delay(5);
    }
  }  
}

Also if you see something glaringly ugly in my code let me know, I'd like to start out doing things the right way, not some backwards way that happens to work. Thanks.

  if (state % 5 == 0 ) {
    state = 0;  //Sets state back to 0 after cycling through LEDs
  }

kinda sleepy but I think this is your issue, 1 / 5 gives a decimal, since your using integers it's a 0

I also tried

if (state == 5) {
state = 0;
}

which worked when I only had the first 3 if statements for LEDs. I also outputted to the serial console and it responds to a button press until the 4th, then it stops counting the button presses. It's stuck inside the if { for {}} loops :-/

If you want it to read the button you have to use digitalRead again, and include code to change the state. You can put that inside the 'for loops'.
You would also want to put 'if (state==4){ in front of the 'for loops' if you want to ignore them once you change the state.

you also might want to consider using if else if else that way you can have as many as you want without fiddling with a hard coded number

example

if (state==1)
else if (state==2)
else if (state==3)
else state = 0

Thanks. So would I have to add

val = digitalRead(BUTTON); //Read input and store it
  if (val != old_val) {
    if (val == HIGH) {
    state++;
    delay(20);

to each for loop? If so, Is there a way to just reference that section of code like GOTO in .bat files?

And thanks for the else if tip Osgeld.

Adding that code into the for loops didn't work. It still doesn't seem to be waiting for a button press... Could somebody maybe explain why it isn't accepting an input during these for loops? And maybe somewhere there is an example like this?

Could somebody maybe explain why it isn't accepting an input during these for loops? And maybe somewhere there is an example like this?

In the code that you posted, you read the button state at the top of the loop() function. For all states other than 4, you turn an LED on, and then loop() ends, and repeats.

For state 4, you run 6 loops, from 0 to 255, with a 5 millisecond delay after each action. Each loop takes just over 1.5 seconds to complete, for a total of more than 9 seconds.

So, you are only looking at the button state for a new nanoseconds, once every 9+ seconds. Quite easy to miss the button press, unless you hold the button down.

Look at the blink without delay example for some hints on how to not use delay, or check the button state more often.

Checking the button state can be done in a function that returns true or false. You'll need to terminate the loop you are in, and not execute any others if you find that the button was pressed.