Neopixel + IR Interrupt

Trying to implement Neopixel Patterns to ~400 LEDs (specifically SK6812 strips). To my understanding Neopixels disable interrupts signals, meaning I cant change the patterns displayed with an IR remote in a timely fashion. Is there any work around to get this project finished? Attached below is an example of a Neopixel animation as well as my current project code.

-PS working on a newer version that implements a state machine to ditch the overall delays listed within the code. Not entirely sure how to convert the example code to a state machine to allow IR interrupts.

RGBW_LOOP.ino (2.1 KB)

LED_Lights_v.2.2.ino (20.4 KB)

Hi

In your previous topic, you posted code in code tags, but not here, why is that? Most forum members read the forum on phones & tablets and cannot open .ino files. Are the sketches too big? Maybe because of multiple patterns or repeated code sections? If so, please remove those and post sketches which are short enough to post between code tags but still illustrate your problem. If you do that, you'll get help much quicker.

Your idea to rewrite the code avoiding use of delay() and implementing an FSM sounds like the right plan. Even then, some interrupts may be missed, but if you can avoid updating the LEDs too frequently, there should be large enough gaps, where interrupts are enabled, to receive IR data. Most IR remotes send the same code many times over when you press a button, so usually one will be received fully by the Arduino.

Unfortunately, I cant post the project code because it exceeds the character limit. However Ill post the animation example code down below. In theory I understand how a FSM would work, but in practice along with the use of interrupts, I'm completely lost. Are interrupts only disabled when the leds change? If so could I use two arduinos together to receive and send the ir command to the main board and have the serial message "wait" until the interrupts are established again to change the animation?

//RGBW LOOP
#include <Adafruit_NeoPixel.h>
#define PIN 11
#define NUM_LEDS 422
// Parameter 1 = number of pixels in strip
// Parameter 2 = pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, PIN, NEO_GRBW + NEO_KHZ800);

void setup() {
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
}

// *** REPLACE FROM HERE ***
void loop() {
  RGBLoop();
}

void RGBLoop() {
  for (int j = 0; j < 4; j++ ) {
    // Fade IN
    for (int k = 0; k < 256; k++) {
      switch (j) {
        case 0: setAll(k, 0, 0, 0); break;
        case 1: setAll(0, k, 0, 0); break;
        case 2: setAll(0, 0, k, 0); break;
        case 3: setAll(0, 0, 0, k); break;
      }
      showStrip();
      delay(0.1);
    }
    // Fade OUT
    for (int k = 255; k >= 0; k--) {
      switch (j) {
        case 0: setAll(k, 0, 0, 0); break;
        case 1: setAll(0, k, 0, 0); break;
        case 2: setAll(0, 0, k, 0); break;
        case 3: setAll(0, 0, 0, k); break;
      }
      showStrip();
      delay(0.1);
    }
  }
}
// *** REPLACE TO HERE ***

void showStrip() {
#ifdef ADAFRUIT_NEOPIXEL_H
  // NeoPixel
  strip.show();
#endif
#ifndef ADAFRUIT_NEOPIXEL_H
  // FastLED
  FastLED.show();
#endif
}

void setPixel(int Pixel, byte red, byte green, byte blue, byte white) {
#ifdef ADAFRUIT_NEOPIXEL_H
  // NeoPixel
  strip.setPixelColor(Pixel, strip.Color(red, green, blue, white));
#endif
#ifndef ADAFRUIT_NEOPIXEL_H
  // FastLED
  leds[Pixel].r = red;
  leds[Pixel].g = green;
  leds[Pixel].b = blue;
  leds[Pixel].w = white;
#endif
}

void setAll(byte red, byte green, byte blue, byte white) {
  for (int i = 0; i < NUM_LEDS; i++ ) {
    setPixel(i, red, green, blue, white);
  }
  showStrip();
}

Interrupts are disabled while strip.show() executes. Your LEDs need 32 bits of data each, there are 422 of them and the data rate is 800KHz, so strip.show() will take 422x32/800 ~= 17ms at the absolute minimum, probably longer in practice. So if you want to update the strip, say, 20 times per second, i.e. once every 50ms, you might have up to 33ms to receive an IR command but probably less. I don't know how long those take. Far fewer bits are transmitted, but I expect the data rate will be much slower.

Your multiple Arduino idea is a possibility, but I would not go down that road until you know you have to. Such projects are well beyond beginner level. An attiny45/85 could be programmed to receive and buffer IR data and pass that to the Nano by some protocol. It would need to be fast, so perhaps SPI.