ATmega32U4 Pro Micro with LED and IR receiving/interrupts

Hi,

I’m fairly new to arduinos but I have been playing around with it for the past few weeks.
I am trying to build a project that uses an IR remote to control digital LED strips.

Basic hardware setup:

  • WS2812 LED strips connected to my arduino pro micro pin 4
  • IR Receiver (38KHZ) connected to pin 2

I read up on timers and interrupts and I tried using a sort of timer in my code but obviously doesn’t work.
I am trying to figure out how to use a hardware interrupt (perhpas using attachInterrupt?) but I am not 100% sure on how to do it but I assume it would work something like this:

My code in the void loop runs where it will call a function, lets say checkButton() and when I push a button on my IR remote e.g. A, it will do whatever I have assigned to “A”. Then I’d like to have a hardware interrupt so then while A is running, if I push another button, it then starts the void loop again or does the checkButton function so that the next effect happens immediately.

Is that possible? Can anyone provide some direction?

The important part here is that I want to have lots of sequences (meaning the LED effects are looped) assigned to my buttons

Code that I tried using below. ( no interrupts in there yet, not sure how to put it in).

#include <IRremote.h>
#include <Adafruit_NeoPixel.h>
#include <stdlib.h>

int RECV_PIN = 6;
#define STRIP_PIN 3
#define NUM_PIXELS 100

IRrecv irrecv(RECV_PIN);
decode_results results;
int btnVal;

#define POWER 0x10EFD827 
#define A 0x10EFF807 
#define B 0x10EF7887
#define C 0x10EF58A7
#define UP 0x10EFA05F
#define DOWN 0x10EF00FF
#define LEFT 0x10EF10EF
#define RIGHT 0x10EF807F
#define SELECT 0x10EF20DF

// Creates an Adafruit_NeoPixel instance
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_PIXELS, STRIP_PIN, NEO_GRB + NEO_KHZ800);

void setup()
{
  Serial.begin(9600);
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
  irrecv.enableIRIn(); // Start the receiver
}

unsigned long last = millis();

void loop() 
{
   checkButton();

   if (btnVal == 1)
   {
     if (millis() - last > 150) {
       Serial.println("A");
          colorWipe(strip.Color(255, 0, 0), 10); // Red
          colorWipe(strip.Color(0, 255, 0), 10); // Green
          colorWipe(strip.Color(0, 0, 255), 10); // Blue
       delay(200);
     }
   }
   if (btnVal == 2)
   {
     if (millis() - last > 150) {
       Serial.println("B");
       delay(100);
     }
   }
    if (btnVal == 3)
   {
     if (millis() - last > 150) {     
       Serial.println("C");
       delay(100);
     }
   }
    if (btnVal == 0)
   {
     if (millis() - last > 150) {
       strip.Color(0, 0, 0);
       delay(100);
     }
   }

   
}

void checkButton() {
if (irrecv.decode(&results)) 
  {
    if (results.value == POWER) 
    {
      Serial.println("POWER");  
      btnVal = 0;  
    }
     if (results.value == A) 
    {
      btnVal = 1;
    }
     if (results.value == B) 
    {
      btnVal = 2; 
    }
     if (results.value == C) 
    {
      btnVal = 3;
    }
     if (results.value == UP) 
    {
      Serial.println("UP");
    }
     if (results.value == DOWN) 
    {
      Serial.println("DOWN");
    }
     if (results.value == LEFT) 
    {
      Serial.println("LEFT");
    }
     if (results.value == RIGHT) 
    {
      Serial.println("RIGHT");
    }
     if (results.value == SELECT) 
    {
      Serial.println("SELECT");  
    }
    irrecv.resume();
    last = millis(); 
  }
}
      
      
void colorWipe(uint32_t c, uint8_t wait) {
  for(uint16_t i=0; i<strip.numPixels(); i++) {
      checkButton();
      strip.setPixelColor(i, c);
      strip.show();
      delay(wait);
  }
}

I think the problem is that the LED strip update disables interrupts so it can get the timing right. That causes the IR receive and any other time-critical interrupt code to fail.

Okay…I figured something like that, but this is also why I wanted to use hardware interrupt - or am I not on the right track?

Using a hardware interrupt won't help if the LED strip library turns the interrupts off for a long time.

If you re-write the LED strip library to use interrupts for timing that might work but I think the times are too short.