"Infinite" loop stop working

Hello,

I have tricky question on you. I am using WS2812b leds together with adafruit_Neopixel library. And I want to control these leds with IR remote controller.

I have picked demo codes from Adafruit_Neopixel library. (colorWipe; theaterChase and so on)
So If I push button on IR remote controller. Arduino decode it, and switch on leds with proper effect.

Code works fine for simple function like turn leds blue or red..... - first two cases.

Case 3 is a led blinking. (void theaterChaseRainbow) And as it blinks it turn color across the whole color spectrum like a rainbow.

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

#define PIN 12
Adafruit_NeoPixel strip = Adafruit_NeoPixel(8, PIN, NEO_GRB + NEO_KHZ800);


int IRpin = 11;
IRrecv irrecv(IRpin);
decode_results results;

void setup()
{
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver


  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
  strip.setBrightness(125); // set brightness

}

void loop()    
{
  if (irrecv.decode(&results))
  {


    switch (results.value)

    {

      case 16228447:
        Serial.println(" green   ");                       // green light turns on
        colorWipe(strip.Color(0, 255, 0), 15);
        break;

      case 16212127:
        Serial.println(" blue    ");                       // blue light turns on
        colorWipe(strip.Color(0, 0, 255), 15);
        break;


      case 16248847:                                     
        Serial.println(" strobe              ");
        theaterChaseRainbow(50);
        break;




    }

    // delay(500);
    irrecv.resume();   // Receive the next value
  }

}

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);
  }
}


void theaterChaseRainbow(uint8_t wait) {
  for (int u = 0; u < 10; u++) { //do 10 cycles of chasing

    for (int j = 0; j < 256; j++) {// cycle all 256 colors in the wheel

      if (results.value == 16248847){
         for (int q = 0; q < 3; q++) {
          for (uint16_t i = 0; i < strip.numPixels(); i = i + 3) {
            strip.setPixelColor(i + q, Wheel( (i + j) % 255)); //turn every third pixel on
          }
          strip.show();

          delay(wait);

          for (uint16_t i = 0; i < strip.numPixels(); i = i + 3) {
            strip.setPixelColor(i + q, 0);      //turn every third pixel off
          }
          Serial.println(j);
          if (irrecv.decode(&results))
          {
            Serial.println(results.value, DEC); // Print the Serial 'results.value'
            irrecv.resume();
          }
          u = 5;

        }
      }


    }


  }

}




uint32_t Wheel(byte WheelPos) {
  WheelPos = 255 - WheelPos;
  if (WheelPos < 85) {
    return strip.Color(255 - WheelPos * 3, 0, WheelPos * 3);
  }
  if (WheelPos < 170) {
    WheelPos -= 85;
    return strip.Color(0, WheelPos * 3, 255 - WheelPos * 3);
  }
  WheelPos -= 170;
  return strip.Color(WheelPos * 3, 255 - WheelPos * 3, 0);
}

The original code swift across all the colors once and than turn off.
I have tried to modify it to keep colors changing in the loop. Loop can be break only if user push some button to switch the effect. At he beginning of function theaterchaserainbow is for cycle which should be infinite loop. Because at the end of the loop I reset the counter U back to 0.

But from time to time (5-10 minutes) counter U didn´t reset itself back to zero, but to some random value like 1548483 or so. So light effect stops, and it is required to push the proper button again.

void theaterChaseRainbow(uint8_t wait) {
  for (int u = 0; u < 10; u++) { //do 10 cycles of chasing

    for (int j = 0; j < 256; j++) {// cycle all 256 colors in the wheel

      if (results.value == 16248847){
         for (int q = 0; q < 3; q++) {
          for (uint16_t i = 0; i < strip.numPixels(); i = i + 3) {
            strip.setPixelColor(i + q, Wheel( (i + j) % 255)); //turn every third pixel on
          }
          strip.show();

          delay(wait);

          for (uint16_t i = 0; i < strip.numPixels(); i = i + 3) {
            strip.setPixelColor(i + q, 0);      //turn every third pixel off
          }
          Serial.println(j);
          if (irrecv.decode(&results)) //check if new button was pushed. If no, keep looping.
          {
            Serial.println(results.value, DEC); // Print the Serial 'results.value'
            irrecv.resume();
          }
          u = 0;  //reset counter U to 0

        }
      }


    }

So I am asking how to avoid this stopping "infinite" loop? Or the approach of using Case method is wrong and I should use If statement in the void loop()?
Goal is to change effects of the leds by pushing button on IR remote controller.

I am using Arduino UNO R3

Thank you very much
Best regards
Tomas

  for (int u = 0; u < 10; u++)   //do 10 cycles of chasing

Declares a variable named u the scope of which is only inside the for loop

How does setting it to zero later in the code achieve anything ?

I see no infinite loop.

  while (true)  // infinite loop
  {
    ..
  }

Fritom:
But from time to time (5-10 minutes) counter U didn´t reset itself back to zero, but to some random value like 1548483 or so. So light effect stops, and it is required to push the proper button again.

You don't display 'u'. You only display 'j' and 'results.value'. I think your IR receiver is receiving a spurious signal. It takes that signal to mean that it's time to stop the chase effect.
Use this simple sketch that does nothing but display each IR results.value:

#include <IRremote.h>


int IRpin = 11;
IRrecv irrecv(IRpin);
decode_results results;


void setup() {
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver
}


void loop() {
  if (irrecv.decode(&results)) {
    Serial.println(results.value, DEC);
    irrecv.resume();   // Receive the next value
  }
}

If you get signals when you are not pressing any buttons on your remote you will need to track down where that signal is coming from.

One way to work around the problem is to move all of the IR Remote code into a separate function that recognizes your button codes and sets a global variable to indicate which button was pressed:

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


#define PIN 12
Adafruit_NeoPixel strip = Adafruit_NeoPixel(8, PIN, NEO_GRB + NEO_KHZ800);




int IRpin = 11;
IRrecv irrecv(IRpin);
decode_results results;


enum {Green, Blue, Strobe} LastButtonPressed;


void setup()
{
  Serial.begin(9600);
  irrecv.enableIRIn(); // Start the receiver


  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
  strip.setBrightness(125); // set brightness


}


void loop() {
  CheckRemote();


  switch (LastPressedButton) {
    case Green:
      Serial.println(" green   ");
      colorWipe(strip.Color(0, 255, 0), 15);
      break;


    case Blue:
      Serial.println(" blue    ");                       // blue light turns on
      colorWipe(strip.Color(0, 0, 255), 15);
      break;


    case Strobe:
      Serial.println(" strobe              ");
      theaterChaseRainbow(50);
      break;
  }
}




void CheckRemote() {
  if (irrecv.decode(&results)) {
    switch (results.value) {


      case 16228447:
        LastPressedButton = Green;
        break;


      case 16212127:
        LastPressedButton = Blue;
        break;


      case 16248847:
        LastPressedButton = Strobe;
        break;
    }
    irrecv.resume();   // Receive the next value
  }
}


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);
  }
}




void theaterChaseRainbow(uint8_t wait) {
  for (int j = 0; j < 256; j++) { // cycle all 256 colors in the wheel


    CheckRemote();
    if (LastButtonPressed != Strobe)
      return;  // Time to change effect


    for (int q = 0; q < 3; q++) {
      for (uint16_t i = 0; i < strip.numPixels(); i = i + 3) {
        strip.setPixelColor(i + q, Wheel( (i + j) % 255)); //turn every third pixel on
      }
      strip.show();


      delay(wait);


      for (uint16_t i = 0; i < strip.numPixels(); i = i + 3) {
        strip.setPixelColor(i + q, 0);      //turn every third pixel off
      }
    }
  }
}