Interrupt help

Hello all,

I am using an arduino to build a LED mood lamp, like everyone else (lol). I am using a switch case format to change LED patterns and using a button to trigger an interrupt to switch cases. When it triggers it still has to wait for the LED pattern subroutine to finish before switching modes. How can I get the program to instantly change modes (case) after the interrupt. Here is some of my code:

void loop() 
{ 
  
  Serial.print("Button State is ");
  Serial.println(buttonState, DEC); 
  delay(50);
  
  switch (buttonState) {
  case 0:
    // off mode
    redOFF();
    blueOFF();
    greenOFF();  
  case 1:

    //All White mode
    delay(500);
    for(int i=0; i<1; i++){ //blink for debugging only
      redON();
      delay(75);
      redOFF();
      delay(75);
    }
    delay(1000);//debug
    WhiteProg();  //LED mode
    delay(1000);//debug
    break;
  case 2:

    //Fast color shift mode
    delay(500);
    for(int i=0; i<2; i++){ //blink for debugging only
      redON();
      delay(75);
      redOFF();
      delay(75);
    }
    delay(1000); //debug
    DiscoProg(); //LED mode
    break;

  case 3:
    //color shifting
    delay(500);
    for(int i=0; i<3; i++){ //blink for debugging only
      redON();
      delay(75);
      redOFF();
      delay(75);
    }
    delay(1000); //debug
    ColorShift(); //LED mode
    break;

  case 4:
    //color shifting with sound
    delay(500);
    for(int i=0; i<4; i++){ //blink for debugging only
      redON();
      delay(75);
      redOFF();
      delay(75);
    }
    delay(1000); //debug
    Sound_ColorShift();  // LED mode
    break;
  }
}


//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~ISR Routine ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
//~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
void buttonPress() //ISR routine for lamp mode
{
  //stolen 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 > 200)
  {
    //do my thang!!!

    buttonState = buttonState++;
    if(buttonState > 4)
    { 
      buttonState = 0;
    }
    //Serial.print("button State is ");
    //Serial.println(buttonState, DEC); 
    //delay(100);
    
    //my thangs done
  }
  
  last_interrupt_time = interrupt_time;
}

Thanks for the help guys. I’m pretty good with hardware but can hardly get around software sometimes. Pointers??? Ugh, don’t even know how to start using them.

The interrupt routine only changes 'buttonstate'. When you return from the ISR your code continues doing what it was doing, delays and loops and all. The next time you check buttonstate it will be changed.

You have two choices:

Set a flag in the interrupt routine and put "if(flag)[flag=false;break;}" inside your various loops.

Change your code to rely on millis() and not delay() for timing. Then you can react to the buttonstate change next time through loop().

Note: Did you declare buttonstate 'volatile' since it can change at any time. Do that for 'flag', too, if you use it.