LED strip animation change

Hi,
When I press my button to change my LED strips animation from ‘rainbow’ to ‘drip’, it clears the strip then plays the first of the next animation, which it’s meant to do, but then it goes back to play out the rest of ‘rainbow’. I’ve tried debugging it using the ‘if (mode != 0)’ in the for loops of ‘rainbow’ but I still can’t get it to change over without it playing out the rest of rainbow. Once it has finished the rainbow animation the drip animation works without issue.

I assume that there something in how the code runs that I don’t understand?
Can someone please help?

#include <Adafruit_NeoPixel.h>
#include <EEPROM.h>
#define LED_PIN0 5
#define LED_PIN1 6
#define LED_PIN2 7
#define LED_PIN3 8
int LED_COUNT = 20;
#define LED_SELECT 0
int address = 0;

//BUTTON
const int Button = 2;
int ButtonActive = LOW;
int ButtonHold;
int ButtonLong = 0;
int ButtonShort = 0;
unsigned long ButtonPreviousMillis = 0;
int ButtonHoldInterval = 1000;
unsigned long currentMillis;

unsigned long previousMillis = 0;
const long interval = 500;
boolean pressed;

Adafruit_NeoPixel strip[] = {
  Adafruit_NeoPixel(LED_COUNT, LED_PIN0),
  Adafruit_NeoPixel(LED_COUNT, LED_PIN1),
  Adafruit_NeoPixel(LED_COUNT, LED_PIN2),
  Adafruit_NeoPixel(LED_COUNT, LED_PIN3),
};

size_t numStrips = sizeof(strip) / sizeof(Adafruit_NeoPixel);

int mode = EEPROM.read(address);

void setup() {
  Serial.begin(9600);
  pinMode(Button, INPUT_PULLUP);

  for (uint8_t a = 0; a < numStrips; a++) {
    strip[a].begin();
    strip[a].clear();
    strip[a].setBrightness(20);
    strip[a].show();
  }

  attachInterrupt(digitalPinToInterrupt(Button), ButtonControl, LOW);

  mode = 0;  //to be able to override EEPROM
}

void loop() {
  Serial.print("The mode is ");
  Serial.println(mode);
  switch (mode) {
    case 0:
      rainbow(10);
      break;
    case 1:
      drip(random(200, 1000));
      break;
    case 2:
      raindrops(250);
      break;
  }
}

void rainbow(int wait) {
  //if (mode != 0) return;
  for (long firstPixelHue = 0; firstPixelHue < 1 * 65536; firstPixelHue += 256) {
      if (mode != 0) {
        Serial.println("trying1");
        break;
        }
    for (int i = 0; i < LED_COUNT; i++) {
        if (mode != 0) {
          Serial.println("trying2");
          break;
          }
      int pixelHue = firstPixelHue + (i * 65536L / LED_COUNT);
      strip[0].setPixelColor(i, strip[0].gamma32(strip[0].ColorHSV(pixelHue)));
      strip[1].setPixelColor(i, strip[1].gamma32(strip[1].ColorHSV(pixelHue)));
      strip[2].setPixelColor(i, strip[2].gamma32(strip[2].ColorHSV(pixelHue)));
      strip[3].setPixelColor(i, strip[3].gamma32(strip[3].ColorHSV(pixelHue)));
    }
    strip[0].show();
    strip[1].show();
    strip[2].show();
    strip[3].show();

    delay(wait);
  }
}

void drip(int freq) {
  uint32_t color = strip[0].Color(110, 110, 255);
  int wait = 500;
  int mode = random(0, 4);
  int maxspeed = 20;

  switch (mode) {
    case 0:
      for (int i = LED_COUNT; i >= 0; i--) {
        //ButtonControl();
        int accel = pow(2, i);
        strip[0].setPixelColor(i, color);
        strip[0].show();
        strip[0].clear();
        delay(wait);
        wait = (max(wait - sqrt(wait), maxspeed)) / 1.8;
      }
      break;
    case 1:
      for (int i = LED_COUNT; i >= 0; i--) {
        //ButtonControl();
        int accel = pow(2, i);
        strip[1].setPixelColor(i, color);
        strip[1].show();
        strip[1].clear();
        delay(wait);
        wait = (max(wait - sqrt(wait), maxspeed)) / 1.8;
      }
      break;
    case 2:
      for (int i = LED_COUNT; i >= 0; i--) {
        //ButtonControl();
        int accel = pow(2, i);
        strip[2].setPixelColor(i, color);
        strip[2].show();
        strip[2].clear();
        delay(wait);
        wait = (max(wait - sqrt(wait), maxspeed)) / 1.8;
      }
      break;
    case 3:
      for (int i = LED_COUNT; i >= 0; i--) {
        //ButtonControl();
        int accel = pow(2, i);
        strip[3].setPixelColor(i, color);
        strip[3].show();
        strip[3].clear();
        delay(wait);
        wait = (max(wait - sqrt(wait), maxspeed)) / 1.8;
      }
      break;
  }
  strip[0].clear();
  strip[0].show();
  strip[1].clear();
  strip[1].show();
  strip[2].clear();
  strip[2].show();
  strip[3].clear();
  strip[3].show();
  delay(freq);
}

void raindrops(int wait) {
  uint32_t color = strip[0].Color(150, 150, 255);
  int brightness = 20;
  strip[0].setBrightness(brightness);
  strip[1].setBrightness(brightness);
  strip[2].setBrightness(brightness);
  strip[3].setBrightness(brightness);
  int qty = LED_COUNT / 5;
  int array0[qty];
  int array1[qty];
  int array2[qty];
  int array3[qty];

  for (int i = 0; i < qty; i++) {
    //ButtonControl();
    int a = random(0, LED_COUNT);
    int b = random(0, LED_COUNT);
    int c = random(0, LED_COUNT);
    int d = random(0, LED_COUNT);
    strip[0].setPixelColor(a, color);
    strip[0].show();
    strip[0].setPixelColor(array0[i], (255, 0, 0));
    strip[0].show();
    array0[i] = a;
    strip[1].setPixelColor(b, color);
    strip[1].show();
    strip[1].setPixelColor(array1[i], (255, 0, 0));
    strip[1].show();
    array1[i] = b;
    strip[2].setPixelColor(c, color);
    strip[2].show();
    strip[2].setPixelColor(array2[i], (255, 0, 0));
    strip[2].show();
    array2[i] = c;
    strip[3].setPixelColor(d, color);
    strip[3].show();
    strip[3].setPixelColor(array3[i], (255, 0, 0));
    strip[3].show();
    array3[i] = d;
    delay(wait);
  }
}

void ButtonControl() {
  unsigned long currentMillis = millis();
  if (digitalRead(Button) == LOW && ButtonActive == 0) {
    ButtonActive = 1;
    ButtonPreviousMillis = currentMillis;
    ButtonShort = 1;
    ButtonLong = 0;
  }
  //else{return;}
  if (currentMillis - ButtonPreviousMillis >= ButtonHoldInterval && ButtonActive == 1) {
    ButtonPreviousMillis = currentMillis;
    ButtonLong = 1;
    ButtonShort = 0;
  }
  while (digitalRead(Button) == LOW) {
    //Serial.println("Holding");
    delay(500);

    if (digitalRead(Button) == HIGH) {
      Serial.println("Released");
      //break;
    }
    //return;
  }

  if (digitalRead(Button) == HIGH) {
    ButtonActive = 0;
    if (ButtonShort == 1) {
      //Short button press
      Serial.println("short press");
      ButtonLong = 0;
      ButtonShort = 0;
      if (++mode > 2) mode = 0;
      Serial.println(mode);
      strip[0].clear();
      strip[1].clear();
      strip[2].clear();
      strip[3].clear();
      strip[0].show();
      strip[1].show();
      strip[2].show();
      strip[3].show();
      delay(1000);

      EEPROM.update(address, mode);
      loop();
      //Serial.println(mode);
      //delay(200);
    } else if (ButtonLong == 1) {
      //Long button press
      Serial.println("Long press");
    }
  }
}

