Help with interrupt

I’ve been tinkering with a dragon skeleton that my wife bought me. The idea is to light it up with WS2812b LEDs with a push button that will trigger a mouth movement using a servo. I of course want to have the mouth start moving as soon as the button is pushed so I’m attempting to use an interrupt. It works great without the LED code but as soon as I run it with the LED code it’s like it’s in and out of the routine that is called. I’ve attached two videos. One with the LED code and the other without. Any thoughts on why it would be have this way?

Dragon code with LEDs

#include <FastLED.h>
#include <Servo.h>

#define INTERUPT_PIN    2
#define LED_PIN         3
#define EYES_LED_PIN    4
#define MOUTH_PIN       5
#define NUM_LEDS        22

//#define BRIGHTNESS      32
#define LED_TYPE    WS2812B
#define COLOR_ORDER GRB

int startMillis;
int currentMillis;
int countMillis;
int dly = 10;
int BRIGHTNESS;

bool runHead = false;

volatile int interuptState = 0;

CRGB leds[NUM_LEDS];
CRGB eyes[2];
Servo myservo;

void setup() {
  attachInterrupt(digitalPinToInterrupt(INTERUPT_PIN), pin_ISR, RISING);
  FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection( TypicalLEDStrip );
  FastLED.addLeds<LED_TYPE, EYES_LED_PIN, COLOR_ORDER>(eyes, 2).setCorrection( TypicalLEDStrip );
  FastLED.setBrightness(BRIGHTNESS);
  Serial.begin(9600);
}

void loop() {
  Serial.println(runHead);
  if (runHead == true) {
    Head();
  }

  if (runHead == false) {
    BRIGHTNESS = 32;
    FastLED.setBrightness(BRIGHTNESS);
    for (int i = 0; i < 4; i++) {
      Serial.println(runHead);
      if (i == 0) {
        for (int x = 0; x < 5; x++) {
          Orange_Single();
        }
      }

      BRIGHTNESS = 32;
      FastLED.setBrightness(BRIGHTNESS);
      if (i == 1) {
        for (int x = 0; x < 100; x++) {
          All_Orange_Fliker();
        }
      }

      BRIGHTNESS = 32;
      FastLED.setBrightness(BRIGHTNESS);
      if (i == 2) {
        for (int x = 0; x < 3; x++) {
          Oragne_Fade();
        }
      }

      BRIGHTNESS = 96;
      FastLED.setBrightness(BRIGHTNESS);
      if (i == 3) {
        for (int x = 0; x < 5; x++) {
          Hue();
        }
      }
    }
  }
}


void All_Orange_Fliker() {
  eyes[0].setRGB(255, 128, 0);
  eyes[1].setRGB(255, 128, 0);
  FastLED.show();
  for (int i = 0; i < NUM_LEDS; i++) {
    Serial.println(runHead);
    leds[i].setRGB(255, 128, 0);
    leds[i + 1].setRGB(128, 0, 0);
    delay(10);
    FastLED.show();
  }
}

void Oragne_Fade() {
  eyes[0].setRGB(255, 128, 0);
  eyes[1].setRGB(255, 128, 0);

  for (int i = 0; i < BRIGHTNESS; i++) {
    Serial.println(runHead);
    FastLED.setBrightness(i);
    fill_solid(leds, NUM_LEDS, CRGB(255, 128, 0));
    FastLED.show();
    delay(50);
  }

  for (int i = BRIGHTNESS; i > 0; i--) {
    Serial.println(runHead);
    FastLED.setBrightness(i);
    fill_solid(leds, NUM_LEDS, CRGB(255, 128, 0));
    FastLED.show();
    delay(50);
  }
  FastLED.setBrightness(BRIGHTNESS);
}

