LED Indicators#
::: tip
LED indicators on split keyboards will require state information synced to the slave half (e.g. #define SPLIT_LED_STATE_ENABLE). See data sync options for more details.
:::
QMK provides methods to read 5 of the LEDs defined in the HID spec:
- Num Lock
- Caps Lock
- Scroll Lock
- Compose
- Kana
There are three ways to get the lock LED state:
- Configuration options in
config.h - Implement
led_update_*function - Call
led_t host_keyboard_led_state()
::: warning
The host_keyboard_led_state() may reflect an updated state before led_update_user() is called.
:::
Deprecated functions that provide the LED state as uint8_t:
uint8_t host_keyboard_leds()
Configuration Options#
To configure the indicators, #define these in your config.h:
| Define | Default | Description |
|---|---|---|
LED_NUM_LOCK_PIN |
Not defined | The pin that controls the Num Lock LED |
LED_CAPS_LOCK_PIN |
Not defined | The pin that controls the Caps Lock LED |
LED_SCROLL_LOCK_PIN |
Not defined | The pin that controls the Scroll Lock LED |
LED_COMPOSE_PIN |
Not defined | The pin that controls the Compose LED |
LED_KANA_PIN |
Not defined | The pin that controls the Kana LED |
LED_PIN_ON_STATE |
1 |
The state of the indicator pins when the LED is "on" - 1 for high, 0 for low |
Unless you are designing your own keyboard, you generally should not need to change the above config options.
LED update function#
When the configuration options do not provide enough flexibility, the following callbacks allow custom control of the LED behavior. These functions will be called when one of those 5 LEDs changes state:
- Keyboard/revision:
bool led_update_kb(led_t led_state) - Keymap:
bool led_update_user(led_t led_state)
Both receives LED state as a struct parameter. Returning true in led_update_user() will allow the keyboard level code in led_update_kb() to run as well. Returning false will override the keyboard level code, depending on how the keyboard level function is set up.
Example of keyboard LED update implementation#
This is a template indicator function that can be implemented on keyboard level code:
bool led_update_kb(led_t led_state) {
bool res = led_update_user(led_state);
if(res) {
// gpio_write_pin sets the pin high for 1 and low for 0.
// In this example the pins are inverted, setting
// it low/0 turns it on, and high/1 turns the LED off.
// This behavior depends on whether the LED is between the pin
// and VCC or the pin and GND.
gpio_write_pin(B0, !led_state.num_lock);
gpio_write_pin(B1, !led_state.caps_lock);
gpio_write_pin(B2, !led_state.scroll_lock);
gpio_write_pin(B3, !led_state.compose);
gpio_write_pin(B4, !led_state.kana);
}
return res;
}
Example of user LED update implementation#
This is an incomplete example will play a sound if Caps Lock is turned on or off. It returns true to allow keyboard LED function to maintain their state.
#ifdef AUDIO_ENABLE
float caps_on[][2] = SONG(CAPS_LOCK_ON_SOUND);
float caps_off[][2] = SONG(CAPS_LOCK_OFF_SOUND);
#endif
bool led_update_user(led_t led_state) {
#ifdef AUDIO_ENABLE
static uint8_t caps_state = 0;
if (caps_state != led_state.caps_lock) {
led_state.caps_lock ? PLAY_SONG(caps_on) : PLAY_SONG(caps_off);
caps_state = led_state.caps_lock;
}
#endif
return true;
}
Host keyboard LED state#
The host_keyboard_led_state() function will report the LED state returned from the host computer as led_t. This is useful for reading the LED state outside led_update_*. For example, you can get the boolean state of Caps Lock from the host with:
bool caps = host_keyboard_led_state().caps_lock;
led_update_ports()#
This function writes the LED state to the actual hardware. Call it manually
from your led_update_*() callbacks to modify the handling of the standard
keyboard LEDs.
For example when repurposing a standard LED indicator as layer indicator.
Setting Physical LED State#
Some keyboard implementations provide convenient methods for setting the state of the physical LEDs.
Ergodox Boards#
The Ergodox implementations provide ergodox_right_led_1/2/3_on/off() to turn individual LEDs on or off, as well as ergodox_right_led_on/off(uint8_t led) to turn them on or off by their index.
In addition, it is possible to specify the brightness level of all LEDs with ergodox_led_all_set(uint8_t n); of individual LEDs with ergodox_right_led_1/2/3_set(uint8_t n); or by index with ergodox_right_led_set(uint8_t led, uint8_t n).
Ergodox boards also define LED_BRIGHTNESS_LO for the lowest brightness and LED_BRIGHTNESS_HI for the highest brightness (which is the default).