はじめに
RGB MATRIX の LED にインジケータの機能を持たせようとするとちょっと面倒だったので、いい感じに制御するコードを書きました。
- はじめに
- 公開場所
- 使い方
- レイヤーインジケータについて
- キーコードについて
- API
- void rgb_matrix_indicator_init(void)
- void eeconfig_init_rgb_matrix_indicator(void)
- void disable_rgb_effect(void)
- bool process_record_rgb_matirx_indicator(uint16_t keycode, keyrecord_t *record)
- void update_layer_indicator(uint8_t layer_state)
- void update_indicators(led_t led_state)
- void layer_indicator_set_hsv(uint8_t hue, uint8_t sat, uint8_t val)
- void numlock_indicator_set_hsv(uint8_t hue, uint8_t sat, uint8_t val)
- void numlock_indicator_off(void)
- void capslock_indicator_set_hsv(uint8_t hue, uint8_t sat, uint8_t val)
- void capslock_indicator_off(void)
- void scrolllock_indicator_set_hsv(uint8_t hue, uint8_t sat, uint8_t val)
- void scrolllock_indicator_off(void)
- void compose_indicator_set_hsv(uint8_t hue, uint8_t sat, uint8_t val)
- void compose_indicator_off(void)
- void kana_indicator_set_hsv(uint8_t hue, uint8_t sat, uint8_t val)
- void kana_indicator_off(void)
- VIA 対応について
- おわりに
公開場所
以下で公開しています。
https://github.com/koktoh/rgb_matrix_indicatorgithub.com
使い方
基本的に、上記のリポジトリにある example_xxxx
系のファイルを見れば何となくわかると思います。
ファイルの配置
<keyboard>
ディレクトリに rgb_matrix_indicator
をコピペします。
<keyboard> │ config.h │ keyboard.json │ readme.md │ rules.mk │ ├─keymaps │ └─default │ keymap.c │ └─rgb_matrix_indicator rgb_matrix_indicator.c rgb_matrix_indicator.h
config.h の記述
RGB_INDICATOR_EEPROM_CONFIG_ADDR の設定
独自の設定を EEPROM に保存しているので、それ用の設定です。
これがないと動かないので、そのままコピペしてください。
#ifdef DYNAMIC_KEYMAP_ENABLE # ifdef VIA_ENABLE # define DYNAMIC_KEYMAP_EEPROM_ADDR (VIA_EEPROM_CONFIG_END) # else // VIA_ANABLE # define DYNAMIC_KEYMAP_EEPROM_ADDR (EECONFIG_SIZE) # endif // VIA_ENABLE # define DYNAMIC_KEYMAP_EEPROM_MAX_ADDR (TOTAL_EEPROM_BYTE_COUNT - 1) # define DYNAMIC_KEYMAP_LAYER_COUNT 4 # define DYNAMIC_KEYMAP_ENCODER_EEPROM_ADDR (DYNAMIC_KEYMAP_EEPROM_ADDR + (DYNAMIC_KEYMAP_LAYER_COUNT * MATRIX_ROWS * MATRIX_COLS * 2)) # ifdef ENCODER_MAP_ENABLE # define DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR (DYNAMIC_KEYMAP_ENCODER_EEPROM_ADDR + (DYNAMIC_KEYMAP_LAYER_COUNT * NUM_ENCODERS * 2 * 2)) # else // ENCODER_MAP_ENABLE # define DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR (DYNAMIC_KEYMAP_ENCODER_EEPROM_ADDR) # endif // ENCODER_MAP_ENABLE # define DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE (DYNAMIC_KEYMAP_EEPROM_MAX_ADDR - DYNAMIC_KEYMAP_MACRO_EEPROM_ADDR + 1) # define RGB_INDICATOR_EEPROM_CONFIG_ADDR (DYNAMIC_KEYMAP_MACRO_EEPROM_SIZE) #else // DYNAMIC_KEYMAP_ENABLE # define RGB_INDICATOR_EEPROM_CONFIG_ADDR (EECONFIG_SIZE) #endif // DYNAMIC_KEYMAP_ENABLE
LED の設定
以下のインジケータとして使用する LED のインデックスを設定します。
- レイヤー
- Num Lock
- Caps Lock
- Scroll Lock
- Compose
- Kana
define
されない場合、各インジケータは表示されません。
インジケータとして不要であれば、 define
しないでおけば OK です。
XXXX_INDICATOR_LED_INDEX
と XXXX_INDICATOR_LED_INDEXES
のどちらかだけを define
してください。
1つの LED をインジケータとして使用する
一番普通の使い方だと思います。
設定されたインデックスの LED が、そのインジケータとして使用されます。
#define LAYER_INDICATOR_LED_INDEX 0 #define NUMLOCK_INDICATOR_LED_INDEX 1 #define CAPSLOCK_INDICATOR_LED_INDEX 2 #define SCROLLLOCK_INDICATOR_LED_INDEX 3 #define COMPOSE_INDICATOR_LED_INDEX 4 #define KANA_INDICATOR_LED_INDEX 5
複数の LED をインジケータとして使用する
例えば、「10番目と20番目の LED を Num Lock のインジケータとして使いたい」というときに設定します。(需要があるのかはわからんけど……)
指定されたインデックスの LED は全部同じ色に光ります。
LED はいくつでも指定できます。
#define LAYER_INDICATOR_LED_INDEXES { 0, 1 } #define NUMLOCK_INDICATOR_LED_INDEXES { 2, 3 } #define CAPSLOCK_INDICATOR_LED_INDEXES { 4, 5, 6 } #define SCROLLLOCK_INDICATOR_LED_INDEXES { 7, 8, 9, 10 } #define COMPOSE_INDICATOR_LED_INDEXES { 11, 12 } #define KANA_INDICATOR_LED_INDEXES { 13, 14 }
その他設定
普通の RGB MATRIX とかであるようなやつを揃えています。
#define LAYER_INDICATOR_BASE_COLOR HSV_CYAN // Default is HSV_RED #define LAYER_INDICATOR_STEP 17 // Default is 25 #define INDICATOR_HUE_STEP 4 // Default is 8 #define INDICATOR_SAT_STEP 8 // Default is 17 #define INDICATOR_VAL_STEP 8 // Default is 17 #define INDICATOR_LIMIT_VAL 127 // Default is 255
keymap.c の記述
基本的に example_keymap.c
を見てもらえればわかるかなと思います。
初期化
rgb_matrix_indicator
を初期化します。
EEPROM に保存していた設定を読み込みます。
void keyboard_post_init_user(void) { rgb_matrix_indicator_init(); }
EEPROM リセット
EE_CLR
とかで EEPROM がリセットされた時に、デフォルト値を設定します。
これを書いておかないと EEPROM がリセットされても、 rgb_matrix_indicator
の設定がリセットされません。
void eeconfig_init_user(void) { eeconfig_init_rgb_matrix_indicator(); }
キーコードの処理
これを忘れると rgb_matrix_indicator
用のキーコードの処理がされないので気を付けてください。
bool process_record_user(uint16_t keycode, keyrecord_t *record) { /* ---- とりあえずここにこれを書いておけば OK ---- */ bool p_rgb_indicator = process_record_rgb_matirx_indicator(keycode, record); if (!p_rgb_indicator) { return false; } }
カスタムキーコードを定義する場合は RGB_INDICATOR_SAFE_RANGE
を使用してください。
enum custom_keycodes { CUSTOM1 = RGB_INDICATOR_SAFE_RANGE, CUSTOM2, CUSTOM3, CUSTOM4, } . . . bool process_record_user(uint16_t keycode, keyrecord_t *record) { /* ---- とりあえずここにこれを書いておけば OK ---- */ bool p_rgb_indicator = process_record_rgb_matirx_indicator(keycode, record); if (!p_rgb_indicator) { return false; } /* ---- 別にカスタムキーコードを定義して使う場合は、ここから下に書く ---- */ switch (keycode) { case CUSTOM1: if (record->event.pressed) { // Do something when pressed } else { // Do something else when release } return false; case CUSTOM2: if (record->event.pressed) { // Do something when pressed } else { // Do something else when release } return false; case CUSTOM3: if (record->event.pressed) { // Do something when pressed } else { // Do something else when release } return false; case CUSTOM4: if (record->event.pressed) { // Do something when pressed } else { // Do something else when release } return false; default: return true; // Process all other keycodes normally } }
インジケータの処理
インジケータを更新して正しく光らせるための処理です。
これを忘れると正しく動きません。
簡単な使用
とりあえずこう書いておけば動きます。
bool rgb_matrix_indicators_advanced_user(uint8_t led_min, uint8_t led_max) { update_layer_indicator(get_highest_layer(layer_state | default_layer_state)); update_indicators(host_keyboard_led_state()); return false; }
カスタマイズ
ちょっとカスタマイズしたいと思ったら、以下のように書いてください。
bool rgb_matrix_indicators_advanced_user(uint8_t led_min, uint8_t led_max) { /* ---- レイヤーインジケータのカスタマイズ ---- */ switch (get_highest_layer(layer_state | default_layer_state)) { case _BASE: layer_indicator_set_hsv(HSV_CYAN); break; case _LAYER1: layer_indicator_set_hsv(HSV_MAGENTA); break; case _LAYER2: layer_indicator_set_hsv(HSV_ORANGE); break; case _LAYER3: layer_indicator_set_hsv(HSV_PURPLE); break; default: break; } /* ---- その他インジケータのカスタマイズ ---- */ if (host_keyboard_led_state().num_lock) { numlock_indicator_set_hsv(HSV_AZURE); } else { numlock_indicator_off(); } if (host_keyboard_led_state().caps_lock) { capslock_indicator_set_hsv(HSV_YELLOW); } else { capslock_indicator_off(); } return false; }
レイヤーは update_layer_indicator(uint8_t layer_state)
を使って、他のインジケータは独自で実装する(逆も然り)とかも可能です。
rules.mk の記述
ソースを追加するだけです。
SRC += rgb_matrix_indicator/rgb_matrix_indicator.c
レイヤーインジケータについて
レイヤーのインジケータは少し特殊になっています。
config.h
で以下のように設定しました。
#define LAYER_INDICATOR_BASE_COLOR HSV_CYAN // Default is HSV_RED #define LAYER_INDICATOR_STEP 17 // Default is 25
LAYER_INDICATOR_BASE_COLOR
は、レイヤー0番が選択されているときの LED の色です。
レイヤー1番になると、LAYER_INDICATOR_STEP
の分だけ Hue に加算された色になります。(ウェブとかの HSV のカラーパレットとかでどんな感じか見てもらえれば)
2番ではさらに LAYER_INDICATOR_STEP
の分だけ加算され……というように、自動で色が設定されます。
あまりにもレイヤーが多かったり、 LAYER_INDICATOR_STEP
の値が小さいと、色が一周して違うレイヤーが同じ色になったり、レイヤーが変わっても色の変化が小さすぎてわかりにくくなったりします。
インジケータの処理 の カスタマイズ に書いたように、レイヤーごとに自分で色を設定することもできるので、好みによって変えてください。
キーコードについて
rgb_matrix_indicator
では、RGB MATRIX に関係するキーコードの動作を変更しています
キーコード | 変更前の動作 | 変更後の動作 |
---|---|---|
RGB_TOG |
すべての LED が点灯 / 消灯する | インジケータ以外の LED が点灯 / 消灯する |
RGB_MOD から RGB_M_SW まで |
それぞれの動作 | インジケータ以外の LED が消灯している場合、何も実行されない |
また、独自のキーコードを定義しています。
キーコード | エイリアス | 説明 |
---|---|---|
RGB_INDICATOR_HUE_UP |
RGB_IHI |
インジケータ LED の Hue を加算する |
RGB_INDICATOR_HUE_DOWN |
RGB_IHD |
インジケータ LED の Hue を減算する |
RGB_INDICATOR_SATURATION_UP |
RGB_ISI |
インジケータ LED の Saturation を加算する |
RGB_INDICATOR_SATURATION_DOWN |
RGB_ISD |
インジケータ LED の Saturation を減算する |
RGB_INDICATOR_VALUE_UP |
RGB_IVI |
インジケータ LED の Value (明るさ)を加算する |
RGB_INDICATOR_VALUE_DOWN |
RGB_IVD |
インジケータ LED の Value (明るさ)を減算する |
これらのキーコードによる操作は、レイヤー以外のすべてのインジケータ LED に反映されます。
つまり、 RGB_IHI
を実行すると、 Num Lock も Caps Lock もすべて同じ色に変化します。
RGB_IVI
/ RGB_IVD
はレイヤー含めたすべてのインジケータ LED に反映されます。
API
void rgb_matrix_indicator_init(void)
rgb_matrix_indicator
を初期化する。
void eeconfig_init_rgb_matrix_indicator(void)
rgb_matirx_indicator
の EEPROM 領域をリセットする。
void disable_rgb_effect(void)
インジケータ以外の LED を消灯する。
bool process_record_rgb_matirx_indicator(uint16_t keycode, keyrecord_t *record)
rgb_matrix_indicator
で定義されたキーコードの処理。
void update_layer_indicator(uint8_t layer_state)
レイヤーインジケータ LED の表示を更新する。
void update_indicators(led_t led_state)
レイヤー以外の全インジケータ LED の表示を更新する。
void layer_indicator_set_hsv(uint8_t hue, uint8_t sat, uint8_t val)
レイヤーインジケータ LED を指定した色に設定する。
HSV_RED
などをそのまま使用可能。
val
に INDICATOR_LIMIT_VAL
を超える値が指定された場合、 INDICATOR_LIMIT_VAL
の値が使用される。
void numlock_indicator_set_hsv(uint8_t hue, uint8_t sat, uint8_t val)
Num Lock インジケータ LED を指定した色に設定する。
HSV_RED
などをそのまま使用可能。
val
に INDICATOR_LIMIT_VAL
を超える値が指定された場合、 INDICATOR_LIMIT_VAL
の値が使用される。
これを使用した場合、 RGB_IHI
, RGB_IHD
, RGB_ISI
, RGB_ISD
のキーコードによる変更は反映されない。
RGB_IVI
, RGB_IVD
のキーコードは反映される。
void numlock_indicator_off(void)
Num Lock インジケータ LED を消灯する。
void capslock_indicator_set_hsv(uint8_t hue, uint8_t sat, uint8_t val)
Caps Lock インジケータ LED を指定した色に設定する。
HSV_RED
などをそのまま使用可能。
val
に INDICATOR_LIMIT_VAL
を超える値が指定された場合、 INDICATOR_LIMIT_VAL
の値が使用される。
これを使用した場合、 RGB_IHI
, RGB_IHD
, RGB_ISI
, RGB_ISD
のキーコードによる変更は反映されない。
RGB_IVI
, RGB_IVD
のキーコードは反映される。
void capslock_indicator_off(void)
Caps Lock インジケータ LED を消灯する。
void scrolllock_indicator_set_hsv(uint8_t hue, uint8_t sat, uint8_t val)
Scroll Lock インジケータ LED を指定した色に設定する。
HSV_RED
などをそのまま使用可能。
val
に INDICATOR_LIMIT_VAL
を超える値が指定された場合、 INDICATOR_LIMIT_VAL
の値が使用される。
これを使用した場合、 RGB_IHI
, RGB_IHD
, RGB_ISI
, RGB_ISD
のキーコードによる変更は反映されない。
RGB_IVI
, RGB_IVD
のキーコードは反映される。
void scrolllock_indicator_off(void)
Scroll Lock インジケータ LED を消灯する。
void compose_indicator_set_hsv(uint8_t hue, uint8_t sat, uint8_t val)
Compose インジケータ LED を指定した色に設定する。
HSV_RED
などをそのまま使用可能。
val
に INDICATOR_LIMIT_VAL
を超える値が指定された場合、 INDICATOR_LIMIT_VAL
の値が使用される。
これを使用した場合、 RGB_IHI
, RGB_IHD
, RGB_ISI
, RGB_ISD
のキーコードによる変更は反映されない。
RGB_IVI
, RGB_IVD
のキーコードは反映される。
void compose_indicator_off(void)
Compose インジケータ LED を消灯する。
void kana_indicator_set_hsv(uint8_t hue, uint8_t sat, uint8_t val)
Kana インジケータ LED を指定した色に設定する。
HSV_RED
などをそのまま使用可能。
val
に INDICATOR_LIMIT_VAL
を超える値が指定された場合、 INDICATOR_LIMIT_VAL
の値が使用される。
これを使用した場合、 RGB_IHI
, RGB_IHD
, RGB_ISI
, RGB_ISD
のキーコードによる変更は反映されない。
RGB_IVI
, RGB_IVD
のキーコードは反映される。
void kana_indicator_off(void)
Kana インジケータ LED を消灯する。
VIA 対応について
一応、VIA で使用する EEPROM 領域は侵さないようになっていると思います。(RGB_INDICATOR_EEPROM_CONFIG_ADDR の設定)
しかし、面倒でちゃんとは確認していないので、不具合等があれば、 issue 立てたり X(旧 Twitter) で突っ込んだりしてください。
また、独自キーコードを設定する場合は Any(n)
などで頑張ってください。
おわりに
以上、 RGB MATRIX をいい感じにするコードを書いた報告とその解説でした。
どんな動きするかは実際使ってみて確かめてみてください。
不具合があったり、要望があったらさらに手を入れるかもしれません。
もちろん PR も大歓迎です。