You need to declare all of the variables updated in the ISR as volatile to clue the compiler in to the fact that they could change at any time and therefore to deal with them appropriately

For instance, when entering the ISR the compiler may well push a variable onto the stack, it is changed in the ISR, then on exit from the ISR the original value is popped off the stack

This instruction is executed before the hardware has been initialized and is thus not reliable. Read settings stored in EEPROM in the setup() method.

Thanks Bob,
I now understand how to use the volatile variable. Unfortunately that hasn’t seemed to have worked. I changed all variables in ButtonControl() and mode to volatile and it hasn’t worked.

Thanks Danois,
I removed the EEPROM and declared the variable without it and I still have the issue. If I reinstate it I will implement the read inside the loop instead.

Do you know any other potential reasons that could cause this?

Please post you code as it is now

Here is the latest. I’ve included all the animations this time as I removed them prior to shorten it down a bit. It has the same issue for the other animations. I’ve managed to get the ‘if (mode != 0)’ working to bypass the extra pass for the first few animations but that is only a workaround not a solution.
Thanks again for your help.

#include <Adafruit_NeoPixel.h>
//#include <EEPROM.h>
#define LED_PIN0 5
#define LED_PIN1 6
#define LED_PIN2 7
#define LED_PIN3 8
int LED_COUNT = 20;
#define LED_SELECT 0
int address = 0;

//BUTTON
const int Button = 2;
int volatile ButtonActive = LOW;
int volatile ButtonHold;
int volatile ButtonLong = 0;
int volatile ButtonShort = 0;
unsigned long volatile ButtonPreviousMillis = 0;
const int ButtonHoldInterval = 1000;
unsigned long volatile currentMillis;

unsigned long previousMillis = 0;
const long interval = 500;

int singlestrip = 0;

//Adafruit_NeoPixel strip1(LED_COUNT, LED_PIN3, NEO_GRB + NEO_KHZ800);

Adafruit_NeoPixel strip[] = {
  Adafruit_NeoPixel(LED_COUNT, LED_PIN0),
  Adafruit_NeoPixel(LED_COUNT, LED_PIN1),
  Adafruit_NeoPixel(LED_COUNT, LED_PIN2),
  Adafruit_NeoPixel(LED_COUNT, LED_PIN3),
};

size_t numStrips = sizeof(strip) / sizeof(Adafruit_NeoPixel);

int volatile mode;

void setup() {
  Serial.begin(9600);
  pinMode(Button, INPUT_PULLUP);

  for (uint8_t a = 0; a < numStrips; a++) {
    strip[a].begin();
    strip[a].clear();
    strip[a].setBrightness(20);
    strip[a].show();
  }

  attachInterrupt(digitalPinToInterrupt(Button), ButtonControl, LOW);
  //mode = EEPROM.read(address);
  mode = 0;  //to be able to override EEPROM
}

void loop() {
  //Serial.print("The mode is ");
  //Serial.println(mode);
  switch (mode) {
    case 0:
      rainbow(10);
      break;
    case 1:
      drip(random(200, 1000));
      //dripTogether(random(200, 1000));
      break;
    case 2:
      raindrops(250);
      break;
    case 3:
      lightning(random(10, 2000));
      break;
    case 4:
      snake(50);
      break;
    case 5:
      breathebright(17);
      break;
    case 6:
      breathesat(17);
      break;
    case 7:
      theaterChaseRainbow(100);
      break;
    case 8:
      theaterChase(strip[0].Color(127, 127, 127), 150);  // White, half brightness
      theaterChase(strip[0].Color(127, 0, 0), 150);      // Red, half brightness
      theaterChase(strip[0].Color(0, 0, 127), 150);      // Blue, half brightness
      break;
    case 9:
      colorWipe(strip[0].Color(255, 0, 0), 50);  // Red
      colorWipe(strip[0].Color(0, 255, 0), 50);  // Green
      colorWipe(strip[0].Color(0, 0, 255), 50);  // Blue
      break;
    case 10:
      rainbowrange(10);
      break;
  }
}

void rainbow(int wait) {
  for (long firstPixelHue = 0; firstPixelHue < 1 * 65536; firstPixelHue += 256) {
    if (mode != 0) {
      Serial.println("trying0");
      break;
    }
    for (int i = 0; i < LED_COUNT; i++) {
      int pixelHue = firstPixelHue + (i * 65536L / LED_COUNT);
      strip[0].setPixelColor(i, strip[0].gamma32(strip[0].ColorHSV(pixelHue)));
      strip[1].setPixelColor(i, strip[1].gamma32(strip[1].ColorHSV(pixelHue)));
      strip[2].setPixelColor(i, strip[2].gamma32(strip[2].ColorHSV(pixelHue)));
      strip[3].setPixelColor(i, strip[3].gamma32(strip[3].ColorHSV(pixelHue)));
    }
    strip[0].show();
    strip[1].show();
    strip[2].show();
    strip[3].show();

    delay(wait);
  }
}

void drip(int freq) {
  uint32_t color = strip[0].Color(110, 110, 255);
  int wait = 500;
  int dripmode = random(0, 4);
  int maxspeed = 20;
    if (mode != 1) {
      Serial.println("trying1");
      return;
    }
  switch (dripmode) {
    case 0:
      for (int i = LED_COUNT; i >= 0; i--) {
        //ButtonControl();
        int accel = pow(2, i);
        strip[0].setPixelColor(i, color);
        strip[0].show();
        strip[0].clear();
        delay(wait);
        wait = (max(wait - sqrt(wait), maxspeed)) / 1.8;
      }
      break;
    case 1:
      for (int i = LED_COUNT; i >= 0; i--) {
        //ButtonControl();
        int accel = pow(2, i);
        strip[1].setPixelColor(i, color);
        strip[1].show();
        strip[1].clear();
        delay(wait);
        wait = (max(wait - sqrt(wait), maxspeed)) / 1.8;
      }
      break;
    case 2:
      for (int i = LED_COUNT; i >= 0; i--) {
        //ButtonControl();
        int accel = pow(2, i);
        strip[2].setPixelColor(i, color);
        strip[2].show();
        strip[2].clear();
        delay(wait);
        wait = (max(wait - sqrt(wait), maxspeed)) / 1.8;
      }
      break;
    case 3:
      for (int i = LED_COUNT; i >= 0; i--) {
        //ButtonControl();
        int accel = pow(2, i);
        strip[3].setPixelColor(i, color);
        strip[3].show();
        strip[3].clear();
        delay(wait);
        wait = (max(wait - sqrt(wait), maxspeed)) / 1.8;
      }
      break;
  }
  strip[0].clear();
  strip[0].show();
  strip[1].clear();
  strip[1].show();
  strip[2].clear();
  strip[2].show();
  strip[3].clear();
  strip[3].show();
  delay(freq);
}

void dripTogether(int freq) {
  uint32_t color = strip[0].Color(110, 110, 255);
  int b = 500;
  int wait = b;
  for (int i = LED_COUNT; i >= 0; i--) {
    //ButtonControl();
    int accel = pow(2, i);
    strip[0].setPixelColor(i, color);
    strip[0].show();
    strip[0].clear();
    strip[1].setPixelColor(i, color);
    strip[1].show();
    strip[1].clear();
    strip[2].setPixelColor(i, color);
    strip[2].show();
    strip[2].clear();
    strip[3].setPixelColor(i, color);
    strip[3].show();
    strip[3].clear();
    delay(wait);
    wait = (max(wait - sqrt(b), 6)) / 1.8;
    b = wait;
  }
  strip[0].clear();
  strip[0].show();
  strip[1].clear();
  strip[1].show();
  strip[2].clear();
  strip[2].show();
  strip[3].clear();
  strip[3].show();
  delay(freq);
}

