← More about keyboards

Overview

QMK’s RGB Matrix Lighting is flexible, with finely tunable brightness using the RM_VALU and RM_VALD keys … But it’s too much! These tuning knobs are unwieldy. Functionally, I want some backlighting to help find the keys at a dim or strong level depending on my environment. Aesthetically, I want lighting that looks good without being distracting.

Lumino implements a minimal, opinionated control scheme for RGB matrix lighting:

This scheme is born from my personal use, but perhaps this appeals to you too. Brightness levels and other above details are configurable.

Add Lumino to your keyboard

Install my community modules. Then enable module getreuer/lumino in your keymap.json file. Or if keymap.json does not exist, create it with the following content:

{
  "modules": ["getreuer/lumino"]
}

Then use the “LUMINO” keycode somewhere in your layout.

Optionally, Lumino may be used in combination with PaletteFx for custom palette-based lighting effects:

{
  "modules": ["getreuer/lumino", "getreuer/palettefx"]
}

Customization

Brightness levels

Lumino cycles the brightness level between off, LUMINO_LOW_BRIGHTNESS, and LUMINO_HIGH_BRIGHTNESS. The latter two are values between 0.0 (off) and 1.0 (max).

To customize, define them in your config.h. Example:

#define LUMINO_HIGH_BRIGHTNESS  0.8
#define LUMINO_LOW_BRIGHTNESS   0.1

It is expected that LUMINO_LOW_BRIGHTNESS is less than LUMINO_HIGH_BRIGHTNESS for 3-state cycling. If not, the LUMINO key toggles between off and LUMINO_LOW_BRIGHTNESS.

By default, the brightness level set with the LUMINO key is saved persistently to EEPROM. To tell Lumino to never write to EEPROM, define LUMINO_NO_EEPROM:

#define LUMINO_NO_EEPROM

Times are configured in units of milliseconds.

Define them in config.h to customize. For longer times, you may find it convenient to express them as (1000 * <seconds>) or (1000 * 60 * <minutes>) for tuning in units of seconds or minutes rather than milliseconds. Example:

#define LUMINO_LONG_TIMEOUT  1000 * 60 * 5  // = 5 minutes.
#define LUMINO_SOON_TIMEOUT  1000 * 12      // = 12 seconds.
#define LUMINO_TRANSITION    750            // = 750 ms.

Another example, where lighting never turns off:

#define LUMINO_LONG_TIMEOUT  0              // Never time out.
#define LUMINO_SOON_TIMEOUT  0              // Never time out.
#define LUMINO_TRANSITION    500            // = 500 ms.

Boot color

⚠  Experimental

I don’t know whether boot color works with all keyboards. It relies on the lighting PWM driver continuing to run while in DFU mode, which seems iffy. I’ve tested that it works on the ZSA Moonlander and Voyager keyboards.

When the QK_BOOT button is pressed for bootloader mode, the lighting is set to RGB color LUMINO_BOOT_COLOR. The default color is RGB_RED. Another RGB color such as one in this list may be specified as:

#define LUMINO_BOOT_COLOR  RGB_WHITE

Or use RGB_OFF to turn lighting off when going to bootloader mode:

#define LUMINO_BOOT_COLOR  RGB_OFF

Functions

These functions may be used to interact with Lumino programmatically:

void lumino_cycle_3_state(void);
uint8_t lumino_get_value(void);
void lumino_set_value(uint8_t new_value);
void lumino_sleep_soon(void);

Function lumino_cycle_3_state() cycles the brightness between 0, LUMINO_LOW_BRIGHTNESS, and LUMINO_HIGH_BRIGHTNESS. Call this function to invoke the same effect as the LUMINO key within a macro, tap dance, etc.

The lumino_get_value() function returns the current Lumino brightness level as a uint8_t value between 0 and RGB_MATRIX_MAXIMUM_BRIGHTNESS. The corresponding function lumino_set_value(value) sets the value.

// Set brightness to 100%.
lumino_set_value(RGB_MATRIX_MAXIMUM_BRIGHTNESS);

Function lumino_sleep_soon() tells Lumino to go to sleep after LUMINO_SOON_TIMEOUT, provided that few keystrokes occur in that time. This is useful to hint that the keyboard will likely go idle soon after using a certain key, say when a lock screen keycode has been pressed:

bool process_record_user(uint16_t keycode, keyrecord_t* record) {
  switch (keycode) {
    case G(KC_L):
      // Hint Lumino to sleep soon after lock screen GUI+L key is used.
      lumino_sleep_soon();
      return true;  // Continue default handling.
  }
  return true;
}

With the above, if G(KC_L) is pressed and followed by at most 5 key taps, the keyboard is considered idle and lighting will go to sleep after the “soon” timeout. If, however, G(KC_L) is followed by more than 5 keys, then the keyboard is not idle and the “long” timeout applies as usual.

Implementation notes

← More about keyboards