void Orange_Single() {
  eyes[0].setRGB(255, 128, 0);
  eyes[1].setRGB(255, 128, 0);

  for (int i = 0; i < 8; i++) {
    Serial.println(runHead);
    leds[i].setRGB(255, 128, 0);
    leds[i - 1].setRGB(0, 0, 0);
    FastLED.show();
    delay(100);
  }

  //wings row 1
  leds[7].setRGB(0, 0, 0);
  leds[8].setRGB(255, 128, 0);
  leds[12].setRGB(255, 128, 0);
  leds[15].setRGB(255, 128, 0);
  leds[18].setRGB(255, 128, 0);
  leds[21].setRGB(255, 128, 0);
  FastLED.show();
  delay(100);

  leds[8].setRGB(0, 0, 0);
  leds[12].setRGB(0, 0, 0);
  leds[15].setRGB(0, 0, 0);
  leds[18].setRGB(0, 0, 0);
  leds[21].setRGB(0, 0, 0);
  FastLED.show();
  delay(100);

  //wings row 2
  leds[11].setRGB(255, 128, 0);
  leds[14].setRGB(255, 128, 0);
  leds[17].setRGB(255, 128, 0);
  leds[20].setRGB(255, 128, 0);
  FastLED.show();
  delay(100);

  leds[11].setRGB(0, 0, 0);
  leds[14].setRGB(0, 0, 0);
  leds[17].setRGB(0, 0, 0);
  leds[20].setRGB(0, 0, 0);
  FastLED.show();
  delay(100);

  //wings row 3
  leds[10].setRGB(255, 128, 0);
  leds[13].setRGB(255, 128, 0);
  leds[16].setRGB(255, 128, 0);
  leds[19].setRGB(255, 128, 0);
  FastLED.show();
  delay(100);

  leds[10].setRGB(0, 0, 0);
  leds[13].setRGB(0, 0, 0);
  leds[16].setRGB(0, 0, 0);
  leds[19].setRGB(0, 0, 0);
  FastLED.show();
  delay(100);

  //wings row 4
  leds[9].setRGB(255, 128, 0);
  FastLED.show();
  delay(100);

  leds[9].setRGB(0, 0, 0);
  FastLED.show();
  delay(100);

  //wings row 3
  leds[10].setRGB(255, 128, 0);
  leds[13].setRGB(255, 128, 0);
  leds[16].setRGB(255, 128, 0);
  leds[19].setRGB(255, 128, 0);
  FastLED.show();
  delay(100);

  leds[10].setRGB(0, 0, 0);
  leds[13].setRGB(0, 0, 0);
  leds[16].setRGB(0, 0, 0);
  leds[19].setRGB(0, 0, 0);
  FastLED.show();
  delay(100);

  //wings row 2
  leds[11].setRGB(255, 128, 0);
  leds[14].setRGB(255, 128, 0);
  leds[17].setRGB(255, 128, 0);
  leds[20].setRGB(255, 128, 0);
  FastLED.show();
  delay(100);

  leds[11].setRGB(0, 0, 0);
  leds[14].setRGB(0, 0, 0);
  leds[17].setRGB(0, 0, 0);
  leds[20].setRGB(0, 0, 0);
  FastLED.show();
  delay(100);

  //wings row 1
  leds[8].setRGB(255, 128, 0);
  leds[12].setRGB(255, 128, 0);
  leds[15].setRGB(255, 128, 0);
  leds[18].setRGB(255, 128, 0);
  leds[21].setRGB(255, 128, 0);
  FastLED.show();
  delay(100);

  leds[8].setRGB(0, 0, 0);
  leds[12].setRGB(0, 0, 0);
  leds[15].setRGB(0, 0, 0);
  leds[18].setRGB(0, 0, 0);
  leds[21].setRGB(0, 0, 0);
  FastLED.show();
  delay(100);

  for (int i = 8; i > 1; i--) {
    Serial.println(runHead);
    leds[i - 1].setRGB(255, 128, 0);
    leds[i].setRGB(0, 0, 0);
    FastLED.show();
    delay(100);
  }
}