void raindrops(int wait) {
  uint32_t color = strip[0].Color(150, 150, 255);
  int brightness = 20;
  strip[0].setBrightness(brightness);
  strip[1].setBrightness(brightness);
  strip[2].setBrightness(brightness);
  strip[3].setBrightness(brightness);
  int qty = LED_COUNT / 5;
  int array0[qty];
  int array1[qty];
  int array2[qty];
  int array3[qty];

  for (int i = 0; i < qty; i++) {
        if (mode != 2) {
      Serial.println("trying2");
      break;
        }
    //ButtonControl();
    int a = random(0, LED_COUNT);
    int b = random(0, LED_COUNT);
    int c = random(0, LED_COUNT);
    int d = random(0, LED_COUNT);
    strip[0].setPixelColor(a, color);
    strip[0].show();
    strip[0].setPixelColor(array0[i], (255, 0, 0));
    strip[0].show();
    array0[i] = a;
    strip[1].setPixelColor(b, color);
    strip[1].show();
    strip[1].setPixelColor(array1[i], (255, 0, 0));
    strip[1].show();
    array1[i] = b;
    strip[2].setPixelColor(c, color);
    strip[2].show();
    strip[2].setPixelColor(array2[i], (255, 0, 0));
    strip[2].show();
    array2[i] = c;
    strip[3].setPixelColor(d, color);
    strip[3].show();
    strip[3].setPixelColor(array3[i], (255, 0, 0));
    strip[3].show();
    array3[i] = d;
    delay(wait);
  }
}

void lightning(int freq) {
  int lightmode = random(0, 4);
  int brightness = 255;  //0-255 brightness scale
  uint32_t color = strip[0].Color(brightness, brightness, brightness);
  //ButtonControl();
  switch (lightmode) {
    case 0:
      for (int i = LED_COUNT; i >= 0; i--) {
        //ButtonControl();
        strip[0].setPixelColor(i, color);
        strip[0].show();
      }
      strip[0].clear();
      strip[0].show();
      break;
    case 1:
      for (int i = LED_COUNT; i >= 0; i--) {
        //ButtonControl();
        strip[1].setPixelColor(i, color);
        strip[1].show();
      }
      strip[1].clear();
      strip[1].show();
      break;
    case 2:
      for (int i = LED_COUNT; i >= 0; i--) {
        //ButtonControl();
        strip[2].setPixelColor(i, color);
        strip[2].show();
      }
      strip[2].clear();
      strip[2].show();
      break;
    case 3:
      for (int i = LED_COUNT; i >= 0; i--) {
        //ButtonControl();
        strip[3].setPixelColor(i, color);
        strip[3].show();
      }
      strip[3].clear();
      strip[3].show();
      break;
  }
  delay(freq);
}

void snake(int speed) {
  //go down one strip then up the next
  snakedirection(speed, 5, 0, 0);
  snakedirection(speed, 7, 1, 1);
  snakedirection(speed, 9, 0, 2);
  snakedirection(speed, 11, 1, 3);
  snakedirection(speed, 13, 0, 2);
  snakedirection(speed, 15, 1, 1);
  snakedirection(speed, 17, 0, 0);
  snakedirection(speed, 19, 1, 1);
  snakedirection(speed, 21, 0, 2);
  snakedirection(speed, 23, 1, 3);
  snakedirection(speed, 25, 0, 2);
  snakedirection(speed, 27, 1, 1);
  snakedirection(speed, 25, 0, 0);
  snakedirection(speed, 23, 1, 1);
  snakedirection(speed, 21, 0, 2);
  snakedirection(speed, 19, 1, 3);
  snakedirection(speed, 17, 0, 2);
  snakedirection(speed, 15, 1, 1);
  snakedirection(speed, 13, 0, 0);
  snakedirection(speed, 11, 1, 1);
  snakedirection(speed, 9, 0, 2);
  snakedirection(speed, 7, 1, 3);
  snakedirection(speed, 5, 0, 2);
  snakedirection(speed, 3, 1, 1);
}

