replacing delay with millis in rainbowCycle function

Hello all, So currently im creating a code where if no buttons are pressed on a series of buttons, a few neopixel Leds will begin to cycle through RGB. The issue is, if i need to interrupt the code at any moment, i have to wait a few seconds before it finally changes out of the condition.
For context, every button will correlate with a color button A is red, button B is orange, etc. The code isn't fully down yet as i need to make sure all the condition due their intended result. Below is small snippit of how the condition will work:

      if ((a && b && x && y && dl && (xs == 360 || xs == 361)) == 1) // If all buttons are stationary
      {        
        rainbowCycle(50);
      }
    void rainbowCycle(uint8_t wait) {
  uint16_t i, j;
 
  for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
    for(i=0; i< strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
    }
    strip.show();
    delay(wait);
  }
}

I tried to replace delay with this:

    void rainbowCycle(uint8_t wait) {
  uint16_t i, j;
 
  for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
    for(i=0; i< strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
    }
    strip.show();
    if (currentMillis - previousMillis >= interval) //Replacing delay with a interval of 50 
     {
      previousMillis = currentMillis;
    }
  }
}

But the code does not work. how is the proper way to replace delay in the original code with millis() so that i can do the color fade and be interrupted at any moment? Thank you
Below is the entire code:

#include <Adafruit_NeoPixel.h>
#define NUM_LEDS 3
#define BRIGHTNESS 75
#define PIN A0
//const int LED = A0;
const int Xs = 9;// pins the buttons are attached too
const int A = 4;//
const int B = 5;//
const int X = 8;//
const int Y = 7;//
const int DL = 6;//
int lastButtonState;
int buttonState;
double long aPressed; // values to insert millis value
double long bPressed;
double long xPressed;
double long yPressed;
double long dlPressed;
double long xsPressed;
byte R; // byte variables
byte G;
byte V;
int zero = 0;
unsigned long previousMillis = 0;
unsigned long currentMillis = millis();
const long interval = 50;

Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUM_LEDS, PIN, NEO_GRB + NEO_KHZ800);

  int a = digitalRead(A); //read digital inputs into integers
  int b = digitalRead(B);
  int x = digitalRead(X);
  int y = digitalRead(Y);
  int dl = digitalRead(DL);
  int xs = analogRead(Xs); // 0-360-728
  
void setup() {
  pinMode(A, INPUT);
  pinMode(B, INPUT);
  pinMode(X, INPUT);
  pinMode(Y, INPUT);
  pinMode(DL, INPUT);
  pinMode(Xs, INPUT);
  Serial.begin(9600);
  strip.setBrightness(BRIGHTNESS);
  strip.begin();
  strip.show(); // Initialize all pixels to 'off'
  byte Wheel = 0;
}

void loop() {
  double long Millis = millis();
  int a = digitalRead(A);
  int b = digitalRead(B);
  int x = digitalRead(X);
  int y = digitalRead(Y);
  int dl = digitalRead(DL);
  int xs = analogRead(Xs); // 0-360-728
  
  //Serial.println("Letter b is");
  Serial.print(a);  // To freeze the lower limit
  Serial.print(" ");
  //Serial.print(2);  // To freeze the upper limit
  Serial.print(" ");  
  //Serial.println(a); 
  //Serial.println("Letter x is");
  //Serial.println(x);
  //Serial.println("-------------------------");
  
  //rainbowCycle(10);
  //------------------------CONDITIONS BEGIN HERE------------------------------------------//

  
  if (b == 0) //when pressed, turn on LEDs to RED
    {
      strip.clear();
      bPressed = Millis;
      strip.setPixelColor(2, 255, 0, 0);
      strip.show();
      strip.setPixelColor(1, 255, 0, 0);
      strip.show();
      strip.setPixelColor(0, 255, 0, 0);
      strip.show();
      strip.clear();
          
    }
  else if (30 + bPressed > Millis) // bPressed will be higher than Millis momentarily, execute color fade
    {
      uint16_t ib, jb;
      for (jb = 255; jb > 0; jb--) {
        for (ib = 0; ib < 2; ib++) {
        strip.setPixelColor(ib, jb, 0, 0);
         }
      strip.show();    
      //Serial.println(j);
      strip.clear();
      }
   } 

  if (x == 0) 
    {
      xPressed = Millis;
      for (int ixx=0; ixx<3; ixx++)
      strip.setPixelColor(ixx, 0, 255, 255);
      strip.show();
    }
  else if (30 + xPressed > Millis)
    {
      uint16_t ix, jx;
      for (jx = 255; jx > 0; jx--) {
        for (ix = 0; ix < 2; ix++) {
        strip.setPixelColor(ix, 0, jx, jx);
         }
      strip.show();    
      //Serial.println(j);
      strip.clear();
      } 
     }
     else if (x == 1)
     {      
       for (int I = 0; I < 2; I++) 
       strip.setPixelColor(I, 0, 0, 0);
       strip.show();
     }
     
     strip.clear();
     
      if ((a && b && x && y && dl && (xs == 360 || xs == 361)) == 1) // If all buttons are stationary
      {        
        rainbowCycle(50);
      }
   
 void rainbowCycle(uint8_t wait) {
  uint16_t i, j;
 
  for(j=0; j<256*5; j++) { // 5 cycles of all colors on wheel
    for(i=0; i< strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
    }
    strip.show();
    delay(wait);
  }
}

how is the proper way to replace delay in the original code with millis() so that i can do the color fade and be interrupted at any moment?

This comes up what seems like several times a day.
Look at the blink without delay example in the IDE or one of the dozens of examples of how to make a state machine.

I have posted code that does all the effects on both the Adafruit library and the fast led library a fair few times myself here. Unfortunately I am on my mobile device now so can’t post it, but if you have not had success by tomorrow I will post it again. But do try and do a search now.

Also read part 3 of multitasking.

Here you go:-

// StrandTest from AdaFruit implemented as a state machine
// pattern change by push button
// By Mike Cook Jan 2016
// Fade function added Sept 2017

#define PINforControl   4 // pin connected to the small NeoPixels strip
#define NUMPIXELS1      64 // number of LEDs on strip

#include <Adafruit_NeoPixel.h>
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUMPIXELS1, PINforControl, NEO_GRB + NEO_KHZ800);

