-
-
Notifications
You must be signed in to change notification settings - Fork 40.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix RGBW not turning off when saturation is set to 0
.
#24254
Conversation
(Temporary) Fix for RGBW not turning off when saturation is set to '0'.
Co-authored-by: Ryan <fauxpark@gmail.com>
@bryan065 the existing rgb to rgbw conversion is very basic. I do not have any rgbw leds so I can't test any different algorithm for the conversion but maybe give these a shot and see if they work better?
|
quantum/color.c
Outdated
led->w = MIN(led->r, MIN(led->g, led->b)); | ||
led->r -= led->w; | ||
led->g -= led->w; | ||
led->b -= led->w; | ||
if (led->r == led->g && led->r == led->b) { | ||
led->w = led->r; | ||
led->r = 0; | ||
led->g = 0; | ||
led->b = 0; | ||
} else { | ||
led->w = MIN(led->r, MIN(led->g, led->b)); | ||
led->r -= led->w; | ||
led->g -= led->w; | ||
led->b -= led->w; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does this actually change the behavior? In the general case, if all RGB color components are equal, MIN(led->r, MIN(led->g, led->b))
should give led->r
, and then subtracting that value from the RGB components should give 0; so the special case should not be needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's why I've mentioned that this is a temporary workaround to the issue. Without led->w = led->r;
, any LED's currently set to saturation 0
will not toggle off with RGB_TOG or sleep/timeout.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This code doesn't really care about RGB_TOG
or sleep, it simply converts the RGB value to RGBW. So the issue is likely not in how it handles the saturation value 0 since it does not even operate on HSV values... perhaps it should actually be checking for the case where all three components are 0, rather than the same value?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Update: I just tested this on a Proton C and an RGBW Neopixel stick - UG_TOGG
turns the LEDs on and off just fine at any saturation level. I don't think there's anything wrong with the conversion code as it currently exists in the repo. The issue you're having must lie elsewhere, and this PR should be closed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'll pull out some AVR controllers and my proton-c to continue testing I guess.
I'm only using SK6812's from BTF-Lighting right now so it might be a timing issue then..
I'll grab a RGBW neopixel to test too. Do you have any SK6812's you can test?
Thanks.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As far as I'm aware, the RGBW Neopixel stick uses SK6812RGBWs, and I'm pretty sure they are the only 5050 WS2812-likes that have white LEDs.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, I'll keep testing on my end. I also found this change improves the brightness of the white LED when saturation is set to 0
so there's that as well.
I realized I had the elite-c, not proton-c so all my testing would be on AVR if that would make any difference.
I'll close this PR if I can't reproduce the issue with any other controller+RGBW+rgb_matrix.
I previously tested it with a DZ60 (added rgb_matrix SK6812) and kbd67mkii/soldered (added rgb_matrix sk6812).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah, I was testing with RGBLight (Underglow). I'll try RGB Matrix in the morning, it may be something to do with that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The real problem may be this piece of code in the set_color
implementation for WS2812, which is from #21135 and tries to avoid a potentially expensive ws2812_setleds()
call if there were no actual LED state changes:
qmk_firmware/quantum/rgb_matrix/rgb_matrix_drivers.c
Lines 180 to 182 in 5acc3b2
if (rgb_matrix_ws2812_array[i].r == r && rgb_matrix_ws2812_array[i].g == g && rgb_matrix_ws2812_array[i].b == b) { | |
return; | |
} |
In the RGBW case
rgb_matrix_ws2812_array
contains RGBW data, and for the zero saturation the RGB components will be set to 0, so the above code will mistakenly ignore the request to set the RGB color to (0, 0, 0).
If we want to keep this optimization for RGBW LEDs, we would need to apply convert_rgb_to_rgbw()
to a temporary buffer, and then compare all 4 components with rgb_matrix_ws2812_array[i]
when detecting changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, I'm able to repro with RGB Matrix and it is probably due to the above.
Untangling this will be a little more complicated since the WS2812 driver is the only one with this single set_leds()
API, rather than the init
/flush
/set_color
/set_color_all
setup, which necessitates this ugly glue code. Additionally, RGBLight will require some refactoring to remove its own internal LED array, as that should really be the the driver's responsibility. Split support also needs to be retained, ideally moved into the RGBLight & RGB Matrix code so that it "just works" for any driver.
All of this is probably a blocker for the original issue here to be resolved.
@zvecr Indeed just @KarlK90 I'm aware the current RGBW is extremely basic (to the point of just getting them working). Thanks for linking those so I might return to this in the future. Right now, This fix is just for LED's not turning off when saturation is set to Video of the issue. Going from 20240805_115339.1.1.mp4 |
Thank you for your contribution! |
Thank you for your contribution! |
(Temporary?) Fix for RGBW not turning off when saturation is set to
0
.Description
Using RGB_MATRIX and RGBW LED's, when any LED's are set to
0
saturation, they won't turn off when toggled/timeout/sleep.Warning: My white LED shines much brighter now when set to
0
saturation and true white (instead of RGB array white), this resulted in my keyboard pulling about 30% more power when the full keyboard LEDs are set to white. Had to turn down maximum brightness accordingly (which would also limit your RGB LED brightness). Future PR for separate RGB maximum brightness and W maximum brightness perhaps?Code credited to @drashna .
Types of Changes
Issues Fixed or Closed by This PR
Checklist