Arduino Interupts

13 views
Skip to first unread message

Phil Spitler

unread,
May 4, 2015, 2:53:40 AM5/4/15
to led-...@googlegroups.com
Hi,
I am using interrupts in my Arduino project to switch between modes on an LED piece I'm working on.

The issue is, while the interrupt is working and my mode number is incrementing, my switch / case isn't switching until the current function / loop ends.

This means that if I have a function that cycles through a ton of colors slowly and I press my mode button, nothing happens until all cycles are done.

Any idea?

Here is my code.

Thanks.

Phil
Phil Spitler  |  Creative Technologist   |  Bonfire Labs  |  t : 415.394.8200  m : 415.571.3139

Website | Facebook | LinkedIn




#include "LPD8806.h"
#include "SPI.h"


int dataPin = 5;   
int clockPin = 4; 
int mode = 0;

LPD8806 strip = LPD8806(28, dataPin, clockPin);



void setup() {
  strip.begin();
  strip.show();
  pinMode(2, INPUT_PULLUP);
  attachInterrupt(0, deBounce, LOW);
  Serial.begin(9600);
}


void loop() {
   switch (mode) {  
     case 0:
       colorChase(strip.Color(127,127,127), 10);
       break;       
     case 1:
     rainbowCycle(100);
      break;
    case 2:  
      colorWipe(strip.Color(127,0,0), 10);
      colorWipe(strip.Color(0,127,0), 10);
      colorWipe(strip.Color(0,0,127), 10); // red
      break;    
  
  
} // case

} // loop





void rainbowCycle(uint8_t wait) {
  uint16_t i, j;
  
  for (j=0; j < 384 * 5; j++) {     // 5 cycles of all 384 colors in the wheel
    for (i=0; i < strip.numPixels(); i++) {
      
      strip.setPixelColor(i, Wheel( ((i * 384 / strip.numPixels()) + j) % 384) );
    }  
    strip.show();  
  }
}

void colorWipe(uint32_t c, uint8_t wait) {
  int i;
  
  for (i=0; i < strip.numPixels(); i++) {
      strip.setPixelColor(i, c);
      strip.show();
      delay(wait);
  }
}


void colorChase(uint32_t c, uint8_t wait) {
  int i;
  
  for (i=0; i < strip.numPixels(); i++) {
    strip.setPixelColor(i, 0);  // turn all pixels off
  } 
  
  for (i=0; i < strip.numPixels(); i++) {
      strip.setPixelColor(i, c);
      if (i == 0) { 
        strip.setPixelColor(strip.numPixels()-1, 0);
      } else {
        strip.setPixelColor(i-1, 0);
      }
      strip.show();
      delay(wait);
  }
}

/* Helper functions */

//Input a value 0 to 384 to get a color value.
//The colours are a transition r - g -b - back to r

uint32_t Wheel(uint16_t WheelPos)
{
  byte r, g, b;
  switch(WheelPos / 128)
  {
    case 0:
      r = 127 - WheelPos % 128;   //Red down
      g = WheelPos % 128;      // Green up
      b = 0;                  //blue off
      break; 
    case 1:
      g = 127 - WheelPos % 128;  //green down
      b = WheelPos % 128;      //blue up
      r = 0;                  //red off
      break; 
    case 2:
      b = 127 - WheelPos % 128;  //blue down 
      r = WheelPos % 128;      //red up
      g = 0;                  //green off
      break; 
  }
  return(strip.Color(r,g,b));
}


void buttonPressed()
{
  
  mode = (mode + 1) %3;
  Serial.println(mode);

}

void deBounce()
{
 static unsigned long last_interrupt_time = 0;
 unsigned long interrupt_time = millis();
 // If interrupts come faster than 200ms, assume it's a bounce and ignore
 if (interrupt_time - last_interrupt_time > 200)
 {
  buttonPressed();
 }
 last_interrupt_time = interrupt_time;






Anton Kast

unread,
May 4, 2015, 10:59:11 AM5/4/15
to led-...@googlegroups.com
You must check the value of "mode" more frequently.  There is no alternative.

You probably need to put the check in your colorWipe() loop, break when you detect the modification, and return a value so you don't just return to colorWipe() when you are in mode 2.

Anton

--
You received this message because you are subscribed to the Google Groups "LED Nerds" group.
To unsubscribe from this group and stop receiving emails from it, send an email to led-nerds+...@googlegroups.com.
To post to this group, send email to led-...@googlegroups.com.
Visit this group at http://groups.google.com/group/led-nerds.
For more options, visit https://groups.google.com/d/optout.

Andrew Morrow

unread,
May 4, 2015, 1:55:39 PM5/4/15
to led-...@googlegroups.com
I can't recall if this was something I tried, it didn't work because of variable accessibility within the function, or I tried and it worked like a champ, but I do recall essentially having a 1/0 value variable that I would check the state of all over the place within the pattern code.  When the button press function would fire, I'd set the value to 0, and it would break the function and head back to start whatever mode it should. 

Perhaps give it a try and report back.   It is a cheap (in terms of CPU cycles) way of determining if the pattern should continue or not, so it doesn't slow down the pattern even if you check it constantly. 

Hope it helps!  I made a 1D pong game that used a 2812 and two interrupts - one for each player's button - and I DO know that I got it to work, so it CAN be done (breaking the pattern code and restarting) but I just can't recall if this is how I did it! Unfortunately, the code for that is in a dead laptop.
Reply all
Reply to author
Forward
0 new messages