void snakedirection(int wait, int qty, int stripdirection, int stripno) {
  uint32_t color = strip[stripno].Color(0, 255, 20);
  //int qty = 10;
  switch (stripdirection) {
    case 0:
      for (int i = LED_COUNT; i >= 0; i--) {
        //ButtonControl();
        int a = i + 1;
        strip[stripno].setPixelColor(i, color);
        strip[stripno].show();
        strip[stripno].setPixelColor(i + qty, (255, 0, 0));
        strip[stripno].show();
        if (i == 0) {
          for (int a = qty; a >= -1; a--) {
            strip[stripno].setPixelColor(a, (255, 0, 0));
            strip[stripno].show();
            delay(wait);
          }
        }
        delay(wait);
      }
      break;
    case 1:
      for (int i = 0; i <= LED_COUNT; i++) {
        //ButtonControl();
        int a = i + 1;
        strip[stripno].setPixelColor(i, color);
        strip[stripno].show();
        strip[stripno].setPixelColor(i - qty, (255, 0, 0));
        strip[stripno].show();
        if (i == LED_COUNT) {
          for (int a = LED_COUNT - qty; a <= LED_COUNT + 1; a++) {
            strip[stripno].setPixelColor(a, (255, 0, 0));
            strip[stripno].show();
            delay(wait);
          }
        }
        delay(wait);
      }
      break;
  }
}

void breathebright(int wait) {
  int color = 45000;
  for (long fade = 100; fade < 255; fade += 1) {
    for (int i = 0; i < 100; i++) {
      //ButtonControl();
      strip[0].setPixelColor(i, strip[0].gamma32(strip[0].ColorHSV(color, 150, fade)));
      strip[1].setPixelColor(i, strip[1].gamma32(strip[1].ColorHSV(color, 150, fade)));
      strip[2].setPixelColor(i, strip[2].gamma32(strip[2].ColorHSV(color, 150, fade)));
      strip[3].setPixelColor(i, strip[3].gamma32(strip[3].ColorHSV(color, 150, fade)));
    }
    strip[0].show();
    strip[1].show();
    strip[2].show();
    strip[3].show();
    delay(wait);
  }
  for (long fade = 255; fade > 100; fade -= 1) {
    for (int i = 100; i >= 0; i--) {
      //ButtonControl();
      strip[0].setPixelColor(i, strip[0].gamma32(strip[0].ColorHSV(color, 150, fade)));
      strip[1].setPixelColor(i, strip[1].gamma32(strip[1].ColorHSV(color, 150, fade)));
      strip[2].setPixelColor(i, strip[2].gamma32(strip[2].ColorHSV(color, 150, fade)));
      strip[3].setPixelColor(i, strip[3].gamma32(strip[3].ColorHSV(color, 150, fade)));
    }
    strip[0].show();
    strip[1].show();
    strip[2].show();
    strip[3].show();
    delay(wait);
  }
}

void breathesat(int wait) {
  int color = 45000;
  for (long fade = 0; fade < 255; fade += 2) {
    for (int i = 0; i < 100; i++) {
      //ButtonControl();
      strip[0].setPixelColor(i, strip[0].gamma32(strip[0].ColorHSV(color, fade, 150)));
      strip[1].setPixelColor(i, strip[1].gamma32(strip[1].ColorHSV(color, fade, 150)));
      strip[2].setPixelColor(i, strip[2].gamma32(strip[2].ColorHSV(color, fade, 150)));
      strip[3].setPixelColor(i, strip[3].gamma32(strip[3].ColorHSV(color, fade, 150)));
    }
    strip[0].show();
    strip[1].show();
    strip[2].show();
    strip[3].show();
    delay(wait);
  }
  for (long fade = 255; fade > 0; fade -= 2) {
    for (int i = 100; i >= 0; i--) {
      //ButtonControl();
      strip[0].setPixelColor(i, strip[0].gamma32(strip[0].ColorHSV(color, fade, 150)));
      strip[1].setPixelColor(i, strip[1].gamma32(strip[1].ColorHSV(color, fade, 150)));
      strip[2].setPixelColor(i, strip[2].gamma32(strip[2].ColorHSV(color, fade, 150)));
      strip[3].setPixelColor(i, strip[3].gamma32(strip[3].ColorHSV(color, fade, 150)));
    }
    strip[0].show();
    strip[1].show();
    strip[2].show();
    strip[3].show();
    delay(wait);
  }
}

