Hello! Slow fade flicker problem help please! Loving FastLED,

Hello! Slow fade flicker problem help please!

Loving FastLED, thank you! I’m trying to produce a very very slow breathe effect with sections of some White APA102 strip. My program is doing other stuff so I don’t want to use delays.

I’ve tried the standard (exp(sin(millis()/2000.0*PI)) - 0.36787944)*108.0 which is lovley. But if I slow it down as much as I need I’m getting really heavy flickering as I near black. I’m slowing by increasing the figure mulitplied by Pi and dividing mills() from 2000 to 7000. Test programme below.

I also tried a simple sin wave test, programme also below but again when I get v low it flickers. I’m wondering if I’m going to need to sequentially step down R, G and B pixels (all white with my LEDs obvs!) in order to get a smooth fade at very low levels? That alos sounds tricky to me?

Arduino is a Mega 2560, running IDE 1.6.7 on a Mac.

Thank you in advance for any help, I’m a bit desperate!

Here’s the sin code:
/***********************************/
#include <FastLED.h>

#define NUM_LEDS 144
#define COLOR_ORDER GRB
#define LED_TYPE APA102
#define MAX_BRIGHTNESS 255

struct CRGB leds[NUM_LEDS];

void setup()
{
delay(1000);
LEDS.addLeds<LED_TYPE, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
FastLED.setBrightness(MAX_BRIGHTNESS);
fill_solid( leds, NUM_LEDS, CRGB(255,255,255));
}

void loop()
{
drawBreathe();
//FastLED.show();
}

void drawBreathe() {

  float in, breath;

  for (in = 0; in < 6.283; in = in + 0.001){
    breath = sin(in) * 127.5 + 127.5;
    fill_solid( leds, NUM_LEDS, CRGB(breath,breath,breath));
    FastLED.show();
    }

}
/***********************************/

and the exp(sin(mills()) code:
/***********************************/
#include <FastLED.h>

#define NUM_LEDS 144
#define COLOR_ORDER GRB
#define LED_TYPE APA102
#define MAX_BRIGHTNESS 255

struct CRGB leds[NUM_LEDS];

void setup()
{
delay(1000);
LEDS.addLeds<LED_TYPE, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
FastLED.setBrightness(MAX_BRIGHTNESS);
FastLED.clear();
fill_solid(leds, NUM_LEDS, CRGB::White);
}

void loop () {

float breath = (exp(sin(millis()/7000.0*PI)) - 0.36787944)108.0; // was (exp(sin(millis()/2000.0PI)) - 0.36787944)*108.0
FastLED.setBrightness(breath);
FastLED.show();
}

/***********************************/

I bet you’re running into this, in the link it describes how to deactivate it. Hope this helps!

Great thinking Jon, thx so much. I’ll give it a go when I’m back with my computer and LEDs later.

I’ve just given disabling dithering a try, I assume you just use FastLED.setDither( 0 ); in setup? But it doesnt seem to make any difference sadly. Thansk for the thoughts though Jon, appreciated.
Any other pointers welcome!

@Fiddian_Warman I’m curious if you played with this some more? Since the pixels are WWW, your idea of doing each color channel separately is interesting. What about three sine waves offset in time. I’m sure you would need to experiment with the offset amount, but something like:
http://tinyurl.com/hoqppfp
If that works then you could then try using the more fancy “breathing” equations with offsets.

Another idea might be to raise the low end (bottom of sine wave) value up just enough until you stop the flickering, and then add some heavy diffusion over the leds that ends up cutting down the light output a decent amount so the leds still go fairly dark on the low end.

Hi Marc, Yes I have been working on it. I was going to post when finished but what I realised is that as you say I’ve got WWW LEDs so can play with each level so have 768 grey levels rather than 255. So this is new ‘breathe’ routine, frame number incremented in main loop:

void drawBreathe() { // slow fade in and out
int phaseFrame = frameNumber % breathePeriodInFrames;

// phase as 0 to 2π
float phase = (phaseFrame * 2.0 * PI) / (float) breathePeriodInFrames;

// brightness as 0 to 1.0
float brightness = (sin(phase) + 1.0) / 2.0; //#### or whatever breathy function you like

// as 0 to 255 * 3
int breath = brightness * (255 * 3);

//int high = 255, medium = 255, low = 255; // these instead of r g b (trying to make them a global

      if (breath < 255 * 3) {
        if (breath  > 255 * 2) {
          high = breath - 255 * 2;
          }
        else if (breath > 255) {
          high = 0;
          medium = breath - 255;
          }
        else {
          high = medium = 0;
          low = breath;
          }
          
          
  fill_solid( leds, confettiStart, CRGB(high,medium,low)); //fill_solid before confetti
  fill_solid( &(leds[confettiStart + confettiLength]), NUM_LEDS - (confettiStart + confettiLength), CRGB(high,medium,low)); //fill_solid after confetti
  }

}

It does seem to give smoother gradation down to black, With a very slow breathe the increase in brightness above around a third is hard to register. Any thoughts or comments very welcome.

Hi Marc, sorry I also meant to say I really like the three sine waves idea, nice, thank you.