Ok, took all of your code and only commented out the Button bits and fixed the patternLastRun type to a long. Testing case 4 it’s working just fine.
Which Button library are you using (link) so I can download it and test with.
Actually, it’s not doing what you just explained you want it to do. fill_rainbow() fills the entire strip in a rainbow, meaning each pixel is a different color. If you want the entire string to be the same color and cycle through the colors of the rainbow, your code is wrong.
You just said (to Jon) that you want the entire strip to be one solid color, cycling through the rainbow. That is different than using fill_rainbow(). What you want is:
volatile long patternLastRun = 0;
volatile uint8_t hue = 0;
static void rainbow(int pause) {
if (millis() - patternLastRun > pause) {
LEDS.showColor(CHSV(hue++, 255, 255));
patternLastRun = millis();
}
}
Or, alternatively, put the hue inside of the function:
volatile long patternLastRun = 0;
static void rainbow(int pause) {
static uint8_t hue;
if (millis() - patternLastRun > pause) {
LEDS.showColor(CHSV(hue++, 255, 255));
patternLastRun = millis();
}
}
Okay. Maybe that explains why I can do it using for(hue=0; hue < 256; hue++), but not an ‘if’ statement. Guess its back to the drawing board. Thank you guys for all of your help… definitely can’t say I haven’t learned anything.
void loop(){
for(byte i = 0; i < NUM_LEDS; i++){
leds[i] = hue; }
LEDS.show();
hue++;
LEDS.delay(20);
}
… or use my short function. 
I forgot about the showColor function, yeah use Ashley’s
Great - ill give that a shot. Again, thank you both very much.
Well, I have come to the conclusion that it must be impossible to fade a strip of LEDs through the colors of the rainbow using a pushbutton and case() function without interrupts. Am I wrong on this?
I want the strip to do more than just a rainbow ( hence the case() ), which is why I have to use for() (since I have to make the rainbow fade a separate function, as opposed to just putting the code in the main loop). At this point I think I’ve spent close to 15 hours on trying to achieve this simple effect… to no avail. Talk about aggravating! Before I give up, does anyone else have any suggestions?
I have code that does several different things, from fading, to flashing, rainbow, all kinds of stuff. None of that code is in the main loop(). It’s all in separate functions and called via a case switch.
My POV code runs code very fast (in the micro seconds updates on a 48 pixel string) and has a button on an interrupt that controls the string’s brightness. Granted, it’s using the LPD8806 so I don’t have issues with interrupts, but even without using interrupts, there’s no reason why you can’t do it.
The trick is to never use a) delay() or b) for or while loops for your patterns (unless it’s for a very short amount of time, like to prefill something really quick.) All variables are kept as either static or outside of the function, then updated inside of the function.
Ah ha! I just put the hue++ inside of my loop() and then called it from the rainbow_fill function - instead of doing a for(hue=0, hue <255, hue++). Thanks Ashley! Time for a beer!
Here’s my sketch, just in case anybody else ever runs into this question:
We’ve been telling you for a while now to stop using a for loop. The hue++ should go inside of the function, otherwise your loop will constantly be updating it for no reason. Especially if you have a timer on your function that causes it not to fire with every single loop iteration. For example:
void loop() {
hue++;
call_function();
}
static void call_function() {
if (millis() - lastRun > 50) {
// Flash LEDs
lastRun = millis();
}
}
Now, your hue is being updated 50 times before being used by the function. You will not end up with a smooth transition of colors.
You need to get rid of that delay() inside of the rainbow function too (line 34). That’s blocking everything. Go back to the code that we’ve posted previously and use a timer delay (based on millis()).
Also, line 35 is unnecessary. It will automatically wrap around.
Here you go, same code with the correct changes: http://pastebin.com/ZQygVWgt
HOWEVER, this is NOT doing what you have previously described. You said you want the entire string to be a single color and have it cycling through the colors of the rainbow. That’s not what this does. This puts the entire rainbow colors on the string then creates a chase where the rainbow is moving along the strip.
If it’s the other one you want, then the rainbow effect should be written as:
static void rainbow(int pause) {
if (millis() - patternLastRun > pause) {
LEDS.showColor(CHSV(hueTick, 255, 255));
patternLastRun = millis();
hueTick++;
}
}
You can also get rid of the hueTick++ line all together by doing it in the LEDS call:
LEDS.showColor(CHSV(hueTick++, 255, 255));
The same applies for the other function.