Other than manually setting values, is there a better way to get a gradient from red->yellow->green along an arbitrary length of LED strip, where all three colors are taking up about the same amount of LEDs? Basically I want to use an LED strip to indicate battery voltage, so I’m taking that value, and mapping it to the length of the strip and light up those LEDs. The gradient will be based on the full length of the strip, so that when the battery’s at half capacity, the strip only lights up to about half way, so you’d only see red to yellow, and only the red part when it’s nearing depletion.
Actually, I suspect you could coax this behavior out of fill_rainbow. Let’s suppose that startLed is the first led you want to color (red) and that you want ‘barLength’ number of other leds lit up with your battery indicator.
fill_rainbow(
&startLed,
barLength,
0 /* starting hue 0 = red */,
deltaHue );
“deltaHue” controls how quickly the color changes from pixel to pixel as this function paints the rainbow. The default is “5”; try adjusting it up or down to get your indicator bar to end on “green”. I suspect you’ll have to go higher, maybe 10? Depends how many pixels long the battery indicator bar will be.
Once you’ve gotten the “deltaHue” set, then just by reducing the “barLength” above, you’ll shrink the colored indicator bar.
Note that this will go from Red to Orange to Yellow to Green, which isn’t exactly what you asked for, but it might be a quick start without having to write too much other code.
Yeah, the colors are fine. Technically it should be from red to green, but when you combine the two in the middle you’ll get yellow … and then yeah, between red and yellow I’ll get orange. That works for this particular application.
Now for the million dollar question: what if i wanted to use two arbitrary colors? What if I wanted to start at red and gradually change to blue (with magenta between them)? Or reversed, from green to red? (Yeah I know, I like to make things difficult.)
(1) the starting hue passed into fill_rainbow can be any color’s hue (not just red), and there’s now a quickie color chart about 40% of the way down this wiki page:
http://code.google.com/p/fastspi/wiki/CRGBreference
(2) the deltaHue can be negative if you want the gradient to go the other way.
(3) you could also use the ‘linear interpolation’ functions (lerp…) in the library to interpolate smoothly between any two hues to make a smooth gradient.
[…and this is why working in the HSV color space is so much nicer than working directly in RGB.]
Aight, awesome. I have homework for when I get home later. 
Ok, not having a whole lot of luck with this. What’s the value of startLed … or, what should that be? I want it to start at the first one, or leds[0] and go from there to leds[47] (the 48th one in the chain).
Never mind, figured it out. This gave me the gradient I’m looking for, from red to green:
fill_rainbow(&(leds[0]), 48, 0, 2);
Making deltaHue larger made the rainbow tighter resulting in several along the string.
Great! Care to share with the class so others can see what you did?
Edited above …
The problem I had was that I made the assumption that startLed was an INT, just like the count of how many LEDs to use … then I reread your post and saw you had it as &startLed … that gave me the missing piece.
Which makes me wonder, why have the start position like that, where the count is a simple INT? Why not make both an INT? Seems more intuitive to just say:
fill_rainbow(0 /* start LED /,
48 / amount to use /,
0 / start hue /,
2 / deltaHue */);
or, instead of a LED count, just set the last LED to use in the string?
It could be like that; it’d have to take one more (earlier) param: what’s your led array? Eg “leds”
This is what I’ve been using to test and get the correct deltaHue:
#include “FastSPI_LED2.h”
// FastSPI_LED2 variables
#define NUM_LEDS 48
struct CRGB leds[NUM_LEDS];
int done = 0;
void setup() {
LEDS.addLeds<LPD8806, 7, 8, RGB>(leds, NUM_LEDS);
}
void loop() {
fill_rainbow(&(leds[0]), 48, 0, 2);
LEDS.show();
}
Huh, I wonder why I removed the ‘done’ check … Oh well, doesn’t make a difference anyway. It just stopped the loop from constantly updating the string.
Ok @Mark_Kriegsman , here’s another one. So I can set the gradient, which I think just fills the leds array with the necessary values and when I call LEDS.show(), it gets shown. Now, rather than lighting up the entire string, if I wanted to light up ONE led and make it a sort of a chase up the ladder so to speak … what’s the best way?
Can I shove all of the values into a separate array, clear the leds array, then in a FOR loop, go through and copy the data back into the leds array for each LED being turned on at that moment? So start the loop at (in my case) leds[0], copy data from the other array, turn it on, turn it off, clear the values in leds[0], then move on to leds[1], copy, on, off, clear, leds[2], copy, on, off, clear, etc., etc. till I reach leds[top] (where ‘top’ in my case represents the battery voltage mapped to the string.)
Or is there a better way? Battery voltage may be X when the unit powers up, but the simple act of showing it along the string, by lighting up all of it, full power, that’ll kill more power. So I figured if I chase a single LED up to the ‘top’, leave it on for a second then shut off, at least that’s using way less power.
And it’s a nice effect.