user49772: I have a very basic circuit setup: 

A button connected to pin 2
An LED connected to pin 9

Desired Functionality: 
When the button is pressed, the user can toggle through 4 LED patterns. 
The Problem: 
Once the first fade pattern begins, the user has to wait until it has finished running before the button can toggle to the next pattern. What  I want is that the button push will move to pattern 2, even if pattern 1 has already started. 
Attempted Solutions: 
I've tried to insert a while function in a couple of places i.e while buttonstate =lastbuttonstate, but that doesn't seem to work. 
Here's the code: (I realize all the fadeloops are the same right now, they will different in the working model) 
//PROBLEM: The fade function has to complete a full loop before allowing toggle to next one


const int  buttonPin = 2;    // the pin that the pushbutton is attached to
const int ledPin = 9;       // the pin that the LED is attached to

// Variables will change:
int buttonPushCounter = 0;   // counter for the number of button presses
int buttonState = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button

int brightness = 0;    // how bright the LED is
int firstFadeAmount = 5;    // how many points to fade the LED by
int secondFadeAmount = 5;    // how many points to fade the LED by


void setup() {
  // initialize the button pin as a input:
  pinMode(buttonPin, INPUT);
  // initialize the LED as an output:
  pinMode(ledPin, OUTPUT);
  // initialize serial communication:
  Serial.begin(9600);
}


void loop() {
  // read the pushbutton input pin:
  buttonState = digitalRead(buttonPin);

  if (buttonState != lastButtonState) {
    if (buttonState == HIGH) {
      buttonPushCounter++;
    } 
    // Delay a little bit to avoid bouncing
    delay(50);
  }
  lastButtonState = buttonState;

  while (buttonPushCounter = lastButtonState) {
    if (buttonPushCounter == 1 && buttonState == HIGH) {
      fadeLoop1(); 
      delay(50);//JP Edit 
    } 

    else if (buttonPushCounter == 2 && buttonState == HIGH) {
      fadeLoop2(); 
      delay(50); 
    } 

    else if (buttonPushCounter == 3 && buttonState == HIGH) {
      fadeLoop3(); 
      delay(50); 
    } 

    else if (buttonPushCounter == 4 && buttonState == HIGH) {
      fadeLoop4(); 
      delay(50); 
    } 

  }
  if (buttonPushCounter == 4) {  //Resets back to zero after 4 presses
     buttonPushCounter = 0;
  }

}


void fadeLoop1()  
{
  for (int i = 0; i < 100; i++) {  //Set the length of the first fading cycle 
    analogWrite(ledPin, brightness);
    brightness = brightness + firstFadeAmount;
    if (brightness <= 0 || brightness >= 255) {
      delay(1000);                  //Sets the hold at the top and bottom of the cycle 
      firstFadeAmount = -firstFadeAmount;
    }
    delay(100);
  }
  for (int i = 0; i < 100; i++) {  //Set the length of second fading cycle
    analogWrite(ledPin, brightness);
    brightness = brightness + secondFadeAmount;
    if (brightness <= 0 || brightness >= 255) {
      secondFadeAmount = -secondFadeAmount;
    }
    delay(30);
  }

  digitalWrite(ledPin, LOW);
}


void fadeLoop2()  
{
  for (int i = 0; i < 100; i++) {  //Set the length of the first fading cycle 
    analogWrite(ledPin, brightness);
    brightness = brightness + firstFadeAmount;
    if (brightness <= 0 || brightness >= 255) {
      delay(1000);                  //Sets the hold at the top and bottom of the cycle 
      firstFadeAmount = -firstFadeAmount;
    }
    delay(100);
  }
  for (int i = 0; i < 100; i++) {  //Set the length of second fading cycle
    analogWrite(ledPin, brightness);
    brightness = brightness + secondFadeAmount;
    if (brightness <= 0 || brightness >= 255) {
      secondFadeAmount = -secondFadeAmount;
    }
    delay(30);
  }

  digitalWrite(ledPin, LOW);
}


void fadeLoop3()  
{
  for (int i = 0; i < 100; i++) {  //Set the length of the first fading cycle 
    analogWrite(ledPin, brightness);
    brightness = brightness + firstFadeAmount;
    if (brightness <= 0 || brightness >= 255) {
      delay(1000);                  //Sets the hold at the top and bottom of the cycle 
      firstFadeAmount = -firstFadeAmount;
    }
    delay(100);
  }
  for (int i = 0; i < 100; i++) {  //Set the length of second fading cycle
    analogWrite(ledPin, brightness);
    brightness = brightness + secondFadeAmount;
    if (brightness <= 0 || brightness >= 255) {
      secondFadeAmount = -secondFadeAmount;
    }
    delay(30);
  }

  digitalWrite(ledPin, LOW);
}


