Go Down

Topic: Smooth Brightness and dimming of WS2812 (Neopixels) over long period of time (Read 296 times) previous topic - next topic

bpmnyc

Hello Fellow forum members,
 I have a current project in which I am using Arduino Micro and WS2812 addressable LEDs.
For this project I need to smoothly brighten, then dim, LEDs of a set color over a long period of time.
I have been stuck with iterations hampered by either flickery results or HSV examples that also change the color overtime as well as the brightness.
It seems that I need to implement sine/cosine functions in order to create floating point values between 0-255 to create non-flickery results.
Any advise on how to implement this or where to find the information would be greatly appreciated!


 

surveyranger

I used a fade function for a NeoPixel project that also used the Digispark ATTiny85.  It shouldn't be much different.  The final code was attached because it was too many characters for me to post.  There is a non-blocking fade function called "fade"  (shared with me by Grumpy_Mike) that you can choose single colors or cycle through colors like I did at different speeds.  Hopefully it helps. 

Paul__B

I have been stuck with iterations hampered by either flickery results or HSV examples that also change the color overtime as well as the brightness.
It seems that I need to implement sine/cosine functions in order to create floating point values between 0-255 to create non-flickery results.
Any advise on how to implement this or where to find the information would be greatly appreciated!
Sorry, you are stuck with it.  That is the advice.

Why?

Because you are given 256-step - 8 bit - values.  At the lower levels, brightness steps will be quite visible.

Same problem as with Arduino PWM.

Wawa

With individual addressable LEDs you have the option of dimming groups of LEDs to different individual values,
so (the light of) 12-bit dimming can be simulated.
No experience with addressable LEDs, but 12-bit dimming is quite good (smooth to a low value) with COB LEDs.
For those LEDs I don't calculate, but use IEC brightness lookup tables.
Leo..

PaulRB

We can't be sure at this stage if your code is making full use of the 8-bit pwm resolution provided by the LEDs. Maybe it is, and the suggestions above could help, or maybe it isn't, and just needs correcting. Your question implies that it is currently using integer maths, and it can be tricky to use this without loss of resolution if you are not familiar with the technique. So please post a short example sketch that demonstrates the difficulty you are having. Please read the forum guide in the sticky post before you post any code.

bpmnyc

Thanks to all of you.
I had been trying to work with integer values as I am familiar with RGB color indices.
I will upload some code examples that I have been trying to work with thus far; as well as the desirable & undesirable characteristics they yield.
surveyranger- I will also attempt to test out your code with my setup and see how it goes.

Paul__B

Integer values are just fine - with 8-bit values, no point using FP mathematics.

As I said above.

bpmnyc

This is the closest I've gotten so far. Any help on how to smoothly scale the amount of time it takes to get to/from max brightness would be SO appreciated.
Code: [Select]

#include <Adafruit_NeoPixel.h>

#define PIN 11

// Parameter 1 = number of pixels in strip
// Parameter 2 = Arduino pin number (most are valid)
// Parameter 3 = pixel type flags, add together as needed:
//   NEO_KHZ800  800 KHz bitstream (most NeoPixel products w/WS2812 LEDs)
//   NEO_KHZ400  400 KHz (classic 'v1' (not v2) FLORA pixels, WS2811 drivers)
//   NEO_GRB     Pixels are wired for GRB bitstream (most NeoPixel products)
//   NEO_RGB     Pixels are wired for RGB bitstream (v1 FLORA pixels, not v2)
Adafruit_NeoPixel strip = Adafruit_NeoPixel(18, PIN, NEO_GRB + NEO_KHZ800);

// IMPORTANT: To reduce NeoPixel burnout risk, add 1000 uF capacitor across
// pixel power leads, add 300 - 500 Ohm resistor on first pixel's data input
// and minimize distance between Arduino and first pixel. Avoid connecting
// on a live circuit... if you must, connect GND first.

void setup() {
  strip.begin();
  strip.show(); // initialize all pixels to "off"
  //delay(1500);
}

void loop() {
  brighten();
  darken();
}

// 0 to 255
void brighten() {
  uint16_t i, j;

  for (j = 0; j < 255; j++) {
    for (i = 0; i < strip.numPixels(); i++) {
      strip.setPixelColor(i, j, j, j);
    }
    strip.show();
    delay(10);
  }
  //
}

// 255 to 0
void darken() {
  Serial.begin(9600);
  uint16_t i, j;

  for (j = 255; j > 0; j--) {
    for (i = 0; i < strip.numPixels(); i++) {
      strip.setPixelColor(i, j, j, j);
    }
    strip.show();
    delay(10);
    Serial.println(j);
  }
  delay(1000);
}

PaulRB

Your sketch is getting the most out of the NeoPixels. They can't dim/brighten more smoothly than what you get now. They are limited by their hardware. No calculations that the Arduino can perform using floating or integer maths can improve this.

But it may be possible to achieve more precisely controlled dimming by grouping LEDs together. For example if 5 LEDs are grouped together, and only one led is dimmed by one unit, then that is a more subtle effect than if all 5 LEDs were dimmed by one unit. Does that make sense?

Go Up