Need help with external interrupt

Hello,

I am trying to using a momentary push button to activate different light routines through an external interrupt. If I do a simple digital write to an led with this ISR - buttonPress - everything works fine. However when I try to call my pwm light function - lightProg1 - nothing happens. Here is my code to look at. Some help would be greatly appreciated. I am new to using interrupts on the Arduino line, been using them on PICs for awhile.

Thanks a lot in advance guys…!

volatile boolean state = true;
int dval = 10; //delay time between pwm outputs

int green = 9;   //analog green pin
int red = 10;    //analog red pin
int blue = 11;   //analog blue pin

// Analog input = 1024 steps...
// 7 colors ~= 125 ADC steps per color
 
void setup()
{
   attachInterrupt(0, buttonPress, RISING);
} 

 
void loop()
{
   delay(1);
}

void buttonPress()
{
  //online debounce code that works amazing!
  static unsigned long last_interrupt_time = 0;
  unsigned long interrupt_time = millis();
  // If interrupts come faster than 150ms, assume it's a bounce and ignore
  if (interrupt_time - last_interrupt_time > 150)
  {
    //do my thang!!!
    
    state = !state;
    if(state == true)
    {
        lightProg1();
    }
    
    //my thangs done
  }
  last_interrupt_time = interrupt_time; 
}

void lightProg1()
{
  
  for (int i=0; i <= 255; i++)
  {
      analogWrite(red, i);
      delay(dval);
   } 
   for (int i=0; i <= 255; i++)
   {
      analogWrite(green, i);
      delay(dval);
   } 
   for (int i=0; i <= 255; i++)
   {
      analogWrite(blue, i);
      delay(dval);
   } 
   for (int i=255; i >= 0; i--)
   {
      analogWrite(red, i);
      delay(dval);
   } 
   for (int i=255; i >= 0; i--)
   {
      analogWrite(green, i);
      delay(dval);
   } 
   for (int i=255; i >= 0; i--)
   {
      analogWrite(blue, i);
      delay(dval);
   } 
   for (int i=0; i <= 255; i++)
   {
      analogWrite(green, i);
      delay(dval);
   } 
   for (int i=0; i <= 255; i++)
   {
      analogWrite(blue, i);
      delay(dval);
   } 
   for (int i=0; i <= 255; i++)
   {
      analogWrite(red, i);
      delay(dval);
   } 
   for (int i=255; i >= 0; i--)
   {
      analogWrite(green, i);
      delay(dval);
   } 
   for (int i=255; i >= 0; i--)
   {
      analogWrite(red, i);
      delay(dval);
   } 
   for (int i=255; i >= 0; i--)
   {
      analogWrite(blue, i);
      delay(dval);
   } 
   
   analogWrite(red, 0);
   analogWrite(green, 0);
   analogWrite(blue, 0);
   delay(dval);
   
}

I'm new to Arduino so please consider this reply an opinion rather than fact...

Interrupt service routines (ISRs) are called with interrupts disabled. millis only updates when interrupts are enabled. delay uses millis. That means, in your ISR, delay will "lock up".

If you decide to enable interrupts during your ISR, you need to check for and prevent a recursive call.

Good luck, Brian

Brian's opinion is correct. Why not poll (repeatedly check) for switch presses in loop?

With all the pwm counts in my lightProg1 polling doesn't give me the control I want. You would have to time the button press just right for it to register, I think. In my simpler program millis() does work within the ISR. I do not know of it increments within the ISR but thats not needed. I just need a new value to compare against.

Does the variable state live within and outside the ISR or is the value garbage outside the ISR? If I can change the value of state in the ISR and do the compare on the value in the main loop that would probably work better.

state will be valid outisde the ISR.

Hey thanks everyone. I got it working. millis() does work in the ISR and I didn't know the variable state would exist outside of ISR. Using that information I am able to make a simple state machine in my main loop and go from there. Thanks guys! ;D