I am trying to dim/fade in and out of warm white and I started with the WS2812B, using fastled and an Arduino Uno. Whenever I try to fade or dim in and out, I end up with yellows and reds, which I understand is due to the color mixing and there being no true white. So should I abandon this and switch to using SK6812?
I understand that fastled doesn’t work with SK6812 strips, but that you can use Neopixel. Am I understanding that Neopixel is just another library inside Arduino IDE?
I’ve already got my LEDs soldered and placed, so it’ll be a pain to tear them out and switch to the SK6812 strips, but if this is going to make the project work much better, I’ll do it. I just ask because I started trying to play around with the SK6812 and the Neopixel library, and still wasn’t quite getting what I was after, though I am a newbie so that’s not surprising.
maybe your code of dimming colors is not correct.
Show us a short demo sketch and describe when the color gets out of control so we can reproduce your problem.
"Warm white" is achieved with RGB LEDs like WS2812 by achieving a particular balance of red Vs blue Vs green levels.
Only 255 levels of red, 255 levels of blue and 255 levels of green can be achieved with WS2812 because of hardware design. The steps between these levels are more obvious at lower levels.
As you try to dim a warm white colour, it becomes more and more difficult to maintain the desired balance of red Vs green Vs blue because only those 255 levels are available and none of them may be very close to the ideal value, which changes that balance slightly. At very low levels this becomes a large change in the balance and the colour noticeably changes.
It sounds like you have multiple WS2812 LEDs in your project? Could you achieve the desired balance for warm white at dimmer levels by having some LEDs set to cool/balanced white and some percentage of the LEDs at yellow or red so that, overall, the desired balance is achieved?
This indeed applies to dimming of all colors that are not equally mixed (same color value for each of R,G & B-combination). It took me a long time to realise, that a real helper is the use of setting the led color with HSV, where Hue sets the color, Saturation makes the color more white-ish and finally Value, which changes the brightness of the chosen color while keeping the mixing ratio of the RGB-colors..
The only challenge is to find the correct HUE- and SAT-values to get the warm-white you would like to have.
If your project doesn't ask colors and you need "real white", go with SK6812 WWA. It has cool, warm and amber. 3 channels, so choice of library shouldn't be problem.
Thank you, yes, I was just wondering if there is any good solution to "dimming" without the heavy shift towards yellow and red. Sounds like maybe the SK6812, specifically the WWA might be the better solution.
That looks like a good option even though it’ll be a pain to tear out and resolder all my LEDs. It sounds like fastled doesn’t natively support these but it’s still possible?
Also I’m having a hard time finding the correct thing. Is this the right strip? When I read the description it sounds like it has only 2 channels… with one half of the LED combined with 2 color temps, and the other another color temp, but I may not fully understand what a “channel” exactly is.
How much of a workaround will it be to code these in fastled? Mostly I’m just having sections dim in and out, or an LEDs trailing across multiple sections together.
As they are fading in, there is some yellowing which isn't ideal but isn't awful. But as it fades out, right before going black it is completely yellow.
And I will preface this by saying since I am new, I am working largely with ChatGPT. Thanks so much for taking a look.
#include <FastLED.h>
#define LED_PIN 4 // Using data pin 4
#define NUM_LEDS 300 // Define 300 LEDs for flexibility
#define MAX_BRIGHTNESS 50 // Maximum brightness for glow effect
#define LED_TYPE WS2812B
#define COLOR_ORDER GRB
CRGB leds[NUM_LEDS];
// Define the LED ranges for each ring
const int ring1_start = 0, ring1_end = 18;
const int ring2_start = 18, ring2_end = 18 + 27;
const int ring3_start = 18 + 27, ring3_end = 18 + 27 + 37;
const int ring4_start = 18 + 27 + 37, ring4_end = 18 + 27 + 37 + 46;
// Softer warm white color (natural incandescent glow)
const CRGB warmWhite = CRGB(255, 160, 40);
void setup() {
FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
FastLED.setBrightness(MAX_BRIGHTNESS);
FastLED.clear();
FastLED.show();
}
void loop() {
fadeInRing(ring1_start, ring1_end); // Fade in first ring
fadeInRing(ring2_start, ring2_end); // Fade in second ring
fadeInRing(ring3_start, ring3_end); // Fade in third ring
fadeInRing(ring4_start, ring4_end); // Fade in outermost ring
delay(2000); // Hold all rings on
fadeOutAll(); // Fade out all LEDs before restarting
}
// Function to fade in a ring smoothly
void fadeInRing(int start, int end) {
for (int brightness = 0; brightness <= 255; brightness += 5) { // Increase brightness
CRGB dimColor = warmWhite;
// Adjust the brightness of the color by scaling RGB values
dimColor.r = (dimColor.r * brightness) / 255;
dimColor.g = (dimColor.g * brightness) / 255;
dimColor.b = (dimColor.b * brightness) / 255;
for (int i = start; i < end; i++) {
leds[i] = dimColor;
}
FastLED.show();
delay(30); // Smooth fade timing
}
}
// Function to fade out all LEDs smoothly
void fadeOutAll() {
for (int brightness = 255; brightness >= 0; brightness -= 5) { // Decrease brightness
CRGB dimColor = warmWhite;
// Adjust the brightness of the color by scaling RGB values
dimColor.r = (dimColor.r * brightness) / 255;
dimColor.g = (dimColor.g * brightness) / 255;
dimColor.b = (dimColor.b * brightness) / 255;
for (int i = 0; i < NUM_LEDS; i++) {
leds[i] = dimColor;
}
FastLED.show();
delay(30);
}
delay(1000); // Pause before restarting
}
Hm maybe? How would I achieve that to set some to cool and some to warm?
For example, one of the projects is a target/bullseye design. So there are 4 rings. I want the center ring to fade in, then the next, the next, the next, and then all to fade out together. But at the fade in and fade out, all the LEDs shift to a distinct yellow which isn't ideal.
The actual warm white color I have when it's fully lit is pretty decent. I am just not sure how to achieve a similar color as they fade in and out (or if that's is even possible due to the way the colors mix to create the whites). It might just be that I am at the limitation of this particular strip and I should start over with the SK6812 WWA that another commenter suggested.
Could this code be modified at all to improve the look of the white as it fades in and out? Especially right before it goes black to restart, there is a very distinct yellow that isn't ideal.
#include <FastLED.h>
#define LED_PIN 4 // Using data pin 4
#define NUM_LEDS 300 // Define 300 LEDs for flexibility
#define MAX_BRIGHTNESS 50 // Maximum brightness for glow effect
#define LED_TYPE WS2812B
#define COLOR_ORDER GRB
CRGB leds[NUM_LEDS];
// Define the LED ranges for each ring
const int ring1_start = 0, ring1_end = 18;
const int ring2_start = 18, ring2_end = 18 + 27;
const int ring3_start = 18 + 27, ring3_end = 18 + 27 + 37;
const int ring4_start = 18 + 27 + 37, ring4_end = 18 + 27 + 37 + 46;
// Softer warm white color (natural incandescent glow)
const CRGB warmWhite = CRGB(255, 160, 40);
void setup() {
FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
FastLED.setBrightness(MAX_BRIGHTNESS);
FastLED.clear();
FastLED.show();
}
void loop() {
fadeInRing(ring1_start, ring1_end); // Fade in first ring
fadeInRing(ring2_start, ring2_end); // Fade in second ring
fadeInRing(ring3_start, ring3_end); // Fade in third ring
fadeInRing(ring4_start, ring4_end); // Fade in outermost ring
delay(2000); // Hold all rings on
fadeOutAll(); // Fade out all LEDs before restarting
}
// Function to fade in a ring smoothly
void fadeInRing(int start, int end) {
for (int brightness = 0; brightness <= 255; brightness += 5) { // Increase brightness
CRGB dimColor = warmWhite;
// Adjust the brightness of the color by scaling RGB values
dimColor.r = (dimColor.r * brightness) / 255;
dimColor.g = (dimColor.g * brightness) / 255;
dimColor.b = (dimColor.b * brightness) / 255;
for (int i = start; i < end; i++) {
leds[i] = dimColor;
}
FastLED.show();
delay(30); // Smooth fade timing
}
}
// Function to fade out all LEDs smoothly
void fadeOutAll() {
for (int brightness = 255; brightness >= 0; brightness -= 5) { // Decrease brightness
CRGB dimColor = warmWhite;
// Adjust the brightness of the color by scaling RGB values
dimColor.r = (dimColor.r * brightness) / 255;
dimColor.g = (dimColor.g * brightness) / 255;
dimColor.b = (dimColor.b * brightness) / 255;
for (int i = 0; i < NUM_LEDS; i++) {
leds[i] = dimColor;
}
FastLED.show();
delay(30);
}
delay(1000); // Pause before restarting
}
If you open the datasheet on your link, it presents 3 channels. Send them a question to be sure.
I expect all 3-channel 5050 LEDs to work with fastled independently from colors and I saw there is experimental version for 4-channel LEDs as well. I have not personally tried though.
In that situation, if you set most LEDs to white and some to yellow to achieve an overall warm white, it is likely that the yellow LEDs will be easy to distinguish from the white ones around them, unless there are a large number of LEDs and they are close together.
This warm white colour that you are aiming for: what are the red, green, blue component values that give the desired colour at high brightness levels?
Right now I am using (255, 160, 40) and that is fairly close to a warmish/neutral white. I guess I shouldn't really be calling it warm white but rather a neutral soft white.
Search "hex code warm white", a result is #FDF4DC
Search "hex code cool white", a result is #F4FDFF
Search "hex code neutral white", a result is #FCFAF6
Color is in the eyes of the beholder.
Note the upper and lower values that are "good" white and use map() and/or constrain()
That is odd. I would expect that to look a strong orange, not "warmish" or "neutral" at all! There's almost no blue content, and red content is much higher than green.
I would expect warmish/neutral white to be more like (255, 225, 225).
Now I understand why, when you dim it, it quickly turns yellow or red.
The question is, why (255, 160, 40) looks like a warm white with your LEDs.
Maybe my terminology is bad, but the (255, 160, 40) is definitely not orange. Here are some photos of the (255, 160, 40) vs (255, 255, 255).
Also at the bottom is a video of when I try to dim the (255, 160, 40), using the code I previously posted.
Here is the simple code I’m using just to illuminate, and changing the fill solid numbers to the ones I mentioned.
#include <FastLED.h>
#define LED_PIN 4 // Your data pin
#define NUM_LEDS 300 // Total number of LEDs
#define BRIGHTNESS 30 // Set brightness
#define LED_TYPE WS2812B
#define COLOR_ORDER GRB
CRGB leds[NUM_LEDS];
void setup() {
FastLED.addLeds<LED_TYPE, LED_PIN, COLOR_ORDER>(leds, NUM_LEDS).setCorrection(TypicalLEDStrip);
FastLED.setBrightness(BRIGHTNESS);
// Set all LEDs to white
fill_solid(leds, NUM_LEDS, CRGB(255, 255, 255));
FastLED.show();
}
void loop() {
// Nothing in loop since we only need to light them up once
}
I would try the HSV option. And gradually reduce the brightness and at the same time shift the color to more blueish.
Leds are not linear. Eye perception is also nit linear. Hence the gradual change of percieved collor.
Well, that's obviously the problem. If you "dim" that by linearly decreasing the RGB values, you'll run out of blue long before you run out of red and green, and that would yield yellows. (IIRC, the "brightness" parameters of the 2812 libraries don't separately dim the LEDs; they just scale the RGB values.)
You might have some luck manually finding dimmer values that you like (at "full brightness" per the library), and doing your own mapping...