unsigned long patternInterval = 20 ; // time between steps in the pattern
unsigned long lastUpdate = 0 ; // for millis() when last update occurred
unsigned long intervals [] = { 20, 20, 50, 100, 30 } ; // speed for each pattern - add here when adding more cases 
int fadeStep = 0; // state variable for fade function
int numberOfCases = 4; // how many case statements or patterns you have
const byte button = 3; // pin to connect button switch to between pin and ground

void setup() {
  strip.begin(); // This initialises the NeoPixel library.
  wipe(); // wipes the LED buffers
  pinMode(button, INPUT_PULLUP); // change pattern button
}

void loop() {
  static int pattern = 4, lastReading; // start with the fade function
  int reading = digitalRead(button);
  if(lastReading == HIGH && reading == LOW){
    pattern++ ; // change pattern number
    fadeStep = 0; // reset the fade state variable
    if(pattern > numberOfCases) pattern = 0; // wrap round if too big
    patternInterval = intervals[pattern]; // set speed for this pattern
    wipe(); // clear out the buffer
    delay(50); // debounce delay
  }
  lastReading = reading; // save for next time

if(millis() - lastUpdate > patternInterval) updatePattern(pattern);
}

void  updatePattern(int pat){ // call the pattern currently being created
  switch(pat) {
    case 0:
        rainbow();
        break;
    case 1:
        rainbowCycle();
        break;
    case 2:
        theaterChaseRainbow();
        break;
    case 3:
         colorWipe(strip.Color(255, 0, 0)); // red
         break; 
         
    case 4:
         fade(0,255, 0,64, 0,0, 400); // fade from black to orange and back
         break;                  
  } 
}

void fade(int redStartValue, int redEndValue, int greenStartValue, int greenEndValue, int blueStartValue, int blueEndValue, int totalSteps) {
static float redIncrement, greenIncrement, blueIncrement;
static float red, green, blue;
static boolean fadeUp = false;

if (fadeStep == 0){ // first step is to initialise the initial colour and increments
  red = redStartValue;
  green = greenStartValue;
  blue = blueStartValue;
  fadeUp = false;

  redIncrement = (float)(redEndValue - redStartValue) / (float)totalSteps;
  greenIncrement = (float)(greenEndValue - greenStartValue) / (float)totalSteps;
  blueIncrement = (float)(blueEndValue - blueStartValue) / (float)totalSteps;
  fadeStep = 1; // next time the function is called start the fade
}
else { // all other steps make a new colour and display it
  // make new colour
  red += redIncrement;
  green +=  greenIncrement;
  blue += blueIncrement;
 
  // set up the pixel buffer
  for (int i = 0; i < strip.numPixels(); i++) {
  strip.setPixelColor(i, strip.Color((int)red,(int)green,(int)blue));
  }
 // now display it
  strip.show();
fadeStep += 1; // go on to next step
if(fadeStep >= totalSteps) { // finished fade
  if(fadeUp){ // finished fade up and back
     fadeStep = 0;
     return; // so next call re-calabrates the increments 
  }
  // now fade back
  fadeUp = true;
  redIncrement = -redIncrement;
  greenIncrement = -greenIncrement;
  blueIncrement = -blueIncrement;
  fadeStep = 1; // don't calculate the increments again but start at first change
}
 }
}

