qmk / qmk_firmware

Open-source keyboard firmware for Atmel AVR and Arm USB families
https://qmk.fm
GNU General Public License v2.0
18.23k stars 39.27k forks source link

Backlight as layer feedback help #1743

Closed loadedsith closed 7 years ago

loadedsith commented 7 years ago

Hi there.

I had the thought that I could program my keyboard, a planck rv3, could change its backlight level based on which layer is active. That is, when on the default layer, have the backlight set to 5, but when on the lower layer turn the backlight off, and when on the raise layer to set the backlight to 10.

I've tried a few things, first I tried this in process_record_user. Which set the backlight correctly on press, but to failed to reset the backlight on the first release, but when pressing and releasing the key again, it would reset on the release.

Then I tried this with matrix_scan_user. I have a harder time explaining how this failed, but it seemed to sometimes flicker between lower and default's backlight levels.

I was hoping someone out there had done something similar or could explain what I'm not understanding about these 2 functions.

Thanks!

drashna commented 7 years ago

I'm not sure how much of this would carry over, but....

Specifically, I do this with the RGB Underglow on the Ergodox EZ. But I do this by detecting which layer it is on (matrix_scan_users), but since the RGB Light commands are resource intensive, I only set it when the layer has changed. Once it's changed, it doesn't need to be called again.

https://github.com/qmk/qmk_firmware/blob/master/keyboards/ergodox_ez/keymaps/drashna/keymap.c

If the backlight works the same (only needs to be called once), then this is what you'd want to do, as well. Add the following to the matrix_scan_user(void) function:

static bool has_layer_changed = true; uint8_t new_layer = biton32(layer_state); static uint8_t old_layer = 0; if (old_layer != new_layer) { has_layer_changed = true; old_layer = new_layer; } if (has_layer_changed) { switch (new_layer) { case 1: //backlight command for layer 1; break; case 2: //backlight command for layer 2; break; case 3: //backlight command for layer 3; break; default: //backlight command for default layer (0); break; } has_layer_changed = false; }

Setting the "has_layer_changed" boolean to true by default ensures that it will run the backlight command at least once.

Otherwise, you may want to add the command to "matrix_init_user" as this runs startup commands.

loadedsith commented 7 years ago

Thanks @drashna. I've got a working snippet here.