void Hue() {
  for (int hue = 64; hue > 0; hue--) {
    for (int i = 0; i < NUM_LEDS; i++) {
      Serial.println(runHead);
      leds[i] = CHSV(hue, 255, BRIGHTNESS);
      eyes[0] = CHSV(hue, 255, BRIGHTNESS);
      eyes[1] = CHSV(hue, 255, BRIGHTNESS);
      delay(5);
    }
    FastLED.show();
  }

  for (int hue = 0; hue < 64; hue++) {
    for (int i = 0; i < NUM_LEDS; i++) {
      Serial.println(runHead);
      leds[i] = CHSV(hue, 255, BRIGHTNESS);
      eyes[0] = CHSV(hue, 255, BRIGHTNESS);
      eyes[1] = CHSV(hue, 255, BRIGHTNESS);
      delay(5);
    }
    FastLED.show();
  }
}

void Head() {
  myservo.write(150);
  delay(1000);

  myservo.write(74);
  delay(500);

  myservo.detach();
  delay(1000);
  runHead = false;
}

void pin_ISR() {
  runHead = true;
  myservo.attach(MOUTH_PIN);
}

Code without the LEDs

#include <Servo.h>

#define interuptPin 2
#define MOUTH_PIN       5

Servo myservo;

int number = 0;
bool runHead = false;


void setup() {
  // Attach an interrupt to the ISR vector
  //myservo.attach(MOUTH_PIN);
  attachInterrupt(digitalPinToInterrupt(interuptPin), pin_ISR, CHANGE);
  //attachInterrupt(digitalPinToInterrupt(interuptPin), pin_ISR, RISING);
  //attachInterrupt(digitalPinToInterrupt(interuptPin), pin_ISR, FALLING);
  //attachInterrupt(digitalPinToInterrupt(interuptPin), pin_ISR, LOW);

  Serial.begin(9600);
}

void loop() {
  number++;
  Serial.println(runHead);

  if (runHead == 1) {
    Head();
  }
}

void Head(){
  myservo.write(150);
  delay(1000);
  
  myservo.write(74);
  delay(500);

  myservo.detach();
  delay(1000);
  runHead = false;
}

void pin_ISR() {
  runHead = true;
  myservo.attach(MOUTH_PIN);
  Serial.println(runHead);
}

Video wothout the LEDs

Video with the LEDs

Interrupts are not for buttons. You are going the wrong way. Read the Adafruit tutorial on how to control Neopixels.

MorganS:
Interrupts are not for buttons. You are going the wrong way. Read the Adafruit tutorial on how to control Neopixels.

Would you mind clarifying why interrupts are not for buttons? I'm seeing many examples using buttons and other external digital inputs. And are you suspecting that the LEDs are the issue here? I'm not sure why else you would direct me to read up on controlling them when I already have the basics down.

By Arduino standards a human pressing a button is verryyyyy slooooowwww. An Arduino with well organized code can easily check a button fast enough on every iteration of loop().

Have a look at how the code is organized in Several Things at a Time

Note how each function runs very briefly and returns to loop() so the next one can be called. None of the functions tries to complete a task in one call. And there may be dozens of calls to a function before it is actually time for it to do anything.

...R

There are 2 kinds of "basics":

  1. Testing that one sensor or one servo or one string of LEDs is connected.

  2. Basic program structure which can be used to do useful things with more than one sensor or servo or other tasks.

The difference between the two is the delay(). Basics 1 uses delay() and basics 2 doesn't.

You have a type 1 program. Robin's example gets you started on type 2.

Okay... Okay... I cry uncle. I will start using millis() instead of delay() lol. I used it on a recent project and thought about using it on this one as well but I already had most of the code done and was to lazy to convert it. I'm still not sure why the interrupt doesn't work as expected (although I suspect it's somewhere in my code) but I need to start using better coding practices anyway.

Thank you for the input all.