forked from mirrors/qmk_firmware
Add ability to blink lighting layer for a specified duration (#8760)
* Implement momentarily blink of lighting layers * Refactor spidey3 userspace to use rgb layer blink * Remove un-necessary line from example in documentation * Revert "Refactor spidey3 userspace to use rgb layer blink" This reverts commit 831649bb680c41c6d663ae6fa86d13f4f8bebdd8. * Adds a missing bit of documentation about lighting layer blink * Update docs/feature_rgblight.md per suggestions Co-authored-by: James Young <18669334+noroadsleft@users.noreply.github.com> * Update docs/feature_rgblight.md per suggestions Co-authored-by: James Young <18669334+noroadsleft@users.noreply.github.com> * Update docs/feature_rgblight.md per suggestions Co-authored-by: James Young <18669334+noroadsleft@users.noreply.github.com> * cformat, as suggested Co-authored-by: James Young <18669334+noroadsleft@users.noreply.github.com>
This commit is contained in:
parent
94fc32f431
commit
e0f548085c
4 changed files with 79 additions and 3 deletions
|
@ -191,7 +191,9 @@ If you define these options you will enable the associated feature, which may in
|
||||||
* `#define RGBLIGHT_ANIMATIONS`
|
* `#define RGBLIGHT_ANIMATIONS`
|
||||||
* run RGB animations
|
* run RGB animations
|
||||||
* `#define RGBLIGHT_LAYERS`
|
* `#define RGBLIGHT_LAYERS`
|
||||||
* Lets you define [lighting layers](feature_rgblight.md) that can be toggled on or off. Great for showing the current keyboard layer or caps lock state.
|
* Lets you define [lighting layers](feature_rgblight.md?id=lighting-layers) that can be toggled on or off. Great for showing the current keyboard layer or caps lock state.
|
||||||
|
* `#define RGBLIGHT_LAYER_BLINK`
|
||||||
|
* Adds ability to [blink](feature_rgblight.md?id=lighting-layer-blink) a lighting layer for a specified number of milliseconds (e.g. to acknowledge an action).
|
||||||
* `#define RGBLED_NUM 12`
|
* `#define RGBLED_NUM 12`
|
||||||
* number of LEDs
|
* number of LEDs
|
||||||
* `#define RGBLIGHT_SPLIT`
|
* `#define RGBLIGHT_SPLIT`
|
||||||
|
|
|
@ -177,6 +177,8 @@ const uint8_t RGBLED_GRADIENT_RANGES[] PROGMEM = {255, 170, 127, 85, 64};
|
||||||
By including `#define RGBLIGHT_LAYERS` in your `config.h` file you can enable lighting layers. These make
|
By including `#define RGBLIGHT_LAYERS` in your `config.h` file you can enable lighting layers. These make
|
||||||
it easy to use your underglow LEDs as status indicators to show which keyboard layer is currently active, or the state of caps lock, all without disrupting any animations. [Here's a video](https://youtu.be/uLGE1epbmdY) showing an example of what you can do.
|
it easy to use your underglow LEDs as status indicators to show which keyboard layer is currently active, or the state of caps lock, all without disrupting any animations. [Here's a video](https://youtu.be/uLGE1epbmdY) showing an example of what you can do.
|
||||||
|
|
||||||
|
### Defining Lighting Layers :id=defining-lighting-layers
|
||||||
|
|
||||||
To define a layer, we modify `keymap.c` to list out LED ranges and the colors we want to overlay on them using an array of `rgblight_segment_t` using the `RGBLIGHT_LAYER_SEGMENTS` macro. We can define multiple layers and enable/disable them independently:
|
To define a layer, we modify `keymap.c` to list out LED ranges and the colors we want to overlay on them using an array of `rgblight_segment_t` using the `RGBLIGHT_LAYER_SEGMENTS` macro. We can define multiple layers and enable/disable them independently:
|
||||||
|
|
||||||
```c
|
```c
|
||||||
|
@ -211,8 +213,12 @@ void keyboard_post_init_user(void) {
|
||||||
rgblight_layers = my_rgb_layers;
|
rgblight_layers = my_rgb_layers;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
Note: For split keyboards with two controllers, both sides need to be flashed when updating the contents of rgblight_layers.
|
||||||
|
|
||||||
Finally, we enable and disable the lighting layers whenever the state of the keyboard changes:
|
### Enabling and disabling lighting layers :id=enabling-lighting-layers
|
||||||
|
|
||||||
|
Everything above just configured the definition of each lighting layer.
|
||||||
|
We can now enable and disable the lighting layers whenever the state of the keyboard changes:
|
||||||
|
|
||||||
```c
|
```c
|
||||||
layer_state_t layer_state_set_user(layer_state_t state) {
|
layer_state_t layer_state_set_user(layer_state_t state) {
|
||||||
|
@ -228,7 +234,40 @@ bool led_update_user(led_t led_state) {
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
Note: For split keyboards with two controllers, both sides need to be flashed when updating the contents of rgblight_layers.
|
### Lighting layer blink :id=lighting-layer-blink
|
||||||
|
|
||||||
|
By including `#define RGBLIGHT_LAYER_BLINK` in your `config.h` file you can turn a lighting
|
||||||
|
layer on for a specified duration. Once the specified number of milliseconds has elapsed
|
||||||
|
the layer will be turned off. This is useful, e.g., if you want to acknowledge some
|
||||||
|
action (e.g. toggling some setting):
|
||||||
|
|
||||||
|
```c
|
||||||
|
const rgblight_segment_t PROGMEM _yes_layer[] = RGBLIGHT_LAYER_SEGMENTS( {9, 6, HSV_GREEN} );
|
||||||
|
const rgblight_segment_t PROGMEM _no_layer[] = RGBLIGHT_LAYER_SEGMENTS( {9, 6, HSV_RED} );
|
||||||
|
|
||||||
|
const rgblight_segment_t* const PROGMEM _rgb_layers[] =
|
||||||
|
RGBLIGHT_LAYERS_LIST( _yes_layer, _no_layer );
|
||||||
|
|
||||||
|
void keyboard_post_init_user(void) {
|
||||||
|
rgblight_layers = _rgb_layers;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note we user post_process_record_user because we want the state
|
||||||
|
// after the flag has been flipped...
|
||||||
|
void post_process_record_user(uint16_t keycode, keyrecord_t *record) {
|
||||||
|
switch (keycode) {
|
||||||
|
case DEBUG:
|
||||||
|
rgblight_blink_layer(debug_enable ? 0 : 1, 500);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case NK_TOGG:
|
||||||
|
case NK_ON:
|
||||||
|
case NK_OFF:
|
||||||
|
rgblight_blink_layer(keymap_config.nkro ? 0 : 1, 500);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
## Functions
|
## Functions
|
||||||
|
|
||||||
|
|
|
@ -658,6 +658,31 @@ static void rgblight_layers_write(void) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ifdef RGBLIGHT_LAYER_BLINK
|
||||||
|
uint8_t _blinked_layer_mask = 0;
|
||||||
|
uint16_t _blink_duration = 0;
|
||||||
|
static uint16_t _blink_timer;
|
||||||
|
|
||||||
|
void rgblight_blink_layer(uint8_t layer, uint16_t duration_ms) {
|
||||||
|
rgblight_set_layer_state(layer, true);
|
||||||
|
_blinked_layer_mask |= 1 << layer;
|
||||||
|
_blink_timer = timer_read();
|
||||||
|
_blink_duration = duration_ms;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rgblight_unblink_layers(void) {
|
||||||
|
if (_blinked_layer_mask != 0 && timer_elapsed(_blink_timer) > _blink_duration) {
|
||||||
|
for (uint8_t layer = 0; layer < RGBLIGHT_MAX_LAYERS; layer++) {
|
||||||
|
if ((_blinked_layer_mask & 1 << layer) != 0) {
|
||||||
|
rgblight_set_layer_state(layer, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
_blinked_layer_mask = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
__attribute__((weak)) void rgblight_call_driver(LED_TYPE *start_led, uint8_t num_leds) { ws2812_setleds(start_led, num_leds); }
|
__attribute__((weak)) void rgblight_call_driver(LED_TYPE *start_led, uint8_t num_leds) { ws2812_setleds(start_led, num_leds); }
|
||||||
|
@ -909,6 +934,10 @@ void rgblight_task(void) {
|
||||||
# endif
|
# endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# ifdef RGBLIGHT_LAYER_BLINK
|
||||||
|
rgblight_unblink_layers();
|
||||||
|
# endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* RGBLIGHT_USE_TIMER */
|
#endif /* RGBLIGHT_USE_TIMER */
|
||||||
|
|
|
@ -192,6 +192,12 @@ bool rgblight_get_layer_state(uint8_t layer);
|
||||||
|
|
||||||
// Point this to an array of rgblight_segment_t arrays in keyboard_post_init_user to use rgblight layers
|
// Point this to an array of rgblight_segment_t arrays in keyboard_post_init_user to use rgblight layers
|
||||||
extern const rgblight_segment_t *const *rgblight_layers;
|
extern const rgblight_segment_t *const *rgblight_layers;
|
||||||
|
|
||||||
|
# ifdef RGBLIGHT_LAYER_BLINK
|
||||||
|
# define RGBLIGHT_USE_TIMER
|
||||||
|
void rgblight_blink_layer(uint8_t layer, uint16_t duration_ms);
|
||||||
|
# endif
|
||||||
|
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
extern LED_TYPE led[RGBLED_NUM];
|
extern LED_TYPE led[RGBLED_NUM];
|
||||||
|
|
Loading…
Reference in a new issue