Arduino - muliple function wait list

Hello, I`m trying to make simpel ledstrip code, so I can change the colors and patterns with a button. I want to do this while an other code is running for the colors. This works but when it is finiched the previous function goes again. Its just like its in a waiting list. How Can I fix this ?

Im using arduino uno and aWS2812B ledstrip.

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
 #include <avr/power.h>
#endif

#define commonPin   2

#define PIXEL_PIN    3
 
#define PIXEL_COUNT 300 

Adafruit_NeoPixel strip(PIXEL_COUNT, PIXEL_PIN, NEO_GRB + NEO_KHZ800);
int     mode     = 0;
unsigned long lastFire = 0;
void setup() {
  pinMode(commonPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(commonPin), pressInterrupt, FALLING);
  strip.begin();
  strip.show();
  Serial.begin(9600);
}
void loop() {
}
void pressInterrupt() {
    if (millis() - lastFire < 200) {
        return;
    }
    lastFire = millis();
    Serial.println("druk");
      if(++mode > 8) mode = 0;
      switch(mode) {
        case 0:
          colorWipe(strip.Color(  0,   0,   0), 50);    // Black/off
          break;
        case 1:
          colorWipe(strip.Color(255,   0,   0), 50);    // Red
          break;
        case 2:
          colorWipe(strip.Color(  0, 255,   0), 50);    // Green
          break;
        case 3:
          colorWipe(strip.Color(  0,   0, 255), 50);    // Blue
          break;
        case 4:
          theaterChase(strip.Color(127, 127, 127), 50); // White
          break;
        case 5:
          theaterChase(strip.Color(127,   0,   0), 50); // Red
          break;
        case 6:
          theaterChase(strip.Color(  0,   0, 127), 50); // Blue
          break;
        case 7:
          rainbow(10);
          break;
        case 8:
          theaterChaseRainbow(50);
          break;
      }
}                               
void colorWipe(uint32_t color, int wait) {
  for(int i=0; i<strip.numPixels(); i++) {
    strip.setPixelColor(i, color);
    strip.show();
    delay(wait);
  }
}
void theaterChase(uint32_t color, int wait) {
  for(int a=0; a<10; a++) {
    for(int b=0; b<3; b++) {
      strip.clear();
      for(int c=b; c<strip.numPixels(); c += 3) {
        strip.setPixelColor(c, color);
      }
      strip.show();
      delay(wait);
    }
  }
}
void rainbow(int wait) {
  for(long firstPixelHue = 0; firstPixelHue < 3*65536; firstPixelHue += 256) {
    for(int i=0; i<strip.numPixels(); i++) {
      int pixelHue = firstPixelHue + (i * 65536L / strip.numPixels());
      strip.setPixelColor(i, strip.gamma32(strip.ColorHSV(pixelHue)));
    }
    strip.show();
    delay(wait);
  }
}
void theaterChaseRainbow(int wait) {
  int firstPixelHue = 0;
  for(int a=0; a<30; a++) {
    for(int b=0; b<3; b++) {
      strip.clear();
      for(int c=b; c<strip.numPixels(); c += 3) {
        int      hue   = firstPixelHue + c * 65536L / strip.numPixels();
        uint32_t color = strip.gamma32(strip.ColorHSV(hue));
        strip.setPixelColor(c, color);
      }
      strip.show();
      delay(wait);
      firstPixelHue += 65536 / 90;
    }
  }
}

So when I change from function to a new function while the other function is running. And the new function is finiched the old starts to continuou.
I hope someone can help me.

you probably have a pending interrupt due to bounce on a button press. you return if an interrupt occurs w/in 200 msec, but many of your actions take longer than that.

this is an interesting but unconventional use of an interrupt. you would have more control by monitoring for a button press in loop()

If I put my button code in loop(), then I need to wait until the functions are completed until I can push on it again, becaus it is there looping. Thats why I used interrupt.

But thats not my problem its working fine.
I need to find a way that I can break out of the other functions from my interrupt method.

if you want to interrupt your functions before they complete, you'll need to add code to check for a button press in each of them

Jeah, I tried that but then I had a problem that my button didn`t always work becaus of the delays in the loops. Is there no way to break specified functions ?

why didn't it work because of the delays? you need to check for a button press in the inner loops before each delay

Adafruit has a tutorial on this very topic: Overview | Multi-tasking the Arduino - Part 3 | Adafruit Learning System

