Hey,
First of all, I am not sure if this is a bug or if it's a misunderstanding on my end about how this work. I'm kind of new to QMK so please be gentle ;)
I'm a recent owner of the DZ60RGB and I've been trying to flash my keyboard so that before resetting it, I change the color of my board such as I'm about to know I've pressed the right key combination.
I was inspired by this bit. Unfortunately, I couldn't get this to work. The keyboard never changes color before reset_keyboard. It seems to eat the command and reset it before the keyboard as the time to change its color.
I've tried the following combinations:
if (timer_elapsed32(key_timer) >= 500) {
rgb_matrix_sethsv(128, 255, 255);
wait_ms(150);
rgb_matrix_sethsv(40, 255, 255);
reset_keyboard();
}
And the keyboard pauses and resets without ever changing color. I've contacted the author and he's been having the same issue. He's also been having the same issue on the CTRL board.
Lastly, I tried to execute SEND_STRING('test') in between so that I'm truly aware that it works for every step:
if (timer_elapsed32(key_timer) >= 500) {
SEND_STRING('changing to cyan')
rgb_matrix_sethsv(128, 255, 255);
wait_ms(150);
SEND_STRING('changing to yellow')
rgb_matrix_sethsv(40, 255, 255);
reset_keyboard();
}
and it's properly sending the string to the active window.
Is this a bug or am I having a misunderstanding on how this should work?
Thanks!
RGB Matrix needs to flush the new hsv value to the LED drivers and cannot do so during wait_ms
Would calling keyboard_task or matrix_scan fix that ?
aka, where is the flush called?
Since the rgb matrix code was updated to do a single render frame calculation over several frames, you would probably need several calls to task or scan to trigger the flush.
An option would be to extern define the flush function and call it right after you set the values each time:
extern void rgb_matrix_update_pwm_buffers(void);
void in_some_function(void)
{
if (timer_elapsed32(key_timer) >= 500) {
SEND_STRING('changing to cyan')
rgb_matrix_sethsv(128, 255, 255);
rgb_matrix_update_pwm_buffers();
wait_ms(150);
SEND_STRING('changing to yellow')
rgb_matrix_sethsv(40, 255, 255);
rgb_matrix_update_pwm_buffers();
reset_keyboard();
}
}
Awesome. Can confirm that this works. :)
Edit: didn't mean to close it!
Also @XScorpion2 is there a specific reason that extern is used here? as far as I'm aware, it's not needed, and have verified that it works without that.
If that reason is "proper coding practices", that's more than fine. I was just curious.
@drashna I couldn't remember if rgb_matrix_update_pwm_buffers was defined in the header or not is all.
It is. I've implemented this, and it works perfectly.
Hey sorry for being so late to the party. I had totally forgotten about this, that's my bad!
Unfortunately, I'll be the party pooper as it doesn't work for me. I've tried what you have suggested and currently have the following
(Please do note that I'm aware that I'm going overkill on rgb_matrix_update_pwm_buffers();. I just wanted to make sure that it would be called at the right time.
...
extern void rgb_matrix_update_pwm_buffers(void);
...
bool process_record_user(uint16_t keycode, keyrecord_t* record)
{
static uint32_t key_timer;
switch (keycode) {
case REBOOT:
if (record->event.pressed) {
key_timer = timer_read32();
} else {
if (timer_elapsed32(key_timer) >= 500) {
rgb_matrix_mode(RGB_MATRIX_BREATHING);
rgb_matrix_update_pwm_buffers();
rgb_matrix_sethsv(88, 255, 100);
rgb_matrix_update_pwm_buffers();
wait_ms(2000);
rgb_matrix_update_pwm_buffers();
rgb_matrix_sethsv(0, 255, 100); // To see if this would work after the wait_ms but it doesn't.
rgb_matrix_update_pwm_buffers();
reset_keyboard();
} else {
rgb_matrix_sethsv(0, 255, 100);
}
}
return false;
default:
return true;
}
By doing the above, the keyboard waits 2 seconds before doing the reset, but the RGB colors and the animations aren't changing still.
At this point, this just becomes a fun little thing, it's not a requirement that it works. I'd just like for my keyboard to turn green and start breathing as it loads the firmware in, instead of apparently just "freezing" as it does it.
The breathing animation will not work while the keyboard is in bootloader mode, as QMK is not running at that point (this is why the RGB always freezes when you hit RESET, the animation task is just running continuously). Some of the ISSI chips have the ability to do breathing all on their own, but the drivers don't make use of it. It may be possible to send the autobreath command manually, though.
Yeah. There are two issues here, actually.
I think on the wait_ms function, it will cause the animation to pause/stop processing until it's done, anyways. And then once you reset to bootloader, it's no longer running the task.
The first issue could be fixed on ARM by using a thread for RGB Matrix tasks.
The second issue, @fauxpark is correct about.
Most helpful comment
RGB Matrix needs to flush the new hsv value to the LED drivers and cannot do so during wait_ms