Smooth Brightness and dimming of WS2812 (Neopixels) over long period of time

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!

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.

bpmnyc:
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.

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..

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.

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.

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

As I said above.

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.

#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);
}

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?

Hello,
I am experimenting with the same issue.
I have 5 rings with 60 Neopixel LED each.
I am reading from a cloud database which ring should be on.
When the database changes, I dim the active ring and simultaneously lit up the new ring.
The main challenge is that the colours are all different.
So Ring1 = [200, 10, 50]
Ring2 = [0, 100, 30]
....
So when I dim a ring I need to have the 3 values come down together.
So from 200 to 0, 10 to 0 and 50 to 0.
200 can be in steps of 1 for instance, and then 10 in steps of 10/200, 50 in steps 5/100.
I round the results.
But Ring2 needs to come up as well and the time of dimming needs to be the same as coming up.

So Ring 2 has its own step up values for each colour.
To make sure the timing of dimming and lighting are the same, I define a crossindex value and which is 0.5 in this case.
I don't want to tell you how many variable I had to create as on top of all this you need to determine the highest value of each ring and its position.

But after I programmed all that, I was very disappointed with the dimming result. In some cases 90% of the brightness is already reached at 25% of the digital input.

I am now going to experiment with an adjustment table that is logarithmic in nature.
So at digital input 25% the RGB value should be at 35 and not at 64 and so on.

Then you have a linear input like from a slider but the driver is logarithmic.

By the way all LEDs are driven like this in dimmer applications.

Edgard

But after I programmed all that, I was very disappointed with the dimming result. In some cases 90% of the brightness is already reached at 25% of the digital input.

This sort of thing is called gamma correction, look it up.