Ok I made a function to check my button and put it in al my functions. But my problem isn`t solved yet. My code does exactily the same as it did before.

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
 #include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif
#define BUTTON_PIN   2

#define PIXEL_PIN    3  // Digital IO pin connected to the NeoPixels.

#define PIXEL_COUNT 300  // Number of NeoPixels
Adafruit_NeoPixel strip(PIXEL_COUNT, PIXEL_PIN, NEO_GRB + NEO_KHZ800);

boolean oldState = HIGH;
int     mode     = 0;    // Currently-active animation mode, 0-9
unsigned long lastFire = 0;
void setup() {
  pinMode(BUTTON_PIN, INPUT_PULLUP);
  strip.begin(); // Initialize NeoPixel strip object (REQUIRED)
  strip.show();  // Initialize all pixels to 'off'
}

void loop() {
  check();
  delay(20);
}
void check() {
  boolean newState = digitalRead(BUTTON_PIN);
   if((newState == LOW) && (oldState == HIGH)) {
    if (millis() - lastFire < 200) {
        return;
    }
    lastFire = millis();
    newState = digitalRead(BUTTON_PIN);
    Serial.println("druk");
    if(newState == LOW) { 
      if(++mode > 8) mode = 0;
      switch(mode) {
        case 0:
          colorWipe(strip.Color(  0,   0,   0), 50);    // Black/off
          break;
        case 1:
          colorWipe(strip.Color(255,   0,   0), 50);    // Red
          break;
        case 2:
          colorWipe(strip.Color(  0, 255,   0), 50);    // Green
          break;
        case 3:
          colorWipe(strip.Color(  0,   0, 255), 50);    // Blue
          break;
        case 4:
          theaterChase(strip.Color(127, 127, 127), 50); // White
          break;
        case 5:
          theaterChase(strip.Color(127,   0,   0), 50); // Red
          break;
        case 6:
          theaterChase(strip.Color(  0,   0, 127), 50); // Blue
          break;
        case 7:
          rainbow(10);
          break;
        case 8:
          theaterChaseRainbow(50);
          break;
      }
    }
  }
  oldState = newState;
}
void colorWipe(uint32_t color, int wait) {
  for(int i=0; i<strip.numPixels(); i++) { // For each pixel in strip...
    strip.setPixelColor(i, color);         //  Set pixel's color (in RAM)
    strip.show();                          //  Update strip to match
    check();
    delay(wait);                           //  Pause for a moment
  }
}

void theaterChase(uint32_t color, int wait) {
  for(int a=0; a<10; a++) {  // Repeat 10 times...
    for(int b=0; b<3; b++) { //  'b' counts from 0 to 2...
      strip.clear();         //   Set all pixels in RAM to 0 (off)
      // 'c' counts up from 'b' to end of strip in steps of 3...
      for(int c=b; c<strip.numPixels(); c += 3) {
        strip.setPixelColor(c, color); // Set pixel 'c' to value 'color'
        check();
      }
      strip.show(); // Update strip with new contents
      delay(wait);  // Pause for a moment
    }
  }
}
void rainbow(int wait) {
  for(long firstPixelHue = 0; firstPixelHue < 3*65536; firstPixelHue += 256) {
    for(int i=0; i<strip.numPixels(); i++) { // For each pixel in strip...
      int pixelHue = firstPixelHue + (i * 65536L / strip.numPixels());
      strip.setPixelColor(i, strip.gamma32(strip.ColorHSV(pixelHue)));
      check();
    }
    strip.show(); // Update strip with new contents
    delay(wait);  // Pause for a moment
  }
}

void theaterChaseRainbow(int wait) {
  int firstPixelHue = 0;     // First pixel starts at red (hue 0)
  for(int a=0; a<30; a++) {  // Repeat 30 times...
    for(int b=0; b<3; b++) { //  'b' counts from 0 to 2...
      strip.clear();         //   Set all pixels in RAM to 0 (off)
      // 'c' counts up from 'b' to end of strip in increments of 3...
      for(int c=b; c<strip.numPixels(); c += 3) {
        // hue of pixel 'c' is offset by an amount to make one full
        // revolution of the color wheel (range 65536) along the length
        // of the strip (strip.numPixels() steps):
        int      hue   = firstPixelHue + c * 65536L / strip.numPixels();
        uint32_t color = strip.gamma32(strip.ColorHSV(hue)); // hue -> RGB
        strip.setPixelColor(c, color); // Set pixel 'c' to value 'color'
        check();
      }
      strip.show();                // Update strip with new contents
      delay(wait);                 // Pause for a moment
      firstPixelHue += 65536 / 90; // One cycle of color wheel over 90 frames
    }
  }
}

When I push my button while a for loop is running. It stops, the new called function runs and then the old function contineous.

you should always set oldState to newState if there values differ. You don't when mills() - lastFire < 200

and why do you read the button again.

Ok I put the oldstate = newstate also in the milis() section. And I dont know why the button read bool was in that code. But my problem isnt solved yet.

My problem is, when I push on the button while in the for loop, The other function starts to run, but when this is finiched, the uncomplete loop from the previous function starts to continiou. I don`t want that becaus I want to keep my color.

So when I go for red, I push the button while red is only half of my strip. Green starts to go over my strip. But when green is finiched. I just want it to keep green, but red goes on with his uncomplete loop.

By the way thank you for al your replies.

need to post your updated code

