Interrupts goTo command?

Having read all the documentation I could find online related to interrupts, I'm left a bit confused, and unable to solve this problem - please could you guys point me in the right direction? :slight_smile:

My product is a bar of RGB LEDs, controlled from 3 PWM pins, one for each colour. I plan to program sequences of colour-changes into the bar, and have a button to change the colour sequence of the bar when the user wants.

If my main loop function polls the state of my switch, and finds it is turned ON, it will execute "programNumber++" . The program then scans down a large SWITCH structure, finds the right colour sequence to play from the value of "programNumber" and plays it. Simple!

BUT when the colour sequences get to larger lengths (say, 30 seconds long, for example) when the user presses the switch, the program might not be polling the switch state, and won't execute "programNumber++" , to change to the next program.

SO I try interrupts. Now, when the button is pressed, the interrupt pin's state changes (rises from high to low, in this case) and executes my interrupt service routine (I think that's the right terminology?). I've called my ISR function "buttonPressed" and it executes "programNumber++". Say this interrupt occurs in the middle of a 30 second colour sequence, the interrupt is called, increments the programNumber counter, and returns to the colour sequence code again! D'oh!

My friend who programs microchip PICs says I need to make my code return to the top of my loop() function after the interrupt has been called. Is this possible? Is there another way of doing this? My abbreviated code is below:

// declare variables
  // PWM output pins 9,10,11
  // input pins
  // other variables

void setup()
{
  pinMode(switchPin, INPUT);               // input  switch on pin 2
  digitalWrite(switchPin, HIGH);           // Set internal pullup
  attachInterrupt(0, buttonPressed, FALLING); // call function buttonPressed, when interrupt switch pin is activated
}


void loop()
{

    switch (programNumber)
  {
    
    case 0:
      // initial state, turn LEDs off
      solid(0, 0, 0, 1);  // solid(rValue,gValue,bValue,time) function PWM's the RGB LED a solid colour specifed by RGB values, for specified amount of time.
      break;
    
    case 1:
      // white
      solid(255, 255, 255, 1);
      break;
      
    case 2:
      // long (30 second) colour sequence
      longColourSequence();   // function contains sequence of many calls to solid() function defining different colour sequences
      break;
      
    // add more cases as more programs are devised
  }

  
  
}


// interrupt service routine
void buttonPressed()
{
  debouncer.update();
  val = debouncer.read();
  
  if( val == HIGH)
  {
    program++;
  }
   
  if(program > 2)
  {
    program = 0;
  }
  

  
  
}

one suggestion

make programNumber volatile and global scope when you declare it (this way you can change it in the interrupt and have it detected by the rest of the program)

volatile byte programNumber = 0;

Then in longColourSequence, check that programNumber still equals 2 in your loop (or loops) and return if it has changed.

Thanks for the quick reply. Could I do something like this? Below is the longColourSequence function:

void colourNoise()
{
solid(30,192,177,50);
if (programNumber !=2) {
    return;
}
solid(16,164,178,50);
if (programNumber !=2) {
    return;
}

solid(64,225,179,50);

if (programNumber !=2) {
    return;
}
solid(167,196,227,50);

if (programNumber !=2) {
    return;
}

// etc etc etc for every single command

IE. after every instruction, check that programNumber hasn't changed. If it has, return! It just seems like a bit of a bodge to me. Much as I love a good bodge, is this the only way?

:slight_smile:

Well, I assume to much maybe.

It is possible to store the data in an array, and loop over it. Just one example, many possible solutions to organize and compact code:

byte colourNoiseSeq [5] [4] = {
{30,192,177,50},
{16,164,178,50},
{64,225,179,50},
{167,196,227,50},
{167,196,227,49}
};

void colourNoise(){
for(int x = 0; x<5; x++){
solid(colourNoiseSeq[x][0],colourNoiseSeq[x][1],colourNoiseSeq[x][2],colourNoiseSeqq[x][3]);
if (programNumber !=2) return;
}
}

Wow that's brilliant! Easy to generate too ... the longColourSequence data is generated first in photoshop, then I've written a processing to scan horizontally across a .gif 's pixels, writing the required data to a .txt file ready to paste into arduino.

Seeing as it's all automated, this a format like that should be easy to make! Thanks for your help :slight_smile:

No prob, glad to help :slight_smile:

note: this data exists in ram, and you only have 1k of that. if you have a lot of data you will need to start looking into progmem in the playground.

Hmm yes, the longer sequences are pushing 4000 bytes. Thanks for pointing me at progmem. It's amazing such a simple task as making a button skip to different parts of a code gets so complex!