void rainbow() { // modified from Adafruit example to make it a state machine
  static uint16_t j=0;
    for(int i=0; i<strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel((i+j) & 255));
    }
    strip.show();
     j++;
  if(j >= 256) j=0;
  lastUpdate = millis(); // time for next change to the display
 
}
void rainbowCycle() { // modified from Adafruit example to make it a state machine
  static uint16_t j=0;
    for(int i=0; i< strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
    }
    strip.show();
  j++;
  if(j >= 256*5) j=0;
  lastUpdate = millis(); // time for next change to the display
}

void theaterChaseRainbow() { // modified from Adafruit example to make it a state machine
  static int j=0, q = 0;
  static boolean on = true;
     if(on){
            for (int i=0; i < strip.numPixels(); i=i+3) {
                strip.setPixelColor(i+q, Wheel( (i+j) % 255));    //turn every third pixel on
             }
     }
      else {
           for (int i=0; i < strip.numPixels(); i=i+3) {
               strip.setPixelColor(i+q, 0);        //turn every third pixel off
                 }
      }
     on = !on; // toggel pixelse on or off for next time
      strip.show(); // display
      q++; // update the q variable
      if(q >=3 ){ // if it overflows reset it and update the J variable
        q=0;
        j++;
        if(j >= 256) j = 0;
      }
  lastUpdate = millis(); // time for next change to the display   
}

void colorWipe(uint32_t c) { // modified from Adafruit example to make it a state machine
  static int i =0;
    strip.setPixelColor(i, c);
    strip.show();
  i++;
  if(i >= strip.numPixels()){
    i = 0;
    wipe(); // blank out strip
  }
  lastUpdate = millis(); // time for next change to the display
}


void wipe(){ // clear all LEDs
     for(int i=0;i<strip.numPixels();i++){
       strip.setPixelColor(i, strip.Color(0,0,0));
       }
}

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

Grumpy_Mike:
Here you go:-

// StrandTest from AdaFruit implemented as a state machine

// pattern change by push button
// By Mike Cook Jan 2016
// Fade function added Sept 2017

#define PINforControl  4 // pin connected to the small NeoPixels strip
#define NUMPIXELS1      64 // number of LEDs on strip

#include <Adafruit_NeoPixel.h>
Adafruit_NeoPixel strip = Adafruit_NeoPixel(NUMPIXELS1, PINforControl, NEO_GRB + NEO_KHZ800);

unsigned long patternInterval = 20 ; // time between steps in the pattern
unsigned long lastUpdate = 0 ; // for millis() when last update occurred
unsigned long intervals [] = { 20, 20, 50, 100, 30 } ; // speed for each pattern - add here when adding more cases
int fadeStep = 0; // state variable for fade function
int numberOfCases = 4; // how many case statements or patterns you have
const byte button = 3; // pin to connect button switch to between pin and ground

void setup() {
  strip.begin(); // This initialises the NeoPixel library.
  wipe(); // wipes the LED buffers
  pinMode(button, INPUT_PULLUP); // change pattern button
}

void loop() {
  static int pattern = 4, lastReading; // start with the fade function
  int reading = digitalRead(button);
  if(lastReading == HIGH && reading == LOW){
    pattern++ ; // change pattern number
    fadeStep = 0; // reset the fade state variable
    if(pattern > numberOfCases) pattern = 0; // wrap round if too big
    patternInterval = intervals[pattern]; // set speed for this pattern
    wipe(); // clear out the buffer
    delay(50); // debounce delay
  }
  lastReading = reading; // save for next time

if(millis() - lastUpdate > patternInterval) updatePattern(pattern);
}

void  updatePattern(int pat){ // call the pattern currently being created
  switch(pat) {
    case 0:
        rainbow();
        break;
    case 1:
        rainbowCycle();
        break;
    case 2:
        theaterChaseRainbow();
        break;
    case 3:
        colorWipe(strip.Color(255, 0, 0)); // red
        break;
       
    case 4:
        fade(0,255, 0,64, 0,0, 400); // fade from black to orange and back
        break;                 
  }
}

