I love nscale8() for controlling my Fade Out routines, because you can slowly fadeout your animations without interfering with the frame rate. What about a Fade In? What techniques do you use for this? Specifically, a fade in function that you could control the duration of fade in time every time you call it…thoughts?
Two thoughts:
First: fade in …to what? Fade out is nice because there’s an implied target:0 0 0. Fade requires that you somehow specify a target.
Second: I use setBrightness to ramp up brightness of the whole animation. Start it at 0, and set it to higher and higher values until you hit the target brightness. You can use EVERY_N_MILLISECONDS(…) { … } to adjust the brightness up periodically.
I’d elaborate, but I’ve got a lulu of a head cold. Play around!
OK,I guess that was what I expected. I had the assumption that you could only use the LEDS.setBrightness() for the setup()…
Oh heck no! Try this in loop:
FastLED.setBrightness( beatsin8(60,128,255));
Presto: pulsing to a beat.
I guess what I should have asked is, I use the setBrightness() to set my Master Brightness ceiling. The scale8() function works well and doesn’t augment this master ceiling setting. Does this make sense?
Uh. Cold medicine.
Try again using more words?
I used setBrightness with a potentiometer to adjust any time needed and it worked great. But it could easily be driven by something besides a pot. Here’s my example of that:
I think this is what I meant:
byte masterBright = 128;
void setup(){
LEDS.setBrightness(masterBright);
}
void fadeIN()
{
for(byte x = 0; x < masterBright; x++)
{
FastLED.setBrightness(x);
}
}
This is more like it now, added a non blocking delay:
byte x = 0;
byte masterBright_ceiling = 128;
void fadeIN()
{
if(millis() - previousMillis > fadeINwaittime)
{
FastLED.setBrightness(x);
if(x++ > masterBright_ceiling)
{
x = 0;
break;
}
}
}
Yep. I’ve used a potentiometer too. Really convenient adjustment.
As for delays and so on, these days I tend to do this in loop:
EVERY_N_MILLISECONDS( 20) {
if( curBright < maxBright) curBright++;
FastLED.setBrightness( curBright );
}
I used nblend for fade in and fade out. There I have 255 steps. Do I have also 255 steps with nscale? And what is the best way to fade in and out very slowly and fluenty especial with analog LED Stripes at low brightnesses? I solved this with nblend with a delay but I’m not completely satisfied, because at lower brightnesses the steps are visible
Maybe someone has a better solution.
@Lars_Walpurgis Yes, nscale8 has 255 steps. Analog strips can’t take advantage of the dithering available in the library I believe…
What do you think about it @Mark_Kriegsman ? Or is it better to take a ws2801 chip and put the analog stripe behind 3 transistors?
Digitally-addressible strips tend to be 8-bits-of-resolution-per-channel all the time. FastLED performs some temporal dithering to add roughly two additional bits of control. So instead of a total of 256 levels of brightness, you can achieve perhaps 1024 levels (although only 256 may be present on the animation at any given time; still only 8 bits per channel per pixel).
Analog strips take whatever they’ve given from whatever’s driving them. If you hook them up to a PWM source (e.g. an Arduino Analog pin) that does 256 levels, then you get 256 levels. If you hook them up to a PWM source that does 4096 levels, then you get 4096 levels. The analog strips have no built-in controller, and thus no built-in limitations (or capabilities).
If you want to drive them from an existing single driver chip (e.g. WS2801, etc.), you can totally do that, and you’ll get whatever resolution the driver chip has with FastLED. The WS2801 has 8 bits per channel, and FastLED’s temporal dithering adds 2 (more or less).
If you want, you can write your own PWM driver / interrupt handler and try for higher resolution from the Arduino itself. If you go that route, check out BAM (Bit Angle Modulation), e.g. http://www.batsocks.co.uk/readme/art_bcm_3.htm as opposed to plain PWM; you can get higher resolution with fewer clock cycles.
But really, this is a pretty advanced topic, and I’d mostly recommend that people not try to write their own PWM/BAM interrupt code unless they’re willing to spend many, many frustrated hours getting all the details right.
One nice shortcut that I’ve looked at are these boards:
http://www.dxsoul.com/product/full-color-rgb-led-strip-driver-module-for-arduino-blue-black-901314667
They’re basically a P9813 driver chip, three MOSFET power transistors, and all the power connectors you need, all on one simple board. For me, it’s a way to save time.
OK, back to taking my cold medicine now.
Thanks @Mark_Kriegsman ! I think I will try the analog LED stripe on a ws2801 chip with dithering and maybe I try the analog output of the teensy with a higher resolution. I think this should also work very well.
I am working on some fading effects for my bigger LED composition project (currently setting it up on GitHub )
I did implement a fade in and fade out using nscale. (the getVal method returns a value between 0-255 to define how much faded out a pixel should be and it depends both on which pixel it is (for e.g. a wipe-style effect) and also how much time has passed within a given fade-duration (e.g. if configured to do a 2 second fade in, after 1 second it returns for all led positons a 128)
nscale8x3(myLeds[l].r, (myLeds[l].g), myLeds[l].b, channelMasks[i]>getVal(myLedRange>getNumLeds(), l));
I have 2 questions:
-
is the nscale8x3 the fastest way? for the 1-byte nscales there is this dirty version without cleaning the register. (i am using a teensy) i have to scale a LOT of pixels.
-
is there a function to map this on the actual physical brightness? I thought so but I dont find it any more. A value of 64 looks much brighter than just 25%
Related to the original question here, fade outs and ins and all other blend-over-effects are implemented in a way that an animations is created first and then put through what i call channel mask which might fade out individual or all pixels.
Thanks
small additional question:
i also want to impelment Palette based blends - however I dont see that there is a way to control the actual duration of nblendPaletteTowardPalette
If I may request this - it would be great if there was a Pallette-Blending function where I have a start and an target Palette as parameter plus a byte value to define the amount of blend. 128 = 50% blended, 25% = more similar to start than to target, etc.
That would enable me to create a Palette blending effect that takes e.g. the duration of 1 beat, etc.
I admit I did not check the implementation yet, if its not too complicated I might do it myself, but I appreciate your comment anyway.
just realized that of course i should use dim8_raw …that was too easy. sorry 
Re: brightness: the human eye sees brightness in a nonlinear way: 1/2 power looks almost as bright as full power. 1/4 power looks roughly half as bright as full power.
If you want visually-linear brightness, process each desired brightness value through a ‘gamma correction’ function. For quick and dirty approximation I use
uint8_t physicalBrightness = dim8_video( desiredBrightness );
As for nBlendPaletteTowardPalette, every time you call it it makes small changes to the current palette. You can control the number of changes, and you can call it more often to control the effect.
But to do what you want, maybe it would help to know that CRGBPalette16 palette entries are “just” arrays of CRGB. So I believe that you could mix up a new variably-blended palette with:
blend( srcPalA, srcPalB, blendedPal, 16, amountToBlend);
Thanks Mark - sorry again for the dim8 thing I just missed that.
Sounds very good with the Palette I will try this tonight.