void fadeLoop4()  
{
  for (int i = 0; i < 100; i++) {  //Set the length of the first fading cycle 
    analogWrite(ledPin, brightness);
    brightness = brightness + firstFadeAmount;
    if (brightness <= 0 || brightness >= 255) {
      delay(1000);                  //Sets the hold at the top and bottom of the cycle 
      firstFadeAmount = -firstFadeAmount;
    }
    delay(100);
  }
  for (int i = 0; i < 100; i++) {  //Set the length of second fading cycle
    analogWrite(ledPin, brightness);
    brightness = brightness + secondFadeAmount;
    if (brightness <= 0 || brightness >= 255) {
      secondFadeAmount = -secondFadeAmount;
    }
    delay(30);
  }

  digitalWrite(ledPin, LOW);
}


user42061: Short Answer:
Switch from using a loop for the entire animation and convert to only tracking what needs to happen at a single point in time.
Long Answer:
The 'while' approach is a good way to test out an individual pattern but for the behavior you describe, you need to limit the use of loops inside of the 'loop()' function.
Essentially, if you use a while to control the entire pattern, as you encountered, you have to wait for the while to exit before the rest of the code can check for a button press.
Here is how I've done the same thing.  I don't have the code handy so I'll have to edit the answer later.  The basic form is something like this:
int pattern = 0;
int brightness = 0;
int maxBrightness = 100;

setup() 
{ 
// your setup code here 
}


loop()
{
   if (pattern = 0)
   {
      //increment brightness      
      //call code to set the LED to the current brightness
      if (brightness => maxBrightness)
      {
          brightness = 0;
      }
   }
   checkforbuttonpress();
}

What you notice is I didn't use a for / while loop to do my animation, because the already existing loop() function already does that for me.  All I have to do is track what needs to happen right now, with variables for which pattern and the current brightness for the code to interact with the hardware.  Remember to handle the repetition manually (maxBrightness in this example) and now when the button is pressed, you can change the pattern anywhere because there is no secondary loop to wait for.

49772: <p>I have a very basic circuit setup: </p>

<ul>
<li>A button connected to pin 2</li>
<li>An LED connected to pin 9</li>
</ul>

<p>Desired Functionality: </p>

<p>When the button is pressed, the user can toggle through 4 LED patterns. </p>

<p>The Problem: </p>

<p>Once the first fade pattern begins, the user has to wait until it has finished running before the button can toggle to the next pattern. What  I want is that the button push will move to pattern 2, even if pattern 1 has already started. </p>

<p>Attempted Solutions: </p>

<p>I've tried to insert a while function in a couple of places i.e while buttonstate =lastbuttonstate, but that doesn't seem to work. </p>

<p>Here's the code: (I realize all the fadeloops are the same right now, they will different in the working model) </p>

<pre><code>//PROBLEM: The fade function has to complete a full loop before allowing toggle to next one


const int  buttonPin = 2;    // the pin that the pushbutton is attached to
const int ledPin = 9;       // the pin that the LED is attached to

// Variables will change:
int buttonPushCounter = 0;   // counter for the number of button presses
int buttonState = 0;         // current state of the button
int lastButtonState = 0;     // previous state of the button

int brightness = 0;    // how bright the LED is
int firstFadeAmount = 5;    // how many points to fade the LED by
int secondFadeAmount = 5;    // how many points to fade the LED by


void setup() {
  // initialize the button pin as a input:
  pinMode(buttonPin, INPUT);
  // initialize the LED as an output:
  pinMode(ledPin, OUTPUT);
  // initialize serial communication:
  Serial.begin(9600);
}


void loop() {
  // read the pushbutton input pin:
  buttonState = digitalRead(buttonPin);

  if (buttonState != lastButtonState) {
    if (buttonState == HIGH) {
      buttonPushCounter++;
    } 
    // Delay a little bit to avoid bouncing
    delay(50);
  }
  lastButtonState = buttonState;

  while (buttonPushCounter = lastButtonState) {
    if (buttonPushCounter == 1 &amp;&amp; buttonState == HIGH) {
      fadeLoop1(); 
      delay(50);//JP Edit 
    } 

    else if (buttonPushCounter == 2 &amp;&amp; buttonState == HIGH) {
      fadeLoop2(); 
      delay(50); 
    } 

    else if (buttonPushCounter == 3 &amp;&amp; buttonState == HIGH) {
      fadeLoop3(); 
      delay(50); 
    } 

    else if (buttonPushCounter == 4 &amp;&amp; buttonState == HIGH) {
      fadeLoop4(); 
      delay(50); 
    } 

  }
  if (buttonPushCounter == 4) {  //Resets back to zero after 4 presses
     buttonPushCounter = 0;
  }

}