Im sorry. I fixed it, I added a while loop at every color functions so it couldnt go back to different colors.

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
 #include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif
#define BUTTON_PIN   2

#define PIXEL_PIN    3  // Digital IO pin connected to the NeoPixels.

#define PIXEL_COUNT 300  // Number of NeoPixels
Adafruit_NeoPixel strip(PIXEL_COUNT, PIXEL_PIN, NEO_GRB + NEO_KHZ800);

bool oldState = HIGH;
bool oldStatebool = HIGH;
int     mode     = 0;    // Currently-active animation mode, 0-9
unsigned long lastFire = 0;
unsigned long lastFire2 = 0;
void setup() {
  pinMode(BUTTON_PIN, INPUT_PULLUP);
  strip.begin(); // Initialize NeoPixel strip object (REQUIRED)
  strip.show();  // Initialize all pixels to 'off'
}

void loop() {
  check();
  delay(20);
}
void check() {
    bool newState = digitalRead(BUTTON_PIN);
    if((newState == LOW) && (oldState == HIGH)) {
    if (millis() - lastFire < 200) {
        oldState = newState;
        return;
    }
    lastFire = millis();
    newState = digitalRead(BUTTON_PIN);
    if(newState == LOW) { 
      Serial.println("druk");
      if(++mode > 8) mode = 0;
      switch(mode) {
        case 0:
          colorWipe(strip.Color(  0,   0,   0), 50);    // Black/off
          break;
        case 1:
          colorWipe(strip.Color(255,   0,   0), 50);    // Red
          break;
        case 2:
          colorWipe(strip.Color(  0, 255,   0), 50);    // Green
          break;
        case 3:
          colorWipe(strip.Color(  0,   0, 255), 50);    // Blue
          break;
        case 4:
          theaterChase(strip.Color(127, 127, 127), 50); // White
          break;
        case 5:
          theaterChase(strip.Color(127,   0,   0), 50); // Red
          break;
        case 6:
          theaterChase(strip.Color(  0,   0, 127), 50); // Blue
          break;
        case 7:
          rainbow(10);
          break;
        case 8:
          theaterChaseRainbow(50);
          break;
      }
    }
  }
  oldState = newState;
}
void colorWipe(uint32_t color, int wait) {
  while(true) {
    for(int i=0; i<strip.numPixels(); i++) { // For each pixel in strip...
      strip.setPixelColor(i, color);         //  Set pixel's color (in RAM)
      strip.show();                          //  Update strip to match
      check();   
      delay(wait);                           //  Pause for a moment
  }
  }
}

void theaterChase(uint32_t color, int wait) {
  while(true) {
  for(int a=0; a<10; a++) {  // Repeat 10 times...
    for(int b=0; b<3; b++) { //  'b' counts from 0 to 2...
      strip.clear();         //   Set all pixels in RAM to 0 (off)
      // 'c' counts up from 'b' to end of strip in steps of 3...
      for(int c=b; c<strip.numPixels(); c += 3) {
        strip.setPixelColor(c, color); // Set pixel 'c' to value 'color'
        check();
      }
      strip.show(); // Update strip with new contents
      delay(wait);  // Pause for a moment
    }
  }
  }
}
void rainbow(int wait) {
  while(true) {
  for(long firstPixelHue = 0; firstPixelHue < 3*65536; firstPixelHue += 256) {
    for(int i=0; i<strip.numPixels(); i++) { // For each pixel in strip...
      int pixelHue = firstPixelHue + (i * 65536L / strip.numPixels());
      strip.setPixelColor(i, strip.gamma32(strip.ColorHSV(pixelHue)));
      check();
    }
    strip.show(); // Update strip with new contents
    delay(wait);  // Pause for a moment
  }
  }
}

void theaterChaseRainbow(int wait) {
  while(true) {
  int firstPixelHue = 0;     // First pixel starts at red (hue 0)
  for(int a=0; a<30; a++) {  // Repeat 30 times...
    for(int b=0; b<3; b++) { //  'b' counts from 0 to 2...
      strip.clear();         //   Set all pixels in RAM to 0 (off)
      // 'c' counts up from 'b' to end of strip in increments of 3...
      for(int c=b; c<strip.numPixels(); c += 3) {
        // hue of pixel 'c' is offset by an amount to make one full
        // revolution of the color wheel (range 65536) along the length
        // of the strip (strip.numPixels() steps):
        int      hue   = firstPixelHue + c * 65536L / strip.numPixels();
        uint32_t color = strip.gamma32(strip.ColorHSV(hue)); // hue -> RGB
        strip.setPixelColor(c, color); // Set pixel 'c' to value 'color'
        check();
      }
      strip.show();                // Update strip with new contents
      delay(wait);                 // Pause for a moment
      firstPixelHue += 65536 / 90; // One cycle of color wheel over 90 frames
    }
  }
  }
}

Thanks for the replies.