Skip to content

Instantly share code, notes, and snippets.

@aashreys
Last active December 20, 2023 09:28
Show Gist options
  • Save aashreys/01cb34605a290a7cfb94a856bdabc94c to your computer and use it in GitHub Desktop.
Save aashreys/01cb34605a290a7cfb94a856bdabc94c to your computer and use it in GitHub Desktop.
Adding RGB Timeout functionality to your QMK keyboard
/* In your config.h define a new variable RGBLIGHT_TIMEOUT and give it a value in milliseconds */
#define RGBLIGHT_SLEEP // allows us to use rgblight_suspend() and rgblight_wakeup() in keymap.c
#define RGBLIGHT_TIMEOUT 30000 // 30 seconds
/* RGB Timeout behaves similar to OLED Timeout where it turns off underglow
lighting on your QMK board after X seconds of inactivity. The logic is
best described by this reddit comment - https://bit.ly/3zCYIRl
To begin, add the following variables and function definitions to your keymap.c file */
static uint16_t key_timer; // timer to track the last keyboard activity
static void refresh_rgb(void); // refreshes the activity timer and RGB, invoke whenever activity happens
static void check_rgb_timeout(void); // checks if enough time has passed for RGB to timeout
bool is_rgb_timeout = false; // store if RGB has timed out or not in a boolean
void refresh_rgb() {
key_timer = timer_read(); // store time of last refresh
if (is_rgb_timeout) { // only do something if rgb has timed out
print("Activity detected, removing timeout\n");
is_rgb_timeout = false;
rgblight_wakeup();
}
}
void check_rgb_timeout() {
if (!is_rgb_timeout && timer_elapsed(key_timer) > RGBLIGHT_TIMEOUT) {
rgblight_suspend();
is_rgb_timeout = true;
}
}
/* Then, call the above functions from QMK's built in post processing functions like so */
/* Runs at the end of each scan loop, check if RGB timeout has occured */
void housekeeping_task_user(void) {
#ifdef RGBLIGHT_TIMEOUT
check_rgb_timeout();
#endif
/* rest of the function code here */
}
/* Runs after each key press, check if activity occurred */
void post_process_record_user(uint16_t keycode, keyrecord_t *record) {
#ifdef RGBLIGHT_TIMEOUT
if (record->event.pressed) refresh_rgb();
#endif
/* rest of the function code here */
}
/* Runs after each encoder tick, check if activity occurred */
void post_encoder_update_user(uint8_t index, bool clockwise) {
#ifdef RGBLIGHT_TIMEOUT
refresh_rgb();
#endif
/* rest of the function code here */
}
@tels7ar
Copy link

tels7ar commented Feb 1, 2023

I'm missing something here because when I try to compile with this code I get 'implicit declaration' for rgblight_wakeup() and rgblight_suspend(). Can't figure out where these functions are actually defined.

@wheelibin
Copy link

wheelibin commented Mar 29, 2023

@tels7ar I ran into the same issue, the problem was because my keyboard (crkbd) uses "RGB Matrix" lighting and not "RGB Lighting".
In this case you can simply change rgblight_wakeup() to rgb_matrix_enable_noeeprom(), and rgblight_suspend() to rgb_matrix_disable_noeeprom()

@aashreys thanks very much for creating this gist!

Edit: turns out the timeout functionality is built-in if you're using RGB Matrix...doh, so I didn't need this....I'll leave this comment for anyone who missed the option like me...
#define RGB_MATRIX_TIMEOUT 0 // number of milliseconds to wait until rgb automatically turns off

@20015jjw
Copy link

Thanks! This is also referenced/added to the official doc: https://github.com/qmk/qmk_firmware/blob/master/docs/custom_quantum_functions.md#keyboard-housekeeping

Be aware. This is NOT for RGB matrix. Check your config/rule file to make sure you are using RGBLIGHT instead of RGBMATRIX. Even though RGBLIGHT is designed for underglow (strip lighting) and RGBMATRIX is designed for per key lightning, some keyboards don't follow this rule.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment