Neopixel + IR + Effect options - cant break loop to trigger different effects

Hi All,

I am spend most of my life in RPi (python) environments and I am very rusty on Arduino.
The project I am working on is an IR remote to trigger effects on NeoPixels (via the Neopixel library).

I can recieve the IR codes with no issue. I can then trigger individual led lighting effects via the IR remote. The issue I have is that when something like the rainbow scroll runs which is a 10 second long or so effect, I am unable to override this with any other IR button pushes. I know there is a simple way to sort this but I am stuck. Can anyone assist?

Thanks
Duncan

#include <Adafruit_NeoPixel.h>
#define  PIN 7
Adafruit_NeoPixel strip = Adafruit_NeoPixel(9, PIN, NEO_GRB + NEO_KHZ800);
const int irPin = 6;

void setup() {
  
  Serial.begin(115200);
  pinMode(irPin, INPUT);
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
}

void loop() {
  int key = getIrKey();
  
  if(key != 0){
    Serial.println(key);}

  if(key == 1269){
    Serial.println(key);
    colorWipe(strip.Color(255,   0,   0), 50); // Red
    }
    
  if(key == 1524){
    Serial.println(key);
    colorWipe(strip.Color(0,   255,   0), 50); // Green
    }

  if(key == 6114){
    {rainbow(10);}   
  }
}

//////////////////////////////////////////////////////////////////////////////////////////////////////

int getIrKey()  //this is the value coming from the IR Remote
{
  int len = pulseIn(irPin,LOW);
  int key, temp;
  key = 0;
  //Serial.print("len=");
  //Serial.println(len);
  if(len > 5000) {
    for(int i=1;i<=32;i++){
      temp = pulseIn(irPin,HIGH);
      if(temp > 1000)
        key = key + (1<<(i-17));
    }
  }
  if(key < 0 )
    key = -key;

  delay(250);
  return key;
}
/////////////////////////////////////////////////////////////////////////////
//Lighting effects
////////////////////////////////////////////////////////////////////////////////////


// Rainbow cycle along whole strip. Pass delay time (in ms) between frames.
void rainbow(int wait) {
  // Hue of first pixel runs 5 complete loops through the color wheel.
  // Color wheel has a range of 65536 but it's OK if we roll over, so
  // just count from 0 to 5*65536. Adding 256 to firstPixelHue each time
  // means we'll make 5*65536/256 = 1280 passes through this loop:
  for(long firstPixelHue = 0; firstPixelHue < 5*65536; firstPixelHue += 256) {
    // strip.rainbow() can take a single argument (first pixel hue) or
    // optionally a few extras: number of rainbow repetitions (default 1),
    // saturation and value (brightness) (both 0-255, similar to the
    // ColorHSV() function, default 255), and a true/false flag for whether
    // to apply gamma correction to provide 'truer' colors (default true).
    strip.rainbow(firstPixelHue);
    // Above line is equivalent to:
    // strip.rainbow(firstPixelHue, 1, 255, 255, true);
    strip.show(); // Update strip with new contents
    delay(wait);  // Pause for a moment
  }
}

// Fill the dots one after the other with a color
void colorWipe(uint32_t c, uint8_t wait) {
  for(uint16_t i=0; i<strip.numPixels(); i++) {
    strip.setPixelColor(i, c);
    strip.show();
    delay(wait);
  }
}

Of course you can't interrupt it because the controller can only do one thing at a time. While executing the rainbow effect - it does not read messages from the IR receiver, this is how your program is written

Unfortunately there is NO simple fix for this. The only way is rewrite whole program in unblocking mode, that the controller can able share it time between generating led effects and reading the IR signals.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.