void theaterChaseRainbow(int wait) {
  int firstPixelHue = 0;
  for (int a = 0; a < 30; a++) {
    for (int b = 0; b < 4; b++) {
      strip[0].clear();
      strip[1].clear();
      strip[2].clear();
      strip[3].clear();
      for (int c = b; c < LED_COUNT; c += 4) {
        //ButtonControl();
        int hue = firstPixelHue + c * 65536L / LED_COUNT;
        uint32_t color = strip[0].gamma32(strip[0].ColorHSV(hue));
        strip[0].setPixelColor(c, color);
        strip[1].setPixelColor(c, color);
        strip[2].setPixelColor(c, color);
        strip[3].setPixelColor(c, color);
      }
      strip[0].show();
      strip[1].show();
      strip[2].show();
      strip[3].show();
      delay(wait);
      firstPixelHue += 65536 / 90;
    }
  }
}

void theaterChase(uint32_t color, int wait) {
  for (int a = 0; a < 10; a++) {
    for (int b = 0; b < 3; b++) {
      strip[0].clear();
      strip[1].clear();
      strip[2].clear();
      strip[3].clear();
      for (int c = b; c < LED_COUNT; c += 3) {
        //ButtonControl();
        strip[0].setPixelColor(c, color);
        strip[1].setPixelColor(c, color);
        strip[2].setPixelColor(c, color);
        strip[3].setPixelColor(c, color);
      }
      strip[0].show();
      strip[1].show();
      strip[2].show();
      strip[3].show();
      delay(wait);
    }
  }
}

void colorWipe(uint32_t color, int wait) {
  for (int i = 0; i < LED_COUNT; i++) {
    strip[0].setPixelColor(i, color);
    strip[0].show();
    strip[1].setPixelColor(i, color);
    strip[1].show();
    strip[2].setPixelColor(i, color);
    strip[2].show();
    strip[3].setPixelColor(i, color);
    strip[3].show();
    //ButtonControl();
    delay(wait);
  }
}

void rainbowrange(int wait) {
  for (long firstPixelHue = 15000; firstPixelHue < 25000; firstPixelHue += 156) {
    for (int i = 0; i < LED_COUNT; i++) {
      //ButtonControl();
      int pixelHue = firstPixelHue + (i * 25000L / LED_COUNT);
      strip[0].setPixelColor(i, strip[0].gamma32(strip[0].ColorHSV(pixelHue)));
      strip[1].setPixelColor(i, strip[1].gamma32(strip[1].ColorHSV(pixelHue)));
      strip[2].setPixelColor(i, strip[2].gamma32(strip[2].ColorHSV(pixelHue)));
      strip[3].setPixelColor(i, strip[3].gamma32(strip[3].ColorHSV(pixelHue)));
    }
    strip[0].show();
    strip[1].show();
    strip[2].show();
    strip[3].show();
    delay(wait);
  }
  for (long firstPixelHue = 25000; firstPixelHue > 15000; firstPixelHue -= 156) {
    for (int i = LED_COUNT; i >= 0; i--) {
      //ButtonControl();
      int pixelHue = firstPixelHue + (i * 25000L / LED_COUNT);
      strip[0].setPixelColor(i, strip[0].gamma32(strip[0].ColorHSV(pixelHue)));
      strip[1].setPixelColor(i, strip[1].gamma32(strip[1].ColorHSV(pixelHue)));
      strip[2].setPixelColor(i, strip[2].gamma32(strip[2].ColorHSV(pixelHue)));
      strip[3].setPixelColor(i, strip[3].gamma32(strip[3].ColorHSV(pixelHue)));
    }
    strip[0].show();
    strip[1].show();
    strip[2].show();
    strip[3].show();
    delay(wait);
  }
}

