Skip to content
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

Closed
wants to merge 3 commits into from

Conversation

bryan065
Copy link

@bryan065 bryan065 commented Aug 7, 2024

(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

  • Core
  • Bugfix
  • New feature
  • Enhancement/optimization
  • Keyboard (addition or update)
  • Keymap/layout/userspace (addition or update)
  • Documentation

Issues Fixed or Closed by This PR

  • n/a

Checklist

  • My code follows the code style of this project: C, Python
  • I have read the PR Checklist document and have made the appropriate changes.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have read the CONTRIBUTING document.
  • I have added tests to cover my changes.
  • I have tested the changes and verified that they work and don't break anything (as well as I can manage).

(Temporary) Fix for RGBW not turning off when saturation is set to '0'.
@github-actions github-actions bot added the core label Aug 7, 2024
quantum/color.c Outdated Show resolved Hide resolved
quantum/color.c Outdated Show resolved Hide resolved
Co-authored-by: Ryan <fauxpark@gmail.com>
@KarlK90
Copy link
Member

KarlK90 commented Aug 9, 2024

@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
Comment on lines 116 to 126
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;
}
Copy link
Contributor

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.

Copy link
Author

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.

Copy link
Member

@fauxpark fauxpark Aug 10, 2024

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?

Copy link
Member

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.

Copy link
Author

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.

Copy link
Member

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.

Copy link
Author

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

Copy link
Member

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.

Copy link
Contributor

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:

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.

Copy link
Member

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.

@bryan065
Copy link
Author

@zvecr Indeed just led->w = led->r; is needed.

@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 0. Doesn't matter if it's the whole keyboard or just indicator LED's set to saturation 0.

Video of the issue. Going from 255 to 0 back to ~50 saturation. Tested with and without userspace, custom and default keymaps.

20240805_115339.1.1.mp4

Copy link

Thank you for your contribution!
This pull request has been automatically marked as stale because it has not had activity in the last 45 days. It will be closed in 30 days if no further activity occurs. Please feel free to give a status update now, or re-open when it's ready.
For maintainers: Please label with bug, awaiting review, breaking_change, in progress, or on hold to prevent the issue from being re-flagged.

@github-actions github-actions bot added the stale Issues or pull requests that have become inactive without resolution. label Sep 26, 2024
Copy link

Thank you for your contribution!
This pull request has been automatically closed because it has not had activity in the last 30 days. Please feel free to give a status update now, ping for review, or re-open when it's ready.
// [stale-action-closed]

@github-actions github-actions bot closed this Oct 27, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
core stale Issues or pull requests that have become inactive without resolution.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants