using Milis() in for loops

Hello im working on a led strip project but I have some problems with reading my IR signals becaus I work with delay.

First I checked for a signal in the for loops of the led strips. But because the receiver frequency doesn’t match the transmitter frequency. I recieve different IR codes. So it doesn`t work after my first push.

https://forum.arduino.cc/index.php?topic=149498.0

Then I looked for making an interrupt with an IR reciever but I just can`t figure that out.

Now my only option is change my code, and get rid of al the delay() functions. But I don`t know how. Do I need to make a very long code with a lot of if-statements ?

For example, how can I change this code to a non delay() code ?

    int firstPixelHue = 0;
    for(int a=0; a<30; a++) {
      for(int b=0; b<3; b++) {
        strip.clear();
        for(int c=b; c<strip.numPixels(); c += 3) {
          int      hue   = firstPixelHue + c * 65536L / strip.numPixels();
          uint32_t color = strip.gamma32(strip.ColorHSV(hue));
          strip.setPixelColor(c, color);
        }
        strip.show();
        delay(wait);
        firstPixelHue += 65536 / 90;
      }
    }
    }

I gues with Milis and a lot of if statements. But I have 5 functions with for loops so my code will be very long, is there an easy way ?

is there an easy way ?

No.

But you should read about state machines. But be prepared you have to redesign your complete sketch.

‘Easy way’ should not appear in your vocabulary.

I started coding with milis(), and I did my first test and it didn`t work already. :frowning:

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

//neopixel setup
#ifdef __AVR__
 #include <avr/power.h> // Required for 16 MHz Adafruit Trinket
#endif
#define PIXEL_PIN    3  // Digital IO pin connected to the NeoPixels.
#define PIXEL_COUNT 300  // Number of NeoPixels
Adafruit_NeoPixel strip(PIXEL_COUNT, PIXEL_PIN, NEO_GRB + NEO_KHZ800);

//ir setup
const int RECV_PIN = 11;
IRrecv irrecv(RECV_PIN);
decode_results results;
unsigned long key_value = 0;

//variabels
int mode = 0;

void setup() {
    irrecv.enableIRIn();
    irrecv.blink13(true);
    strip.begin();
    strip.show();
    Serial.begin(9600);
}

void loop() {
      //ir control
      if (irrecv.decode(&results)){
          if (results.value == 0XFFFFFFFF)results.value = key_value;
          Serial.println(results.value, HEX);
          irrecv.resume();           
          if (results.value == 0xFF18E7 || results.value == 4294967295) { //2
            Serial.println("2");
            if(++mode > 9) mode = 0;
          } 
      }
      switch(mode) {
        case 0:
          colorWipe(strip.Color(  0,   0,   0), 50);    // Black/off
          break;
        case 1:
          colorWipe(strip.Color(  127,   127,   127), 50);    // white
          break;
        case 2:
          colorWipe(strip.Color(255,   0,   0), 50);    // Red
          break;
        case 3:
          colorWipe(strip.Color(  0, 255,   0), 50);    // Green
          break;
        case 4:
          colorWipe(strip.Color(  0,   0, 255), 50);    // Blue
          break;
        case 5:
          theaterChase(strip.Color(127, 127, 127), 50); // White
          break;
        case 6:
          theaterChase(strip.Color(127,   0,   0), 50); // Red
          break;
        case 7:
          theaterChase(strip.Color(  0,   0, 127), 50); // Blue
          break;
        case 8:
          rainbow(10);
          break;
        case 9:
          theaterChaseRainbow(50);
          break;   
      }
}
unsigned long previousMillis = 0;
int count = 0;
void colorWipe(uint32_t color, int wait) {
   if (millis() - previousMillis >= wait) {
     previousMillis = millis();
     strip.setPixelColor(count, color);
     strip.show();
     if(++count >= strip.numPixels()) count = 0;
   }
}
void theaterChase(uint32_t color, int wait) {
  
}
void rainbow(int wait) {
  
}
void theaterChaseRainbow(int wait) {
  
}

There are no delays in this, how does it not work ?
My IR outputs are all different from the same button. When I delete the led code in the function its working.

When the mode transitions to 0,1,2,3,4 you need to initialize the variables used by colorWipe.
If the mode stays the same and is in the range 0..4 then you don't initialize the variables, you progress them.

In particular when you switch to a new mode you'll need to update any time-out values.

Basically the changes of state may require explicit code to setup that state. The code running within a state
is dealing with sub-states of that state, as you have coded with its own variables, which looks reasonable.

In short you're close I think.

The IRRemote library relies on interrupts to receive the signal.
The Adafruit NeoPixel library relies on interrupts being OFF to make the time correct when sending data.

I would try moving your irrev.resume() function to after any of the led routines. Basically, you want to receive a code, act on it and then resume looking for a code while not updating the leds

I see what you mean with initializing the variabels. So I changed my switch, when the mode changes the variabels are set to 0 again.

     switch(mode) {
        case 0:
          if(oldmode == mode) colorWipe(strip.Color(  200,   0,   0), 50);    // Black/off
          else {
             previousMillis = 0;
             count = 0;
             colorWipe(strip.Color(  200,   0,   0), 50);    // Black/off
          }
          break;
        case 1:
          if(oldmode == mode) colorWipe(strip.Color(  127,   127,   127), 50);    // white
          else {
             previousMillis = 0;
             count = 0;
             colorWipe(strip.Color(  127,   127,   127), 50);    // white
          }
          break;
        case 2:
          if(oldmode == mode) colorWipe(strip.Color(255,   0,   0), 50);    // Red
          else {
             previousMillis = 0;
             count = 0;
             colorWipe(strip.Color(255,   0,   0), 50);    // Red
          }
          break;
        case 3:
          if(oldmode == mode) colorWipe(strip.Color(  0, 255,   0), 50);    // Green
          else {
             previousMillis = 0;
             count = 0;
             colorWipe(strip.Color(  0, 255,   0), 50);    // Green
          }
          break;
        case 4:
         if(oldmode == mode) colorWipe(strip.Color(  0,   0, 255), 50);    // Blue
          else {
             previousMillis = 0;
             count = 0;
             colorWipe(strip.Color(  0,   0, 255), 50);    // Blue
          }
          break;
        case 5:
          theaterChase(strip.Color(127, 127, 127), 50); // White
          break;
        case 6:
          theaterChase(strip.Color(127,   0,   0), 50); // Red
          break;
        case 7:
          theaterChase(strip.Color(  0,   0, 127), 50); // Blue
          break;
        case 8:
          rainbow(10);
          break;
        case 9:
          theaterChaseRainbow(50);
          break;   
      }
      oldmode = mode;