void fade(int redStartValue, int redEndValue, int greenStartValue, int greenEndValue, int blueStartValue, int blueEndValue, int totalSteps) {
static float redIncrement, greenIncrement, blueIncrement;
static float red, green, blue;
static boolean fadeUp = false;

if (fadeStep == 0){ // first step is to initialise the initial colour and increments
  red = redStartValue;
  green = greenStartValue;
  blue = blueStartValue;
  fadeUp = false;

redIncrement = (float)(redEndValue - redStartValue) / (float)totalSteps;
  greenIncrement = (float)(greenEndValue - greenStartValue) / (float)totalSteps;
  blueIncrement = (float)(blueEndValue - blueStartValue) / (float)totalSteps;
  fadeStep = 1; // next time the function is called start the fade
}
else { // all other steps make a new colour and display it
  // make new colour
  red += redIncrement;
  green +=  greenIncrement;
  blue += blueIncrement;

// set up the pixel buffer
  for (int i = 0; i < strip.numPixels(); i++) {
  strip.setPixelColor(i, strip.Color((int)red,(int)green,(int)blue));
  }
// now display it
  strip.show();
fadeStep += 1; // go on to next step
if(fadeStep >= totalSteps) { // finished fade
  if(fadeUp){ // finished fade up and back
    fadeStep = 0;
    return; // so next call re-calabrates the increments
  }
  // now fade back
  fadeUp = true;
  redIncrement = -redIncrement;
  greenIncrement = -greenIncrement;
  blueIncrement = -blueIncrement;
  fadeStep = 1; // don't calculate the increments again but start at first change
}
}
}

void rainbow() { // modified from Adafruit example to make it a state machine
  static uint16_t j=0;
    for(int i=0; i<strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel((i+j) & 255));
    }
    strip.show();
    j++;
  if(j >= 256) j=0;
  lastUpdate = millis(); // time for next change to the display

}
void rainbowCycle() { // modified from Adafruit example to make it a state machine
  static uint16_t j=0;
    for(int i=0; i< strip.numPixels(); i++) {
      strip.setPixelColor(i, Wheel(((i * 256 / strip.numPixels()) + j) & 255));
    }
    strip.show();
  j++;
  if(j >= 256*5) j=0;
  lastUpdate = millis(); // time for next change to the display
}

void theaterChaseRainbow() { // modified from Adafruit example to make it a state machine
  static int j=0, q = 0;
  static boolean on = true;
    if(on){
            for (int i=0; i < strip.numPixels(); i=i+3) {
                strip.setPixelColor(i+q, Wheel( (i+j) % 255));    //turn every third pixel on
            }
    }
      else {
          for (int i=0; i < strip.numPixels(); i=i+3) {
              strip.setPixelColor(i+q, 0);        //turn every third pixel off
                }
      }
    on = !on; // toggel pixelse on or off for next time
      strip.show(); // display
      q++; // update the q variable
      if(q >=3 ){ // if it overflows reset it and update the J variable
        q=0;
        j++;
        if(j >= 256) j = 0;
      }
  lastUpdate = millis(); // time for next change to the display 
}

void colorWipe(uint32_t c) { // modified from Adafruit example to make it a state machine
  static int i =0;
    strip.setPixelColor(i, c);
    strip.show();
  i++;
  if(i >= strip.numPixels()){
    i = 0;
    wipe(); // blank out strip
  }
  lastUpdate = millis(); // time for next change to the display
}

void wipe(){ // clear all LEDs
    for(int i=0;i<strip.numPixels();i++){
      strip.setPixelColor(i, strip.Color(0,0,0));
      }
}

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

I've been studying your code for the past few days to see how it works. Ill continue also reading the articles larryd showed me however i am having some trouble understanding how this works, but ill keep trying to understand it. I do have one question on a particular line of code:
redIncrement = (float)(redEndValue - redStartValue) / (float)totalSteps;
ive never seen a variable type just multiplied with a variable, unless your assigning the result of the (redEndValue - redStartValue) to (float)?

(float) is casting the result as a float value.

Say, you add 2 integers together you get an integer answer 1+1=2 but if you want the answer of adding two integer to be a float answer you could (float)(1+1)=2.0.

Idahowalker:
(float) is casting the result as a float value.

Say, you add 2 integers together you get an integer answer 1+1=2 but if you want the answer of adding two integer to be a float answer you could (float)(1+1)=2.0.

That is usually not the reason you use (float), the reason is often due to a division:

1/2 -> 0
(float) 1/2 -> 0.5

HKJ-lygte:
(float) 1/2 -> 0.5

That's correct (I wasn't quite sure myself, I had to check!)

However...
(float) (1/2) gives 0.00
Why?

Because in "(float) 1/2", the value 1 gets converted to a float before it gets divided by 2. The reason for this is that type-casting (converting between types) in C takes precedence over (i.e. gets done before) division. So it becomes "1.0/2" which is 0.5.

But in "(float) (1/2)" the extra braces force the division to be done first. Because 1 and 2 are integers, integer division is used. So that becomes "(float) 0" which is 0.0.

There's an easy way to force C to use float division instead of integer division, if that's what you need. "1.0/2" gives 0.5 and "1/2.0" also gives 0.5. Putting a decimal point in the formula gives the C compiler a clue that you want to do float maths instead of integer maths.