LED Fade Loop Inturruption with Push Button

I am super new to Arduino, and almost just as new to programming. Yes, this is homework, no I don't want anyone to just give me the answer, just point me in the right direction, I'm super lost. I'm sure there is something simple I've missed here. I need this code to begin fading the LED from 0-255 when the button is pushed once, then turn off once it reaches 255. It does that just fine. The other thing I need it to do is to stop mid-loop and reset to 0 (and stay there) if I push the button while the loop is running. This is my code, what have I done wrong here?

const int LED=9;
const int BUTTON=2;
boolean lastButton = LOW;
boolean currentButton = LOW;
boolean ledOn = false;
boolean buttonState = LOW;

void setup() {
pinMode (LED, OUTPUT);
pinMode (BUTTON, INPUT);

}

boolean debounce(boolean last)
{
boolean current = digitalRead(BUTTON);
if (last != current)
{
delay(5);
current = digitalRead(BUTTON);
}
return current;
}

void loop() {
currentButton = debounce(lastButton);
if (lastButton == LOW && currentButton == HIGH)
{
for (int i=0; i<256; i++)
{

analogWrite(LED, i);
delay(10);

}
buttonState = digitalRead(BUTTON);
if (buttonState != currentButton)
{
digitalWrite(LED, LOW);
}
}

lastButton = currentButton;
digitalWrite(LED, ledOn);

Instead of using a for loop why not let the loop() function do what its name implies ?

Decrement a variable each time round loop() and then you can read the input frequently. For extra points, do away with the delay() to make the program even more responsive to inputs

See Using millis() for timing. A beginners guide, Several things at the same time and look at the BlinkWithoutDelay example in the IDE.

Please edit your post putting your code between a code and a /code tags. code and /code must be in []. I can't write them here, because you could only see a code box!

The button needs a pull-up (if switch closes to ground) or a pull-down resistor (if switch closes to +V). You can activate pull-up resistors by software:

pinMode (BUTTON, INPUT);

digitalWrite(BUTTON, HIGH);
or
pinMode(BUTTON, INPUT_PULLUP);

Usually switches close to ground, because you don't have to run +V wires.

Instead of wasting code for debouncing, you can simply connect a 1uF capacitor (via 100 ohm, if you want to be meticulous) from input pin to ground or to +V.

for (int i=0; i<256; i++) {analogWrite(LED, i); delay(10);}Please note that you don't check the button in the for loop, then you can do nothing until the loop ends.

This is a night LED controller i wrote a year and a half ago, when I was doing my first experiences with Arduino. It is a fading LED of which you can set fade time between 10 and 60 minutes pushing the button at power on:

#include<avr/sleep.h>
#include<EEPROM.h>
#define LED 10
#define SW 4

byte B=0;
int X=0;
byte n=0; 
byte minuti=10; // Durata dello sfumo
unsigned long T=0;
unsigned long t0=0;
unsigned long t1=0;
byte S=0; // S=1 indica che è passato per il "set"
int I[]={0,20,40,70,120,180,255}; // I[minuti/10] indica l'intensità del LED 
               // per indicare le diverse durate, I[0] è 0 poiché non lo uso.

void setup()
{
Serial.begin(9600);
pinMode(LED, OUTPUT);
pinMode(SW, INPUT);
pinMode(SW, HIGH); // Pullup
lamp();
t0=millis();

while(millis()-t0<2000)
  {
  if(digitalRead(SW)==LOW) set();
  }

} // END Setup



void loop()
{
inizia:
B=EEPROM.read(0); // Legge i minuti impostati.
if(B==255) EEPROM.update(0,10); // Se nella EEPROM c'è scritto 255, significa
                      // che è vergine o cancellata, perciò imposta 10 minuti.
T=B*60000/255; // Calcola la durata di ciascun passo.

if(S==0) // Se non è passato dal "set", visualizza la scala di intensità
  {      // fino al tempo precedentemente impostato.
  for(n=1; n<=B/10; n++)
    {
    analogWrite(LED,I[n]); // Visualizza la scala fino al tempo preimpostato.
    delay(600);
    }
  delay(400);
  digitalWrite(LED,0);
  delay(1000);
  }
else{digitalWrite(LED,0); delay(1000);} // Se viene dal "set", fa solo 
                                        // 1 secondo di buio.
for(X=256; X>0; X--) // Inizia lo sfumo.
  {
  analogWrite(LED,X-1);
  delay(T);
  } // Il tempo è finito: va in Power down.
  
set_sleep_mode(SLEEP_MODE_PWR_DOWN);   // Imposta il modo Power down.
sleep_enable(); // Enables the sleep bit in the mcucr register
                // so sleep is possible. Just a safety pin.
sleep_mode();   // Here the device is actually put to sleep! 
}



void set()
{
S=1; // Memorizza che è passato per il "set".
analogWrite(LED,I[1]); minuti=10;

while(digitalRead(SW)==LOW); // Attende che venga lasciato il pulsante.
t1=millis();
while(millis()-t1<1000)
  {
  if(digitalRead(SW)==LOW) {analogWrite(LED,I[2]); minuti=20; delay(300); goto due;}
  }                           // I[...] è l'intensità relativa ai minuti impostati.
EEPROM.update(0,10); Serial.println("10  Update!"); goto fuori;

due:
while(digitalRead(SW)==LOW); // Attende che venga lasciato il pulsante
t1=millis();
while(millis()-t1<1000)
  {
  if(digitalRead(SW)==LOW) {analogWrite(LED,I[3]); minuti=30; delay(300); goto tre;}
  }
EEPROM.update(0,20); Serial.println("20 Update!"); goto fuori;

tre:
while(digitalRead(SW)==LOW); // Attende che venga lasciato il pulsante
t1=millis();
while(millis()-t1<1000)
  {
  if(digitalRead(SW)==LOW) {analogWrite(LED,I[4]); minuti=40; delay(300); goto quattro;}
  }
EEPROM.update(0,30); Serial.println("30 Update!"); goto fuori;

quattro:
while(digitalRead(SW)==LOW); // Attende che venga lasciato il pulsante
t1=millis();
while(millis()-t1<1000)
  {
  if(digitalRead(SW)==LOW) {analogWrite(LED,I[5]); minuti=50; delay(300);  goto cinque;}
  }
EEPROM.update(0,40); Serial.println("40 Update!"); goto fuori;

cinque:
while(digitalRead(SW)==LOW); // Attende che venga lasciato il pulsante
t1=millis();
while(millis()-t1<1000)
  {
  if(digitalRead(SW)==LOW) {analogWrite(LED,I[6]); minuti=60; EEPROM.update(0,60); Serial.println("60 Update!"); goto fuori;}
  }
EEPROM.update(0,50); Serial.println("50 Update!"); goto fuori;

fuori:
Serial.print(minuti); Serial.print(" minuti   ");Serial.println(I[int(minuti/10)]);
delay(10); // No operation
} // END Set



void lamp()
{
digitalWrite(LED,1);
delay(50);
digitalWrite(LED,0);
delay(50);
}

This is the v2.0, using an RGB LED:

/*
1.1b 12/9/16  Finalmente funziona tutto! Avevo anche avuto il problema che, facendo scrivere qualcosa dalla 
              seriale per le prove, andava a "premere" il pulsante che stava sulla porta 1!!!
2.0  12/9/16  Versione con LED RGB: Sfuma dal bianco verso il rosso. R, G e B deboli e poi intensi vengono  
              anche usati per indicare il tempo.
2.0a 14/9/16  Ho abbassato l'intensità dei lampi iniziali e velocizzato la scala del tempo preimpostato.
 */

#include<avr/sleep.h>
#include<EEPROM.h>
#define LEDR 3
#define LEDV 5
#define LEDB 6
#define SW 10

byte TEST=0;
byte B=0;
int X=0; int Y=0; int Z=0;
byte n=0; 
byte minuti=10; // Durata dello sfumo
byte L=10; // Intensità bassa
byte H=80; // Intensità alta
unsigned long T=0;
unsigned long t0=0;
unsigned long t1=0;
byte S=0; // S=1 indica che è passato per il "set"

void setup()
{
// Serial.begin(9600);
pinMode(LEDR, OUTPUT);
pinMode(LEDV, OUTPUT);
pinMode(LEDB, OUTPUT);
pinMode(SW, INPUT_PULLUP);
if(digitalRead(SW)==LOW){TEST=1; lampR(); lampR(); lampR(); delay(1000);}
                 // Fa 3 lampi rossi per indicare che è in modalità TEST.
                 // 3 red flashes: TEST mode (fast cycle).
lampB();         // Fa 1 lampo blu per indicare che si può impostare il tempo.
t0=millis();     // 1 blue flash: you can set fade time.
while(millis()-t0<2000) {if(digitalRead(SW)==LOW) set();}
} // END Setup



void loop()
{
B=EEPROM.read(0); // Legge i minuti impostati.
if(B==255) EEPROM.update(0,10); // Se nella EEPROM c'è scritto 255, significa
                      // che è vergine o cancellata, perciò imposta 10 minuti.
if(TEST==0) {T=B*60000/255;} // Calcola la durata di ciascun passo.
else T=B*500/255; // In modo TEST va a 120x (5 sec = 10 min).

if(S==0) // Se non è passato dal "set", visualizza la scala di intensità
  {      // fino al tempo precedentemente impostato.
  for(n=1; n<=B/10; n++)
    {
    spegnetutto();  
    switch(n) // Visualizza la scala fino al tempo preimpostato.
      {
      case 1: analogWrite(LEDR,L); break;
      case 2: analogWrite(LEDV,L); break;
      case 3: analogWrite(LEDB,L); break;
      case 4: analogWrite(LEDR,H); break;
      case 5: analogWrite(LEDV,H); break;
      case 6: analogWrite(LEDB,H); break;
      }
    delay(350);
    }
  delay(200);  spegnetutto();  delay(1500);
  }
else{spegnetutto(); delay(1500);} // Se viene dal "set", fa solo 
                                  // 1 secondo di buio.
Y=255; Z=255;                                  
for(X=256; X>0; X--) // Inizia lo sfumo.
  {
  if(Y<0) Y=0; if(Z<0) Z=0;
  analogWrite(LEDR,X-1);
  analogWrite(LEDV,Y);
  analogWrite(LEDB,Z);
  delay(T); Y-=2; Z-=3;
  } // Il tempo è finito: va in Power down.
  
set_sleep_mode(SLEEP_MODE_PWR_DOWN);   // Imposta il modo Power down.
sleep_enable(); // Enables the sleep bit in the mcucr register
                // so sleep is possible. Just a safety pin.
sleep_mode();   // Here the device is actually put to sleep! 
}


void set()
{
S=1; // Memorizza che è passato per il "set".
analogWrite(LEDR,L); minuti=10;

while(digitalRead(SW)==LOW) {delay(100);} // Attende che venga lasciato il pulsante.
t1=millis();
while(millis()-t1<1000)
  {
  if(digitalRead(SW)==LOW) {spegnetutto(); analogWrite(LEDV,L); minuti=20; delay(300); goto due;}
  }                           // I[...] è l'intensità relativa ai minuti impostati.
EEPROM.update(0,10); goto fuori;

due:
while(digitalRead(SW)==LOW) {delay(100);} // Attende che venga lasciato il pulsante
t1=millis();
while(millis()-t1<1000)
  {
  if(digitalRead(SW)==LOW) {spegnetutto(); analogWrite(LEDB,L); minuti=30; delay(300); goto tre;}
  }
EEPROM.update(0,20); goto fuori;

tre:
while(digitalRead(SW)==LOW) {delay(100);} // Attende che venga lasciato il pulsante
t1=millis();
while(millis()-t1<1000)
  {
  if(digitalRead(SW)==LOW) {spegnetutto(); analogWrite(LEDR,H); minuti=40; delay(300); goto quattro;}
  }
EEPROM.update(0,30); goto fuori;

quattro:
while(digitalRead(SW)==LOW) {delay(100);} // Attende che venga lasciato il pulsante
t1=millis();
while(millis()-t1<1000)
  {
  if(digitalRead(SW)==LOW) {spegnetutto(); analogWrite(LEDV,H); minuti=50; delay(300);  goto cinque;}
  }
EEPROM.update(0,40); goto fuori;

cinque:
while(digitalRead(SW)==LOW) {delay(100);} // Attende che venga lasciato il pulsante
t1=millis();
while(millis()-t1<1000)
  {
  if(digitalRead(SW)==LOW) {spegnetutto(); analogWrite(LEDB,H); minuti=60; EEPROM.update(0,60); delay(1000); goto fuori;}
  }
EEPROM.update(0,50); goto fuori;

fuori:
delay(10); // No operation
} // END Set


void lampB()
{
analogWrite(LEDB, H); delay(50);
analogWrite(LEDB, 0); delay(50);
}

void lampR()
{
analogWrite(LEDR, H); delay(50);
analogWrite(LEDR, 0); delay(50);
}



void spegnetutto()
{
digitalWrite(LEDR, LOW);
digitalWrite(LEDV, LOW);
digitalWrite(LEDB, LOW);
}

And if you just want simple, have a look at my library FadeLed :slight_smile:

septillion:
And if you just want simple, have a look at my library FadeLed :slight_smile:

If you REALLY want simple, simply read the state of the switch on each pass through each for loop. Break out of the loop if the switch is pressed. As long as you press the switch for 10 milliseconds, polling will be sufficient to not miss any presses.