And I tried moving the irrev.resume() function but it doesn`t help. But the leds are always updating, and I want to update to new leds while its updating to. becaus my rainbow function keeps going through the loop.

Are you using debug print statements? That’s how to track your code to check its actually doing what you think.

Yes its doing what I think. I already spent a lot of time debugging. I just get different values from my IR reciever becaus of the led updates. When I clear the function colorWipe. Its working fine. And I get to mode 9 with no problem.

When I use this code I get my colors in my serial just like it should be. And I can push on my IR button to change colors.

   if (millis() - previousMillis >= wait) {
     previousMillis = millis();
     //strip.setPixelColor(count, color);
     //strip.show();
     //if(++count >= strip.numPixels()) count = 0;
     Serial.println(color);
   }

A IR controller just wont work. Ill keep it with a button. I changed everything to a non delay code for the future if I want to add an other module. Here is my code it works fine. U can use it to if you want a good ledstrip code.

#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
 #include <avr/power.h>
#endif

#define PIXEL_PIN    3
#define PIXEL_COUNT 300
#define BUTTON_PIN   2

#define UNSET -1
Adafruit_NeoPixel strip(PIXEL_COUNT, PIXEL_PIN, NEO_GRB + NEO_KHZ800);
//variabels
unsigned int mode,oldmode;
unsigned long previousMillis,lastFire,count;
bool oldState = HIGH;
void setup() {
  mode = oldmode = count = previousMillis = lastFire = 0;
  pinMode(BUTTON_PIN, INPUT_PULLUP);
  strip.begin();
  strip.show();
  Serial.begin(9600);
}
void loop() {
    bool newState = digitalRead(BUTTON_PIN);
    if((newState == LOW) && (oldState == HIGH)) {
      if (millis() - lastFire < 200) {
          oldState = newState;
          return;
      }
      lastFire = millis();
      newState = digitalRead(BUTTON_PIN);
      if(newState == LOW) { 
        if(++mode > 9) mode = 0;
        Serial.println(mode);
      }
    }
    switch(mode) {
      case 0:
        if(oldmode == mode) colorWipe(strip.Color(  0,   0,   0), 25);    // Black/off
        else {
           previousMillis = 0;
           count = 0;
           colorWipe(strip.Color(  0,   0,   0), 25);    // Black/off
        }
        break;
      case 1:
        if(oldmode == mode) colorWipe(strip.Color(  127,   127,   127), 50);    // white
        else {
           resett();
           colorWipe(strip.Color(  127,   127,   127), 50);    // white
        }
        break;
      case 2:
        if(oldmode == mode) colorWipe(strip.Color(255,   0,   0), 50);    // Red
        else {
           resett();
           colorWipe(strip.Color(255,   0,   0), 50);    // Red
        }
        break;
      case 3:
        if(oldmode == mode) colorWipe(strip.Color(  0, 255,   0), 50);    // Green
        else {
           resett();
           colorWipe(strip.Color(  0, 255,   0), 50);    // Green
        }
        break;
      case 4:
       if(oldmode == mode) colorWipe(strip.Color(  0,   0, 255), 50);    // Blue
        else {
           resett();
           colorWipe(strip.Color(  0,   0, 255), 50);    // Blue
        }
        break;
      case 5:
        theaterChase(strip.Color(127, 127, 127), 50); // White
        break;
      case 6:
        theaterChase(strip.Color(127,   0,   0), 50); // Red
        break;
      case 7:
        theaterChase(strip.Color(  0,   0, 127), 50); // Blue
        break;
      case 8:
       if(oldmode == mode) rainbow(10);
        else {
           resett();
           rainbow(10);
        }
        break;
      case 9:
        if(oldmode == mode) theaterChaseRainbow(50, false);
        else {
           resett();
           theaterChaseRainbow(50, true);
        }
        break;   
    }
    oldmode = mode;
    oldState = newState;
}
void resett() {
   strip.clear();
   previousMillis = 0;
   count = 0;
}
void colorWipe(uint32_t color, int wait) { 
   if (millis() - previousMillis >= wait) {
     previousMillis = millis();
     strip.setPixelColor(count, color);
     strip.show();
     if(++count >= strip.numPixels()) count = 0;
   }
}
void theaterChase(uint32_t color, int wait) {
   if (millis() - previousMillis >= wait) {
      previousMillis = millis();
      strip.clear();
      for(int c=count; c<strip.numPixels(); c += 3) {
          strip.setPixelColor(c, color);
      }
      strip.show();
      if(++count >= 3) count = 0;
   }
}
void rainbow(int wait) {
    if (millis() - previousMillis >= wait) {
    previousMillis = millis();
    for(int i=0; i<strip.numPixels(); i++) {
      int pixelHue = count + (i * 65536L / strip.numPixels());
      strip.setPixelColor(i, strip.gamma32(strip.ColorHSV(pixelHue)));
    }
    strip.show();
    count += 256;
    if(count >= 3*65536) count = 0;
   }
}
void theaterChaseRainbow(int wait, bool first) {
  int firstPixelHue;
  if(first) firstPixelHue = 0;
  if (millis() - previousMillis >= wait) {
   previousMillis = millis();
   strip.clear(); 
   for(int c=count; c<strip.numPixels(); c += 3) {
    int hue = firstPixelHue + c * 65536L / strip.numPixels();
    uint32_t color = strip.gamma32(strip.ColorHSV(hue));
    strip.setPixelColor(c, color);
   }
   strip.show();
   firstPixelHue += 65536 / 90;
   if(++count >= 3) count = 0;
  }
}

Thanks for the replies