void ButtonControl() {
  unsigned long volatile currentMillis = millis();
  if (digitalRead(Button) == LOW && ButtonActive == 0) {
    ButtonActive = 1;
    ButtonPreviousMillis = currentMillis;
    ButtonShort = 1;
    ButtonLong = 0;
  }
  //else{return;}
  if (currentMillis - ButtonPreviousMillis >= ButtonHoldInterval && ButtonActive == 1) {
    ButtonPreviousMillis = currentMillis;
    ButtonLong = 1;
    ButtonShort = 0;
  }
  while (digitalRead(Button) == LOW) {
    //Serial.println("Holding");
    delay(500);

    if (digitalRead(Button) == HIGH) {
      Serial.println("Released");
      //break;
    }
    //return;
  }

  if (digitalRead(Button) == HIGH) {
    ButtonActive = 0;
    if (ButtonShort == 1) {
      //Short button press
      Serial.println("short press");
      ButtonLong = 0;
      ButtonShort = 0;
      if (++mode > 10) mode = 0;
      Serial.println(mode);
      strip[0].clear();
      strip[1].clear();
      strip[2].clear();
      strip[3].clear();
      strip[0].show();
      strip[1].show();
      strip[2].show();
      strip[3].show();
      delay(1000);

      //EEPROM.update(address, mode);
      loop();
      //Serial.println(mode);
      //delay(200);
    } else if (ButtonLong == 1) {
      //Long button press
      Serial.println("Long press");
    }
  }
}

The solution is that your code needs to be completely restructured to use non-blocking techniques. This happens frequently when folks first start out (especially when copying Adafruit’s NeoPixel examples). They paint themselves in a blocking-code corner and then try to use interrupts to bail themselves out.

The animations need to broke up so that only a little piece is done on each iteration through the loop() function. Then, millis()-based timing along with reading the button’s state is used to determine what (if anything) is to be done on each pass. This way, loop() exits very quickly and is repeated called by the (hidden) main() function. Thus, the button is checked frequently, allowing the code to change modes and/or make the next step in the current animation as required.

Here is an example of how you could write the rainbow() function to make it non-blocking… You would call it every time through loop() as fast as you want and it will only update as needed. If all your “pattern” functions behaved similarly, you could just check your button at the start of loop() and get rid of interrupts.

This function does one hue, takes note of when it did the update and then returns

// example of a non-blocking rainbow function
void rainbow(int wait) {
  static long firstPixelHue;
  static unsigned long lastTime;

  if ( firstPixelHue >= 1 * 65536UL ) {
    // end of loop, reset
    firstPixelHue = 0;
  }
  if ( millis() - lastTime >= wait ) {
    // time to update the rainbow
    for (int i = 0; i < LED_COUNT; i++) {
      int pixelHue = firstPixelHue + (i * 65536L / LED_COUNT);
      strip[0].setPixelColor(i, strip[0].gamma32(strip[0].ColorHSV(pixelHue)));
      strip[1].setPixelColor(i, strip[1].gamma32(strip[1].ColorHSV(pixelHue)));
      strip[2].setPixelColor(i, strip[2].gamma32(strip[2].ColorHSV(pixelHue)));
      strip[3].setPixelColor(i, strip[3].gamma32(strip[3].ColorHSV(pixelHue)));
    }
    strip[0].show();
    strip[1].show();
    strip[2].show();
    strip[3].show();

    firstPixelHue += 256; // prepare for next time
    lastTime = millis();
  }
}