void fadeLoop1()  
{
  for (int i = 0; i &lt; 100; i++) {  //Set the length of the first fading cycle 
    analogWrite(ledPin, brightness);
    brightness = brightness + firstFadeAmount;
    if (brightness &lt;= 0 || brightness &gt;= 255) {
      delay(1000);                  //Sets the hold at the top and bottom of the cycle 
      firstFadeAmount = -firstFadeAmount;
    }
    delay(100);
  }
  for (int i = 0; i &lt; 100; i++) {  //Set the length of second fading cycle
    analogWrite(ledPin, brightness);
    brightness = brightness + secondFadeAmount;
    if (brightness &lt;= 0 || brightness &gt;= 255) {
      secondFadeAmount = -secondFadeAmount;
    }
    delay(30);
  }

  digitalWrite(ledPin, LOW);
}


void fadeLoop2()  
{
  for (int i = 0; i &lt; 100; i++) {  //Set the length of the first fading cycle 
    analogWrite(ledPin, brightness);
    brightness = brightness + firstFadeAmount;
    if (brightness &lt;= 0 || brightness &gt;= 255) {
      delay(1000);                  //Sets the hold at the top and bottom of the cycle 
      firstFadeAmount = -firstFadeAmount;
    }
    delay(100);
  }
  for (int i = 0; i &lt; 100; i++) {  //Set the length of second fading cycle
    analogWrite(ledPin, brightness);
    brightness = brightness + secondFadeAmount;
    if (brightness &lt;= 0 || brightness &gt;= 255) {
      secondFadeAmount = -secondFadeAmount;
    }
    delay(30);
  }

  digitalWrite(ledPin, LOW);
}


void fadeLoop3()  
{
  for (int i = 0; i &lt; 100; i++) {  //Set the length of the first fading cycle 
    analogWrite(ledPin, brightness);
    brightness = brightness + firstFadeAmount;
    if (brightness &lt;= 0 || brightness &gt;= 255) {
      delay(1000);                  //Sets the hold at the top and bottom of the cycle 
      firstFadeAmount = -firstFadeAmount;
    }
    delay(100);
  }
  for (int i = 0; i &lt; 100; i++) {  //Set the length of second fading cycle
    analogWrite(ledPin, brightness);
    brightness = brightness + secondFadeAmount;
    if (brightness &lt;= 0 || brightness &gt;= 255) {
      secondFadeAmount = -secondFadeAmount;
    }
    delay(30);
  }

  digitalWrite(ledPin, LOW);
}


void fadeLoop4()  
{
  for (int i = 0; i &lt; 100; i++) {  //Set the length of the first fading cycle 
    analogWrite(ledPin, brightness);
    brightness = brightness + firstFadeAmount;
    if (brightness &lt;= 0 || brightness &gt;= 255) {
      delay(1000);                  //Sets the hold at the top and bottom of the cycle 
      firstFadeAmount = -firstFadeAmount;
    }
    delay(100);
  }
  for (int i = 0; i &lt; 100; i++) {  //Set the length of second fading cycle
    analogWrite(ledPin, brightness);
    brightness = brightness + secondFadeAmount;
    if (brightness &lt;= 0 || brightness &gt;= 255) {
      secondFadeAmount = -secondFadeAmount;
    }
    delay(30);
  }

  digitalWrite(ledPin, LOW);
}
</code></pre>
 42061: <h2>Short Answer:</h2>

<p>Switch from using a loop for the entire animation and convert to only tracking what needs to happen at a single point in time.</p>

<h2>Long Answer:</h2>

<p>The 'while' approach is a good way to test out an individual pattern but for the behavior you describe, you need to limit the use of loops inside of the 'loop()' function.</p>

<p>Essentially, if you use a while to control the entire pattern, as you encountered, you have to wait for the while to exit before the rest of the code can check for a button press.</p>

<p>Here is how I've done the same thing.  I don't have the code handy so I'll have to edit the answer later.  The basic form is something like this:</p>

<pre><code>int pattern = 0;
int brightness = 0;
int maxBrightness = 100;

setup() 
{ 
// your setup code here 
}


loop()
{
   if (pattern = 0)
   {
      //increment brightness      
      //call code to set the LED to the current brightness
      if (brightness =&gt; maxBrightness)
      {
          brightness = 0;
      }
   }
   checkforbuttonpress();
}
</code></pre>

<p>What you notice is I didn't use a for / while loop to do my animation, because the already existing loop() function already does that for me.  All I have to do is track what needs to happen right now, with variables for which pattern and the current brightness for the code to interact with the hardware.  Remember to handle the repetition manually (maxBrightness in this example) and now when the button is pressed, you can change the pattern anywhere because there is no secondary loop to wait for.</p>
