自作キーボード”Tenalice-ambidextrous”について(その2)

はじめに

自作キーボード"Tenalice-ambidextrous(テナリス-アンビデクストラス)”の不具合修正とLEDを搭載したことに関する記事です。またそのLEDを最大に活かすアクリル積層ケースについてもご紹介させていただきます。

本キーボード自体の特徴や設計経緯などは過去のこちらの記事をご参照ください。

cerbekos00.hatenablog.com

目次

1.Ver2による変更点の概要

Ver1を頒布して以降、うれしいことにご購入いただいた方の投稿写真やブログなどを目にする機会に恵まれました。世に出して良かったと思ったのも束の間、残念ながらいくつかの不具合も見つかることとなりました。今回のVer2ではそれら見つかった不具合の修正を実施いたしました。また、ご購入いただいた方の投稿写真などで刺激を受けた結果、機能追加としてLEDを搭載することにしました。

2.不具合の修正(3点)

2-1.REF**の削除

”REF**”とは、私の中では思い出深い、Ver1設計時にフットプリントの消し忘れによって出来てしまったこちら(左の写真)のことです。今回ついに”REF**の悪夢”から解放されました!

f:id:Cerbekos00:20211030115002j:plain
f:id:Cerbekos00:20211231124659j:plain
左:Ver1.0、右:Ver2.0

2-2.スペーサー穴の調整

Ver1.0では、一部のスペーサー穴にスペーサーが入りずらいという問題が発覚しました。購入者様の方でも、あの手この手で広げていただいた様子で申し訳ないです。全て同じフットプリントを使用していたのですが、製造誤差なのかそういうものなのか、だいたい入らないのは中央テンキーの上下のスペーサーだったようです。
今回対策として、使用していた”M2_Hole_TH_Outside”のパッドのプロパティより、サイズを4mmから4.15mmへ広げました。

f:id:Cerbekos00:20211231131040p:plain

2-3.スタビライザー穴、スイッチ穴の調整

Ver1.0では、Plate & Case Builder - swillkbでトッププレートの元となるデータをDXFで生成し、DXFデータをKicadへ取り込み、その外形線に基づいてスイッチ穴やスタビライザー穴を作成していました。ですが使用するスタビライザーによっては入らないことや、スイッチ穴についてもかなりキツめで取り外ししにくいという問題がありました。
今回対策として、それぞれ穴の大きさを広げる調整を行いました。

f:id:Cerbekos00:20220105210736p:plain

f:id:Cerbekos00:20220105211110p:plain

上:Plate&Case Builder、下:修正後のkicad

見つかった不具合と修正の内容は以上です。これらはVer2のPCBやトッププレートの実物で、修正された点に問題がないことを確認いたしました。

3.機能追加(LED)

アクリル積層とLEDグラデーションがマッチした美しい写真を見たことですっかりLEDに魅入られてしまい、この度めでたくLEDを搭載する運びとなりました。このLEDにはいろいろ手間をかけたのでたっぷり紹介させていただきます。

3-1.LED配置の方針

まずはLED配置の方針から。LEDには、スイッチ側を照らすバックライトとPCB底面側に照らすアンダーグローの2種類があります。アクリル積層ケースとの相性の良さからアンダーグローは絶対つけたいと思っていました。先行でLEDを搭載していた”Ambi-MINI"のアンダーグローの光り方を参考にLEDの配置間隔を検討していきました。その結果LED数を17個(奥側5/左右4/手前8)に決定しました。

f:id:Cerbekos00:20211211220957j:plain

Ambi-MINI"のアンダーグロー

続いてバックライトについての検討です。バックライトはスイッチひとつひとつにLEDが割り当てられてスイッチが光るというのが基本です。そのほかインジケータとしてLEDが直接/間接的に見えるようにするケースなどがあります。
今回”Tenalice-ambidextrous”では、中央テンキーのみバックライトという一風変わった仕様にしてみました。中央テンキー部分は13スイッチありますので、バックライトLEDは13個です。

3-2.配線の検討

使用するLEDは”Ambi-MINI”の時と同じ”SK6812MINI-E”とすることを前提にしていたため、シリアル接続による配線となります。ProMicroのLEDピンより近い位置である1番よりぐるっと一周してアンダーグローを配置し、中央テンキーへ降りてくるような配線としました。

f:id:Cerbekos00:20220105225631j:plain

アンダーグロー

f:id:Cerbekos00:20220105225657j:plain

バックライト

この配線の場合、中央テンキーとアンダーグローがひとつなぎとなるため、それぞれで異なるアニメーションが使用できないことに気づきました。QMKドキュメントを調べてみたところ、異なる複数のLEDグループを作成してアニメーションをそれぞれで制御するような機能を見つけることができませんでした。
それほど大きな問題でもないため、このまま実装することにしました。

3-3.RGB LightingとRGB Matrix

次はLEDの制御に関する検討です。"QMK Firmware Docs"を参考しながらLEDの制御方法について調べていくと、"RGB Lighting"と"RGB Matrix"の2つがあることに気が付きました。これらの違いについて、私は、"RGB Lighting"がアンダーグロー用、"RGB Matrix"がバックライト用と理解しました。("RGB Matrix"は、LEDと各スイッチについて、位置で紐づけたり、モディファイアキーなどのキーの役割で紐づけるので)
今回は、実装方法の簡便さを踏まえ"RGB Lighting"による制御を行うことにしました。

docs.qmk.fm

3-4.LED順序の変更

既定の設定ではLEDは配線で接続された順番に番号が振られて管理されますが、そのLEDの順番は変えることができます。(LEDに対して、基板上の物理的効率のよい配線と、ソフトウェア的に点灯させたい順序が一致しないことを前提としているので)
基板上の効率が良いかどうかはさておき、中央テンキー部分の点灯順序は左の写真の通りです。これを管理する順番を変えて、うずまきを描くよう並び替えることにしました。

f:id:Cerbekos00:20220105225657j:plain
f:id:Cerbekos00:20220106225557j:plain
左:基板上のLEDのシリアル接続の順番、右:並び替え後

この定義は"config.h"に”RGBLIGHT_LED_MAP”として記述します。

#define RGBLIGHT_LED_MAP {0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,\
    17,28,27,18,29,26,25,19,20,23,24,21,22}

3-5.レイヤーインジケータ

レイヤーインジケータは、現在のレイヤーが何であるかをLEDの色によって示す機能です。VIA(Remap)に準拠したキーボードでは、デフォルトレイヤーに加えて最大3つまでレイヤーを持たせることができますので、この3つのレイヤーにそれぞれLEDを設定します。
”config.h”に”RGBLIGHT_LAYERS”を定義し、”keymap.c”に点灯させるLEDを設定したレイヤを定義することで、LEDアニメーションを中断することなく、レイヤーに合わせて設定したLEDを点灯させることができます。

例えば、レイヤー1にしたとき、中央テンキーをハート型に赤色で点灯させる場合は、次のような定義を”keymap.c”に記載します。

//レイヤ1で点灯させるのLEDの設定
const rgblight_segment_t PROGMEM my_layer1_layer = RGBLIGHT_LAYER_SEGMENTS(
  {7, 2, HSV_RED},
  {16, 1, HSV_RED},
  {17, 1, HSV_OFF},
  {18, 3, HSV_RED},
  {21, 2, HSV_OFF},
  {23, 1, HSV_RED},
  {24, 2, HSV_OFF},
  {26, 5, HSV_RED}
);
//RGBLIGHT_LAYERS_LISTに格納
const rgblight_segment_t * const PROGMEM my_rgb_layers
= RGBLIGHT_LAYERS_LIST(
    my_layer1_layer
);

//セットアップ時のrgblight_layersにリストを割り当て

void keyboard_post_init_user(void) {
    rgblight_layers = my_rgb_layers;
};

//レイヤーの状態変化に応じてリストからレイヤを割り当て

layer_state_t layer_state_set_user(layer_state_t state) {

    rgblight_set_layer_state(0, layer_state_cmp(state, 1));
    } 
    return state;
};

3-6.LOCKインジケータ

レイヤー同様、CAPSLOCKやNUMLOCKもQMKでは状態管理されており、その状態を取得することでレイヤーインジケータと同じような振る舞いをさせることができます。ロック状態であるかどうかを取得する方法は3つほどあるようですが、私は”led_state”を見る方法で実装しました。

docs.qmk.fm

//led_stateよりNUMLOCKの状態を取得し、NUMLOCKで"ない"ならリストからレイヤを割り当て

bool led_update_kb(led_t led_state) {
    bool res = led_update_user(led_state);
    if(res) {
      rgblight_set_layer_state(0, !led_state.num_lock);
      }
    return res;
};

私の場合、NUMLOCK状態、つまりテンキーが使える状態がデフォルトのため、非NUMLOCKになればインジケータを点灯させています。

レイヤーと合わせると、インジケータは全5色となります。

f:id:Cerbekos00:20220110231029j:plain
f:id:Cerbekos00:20220110231041j:plain
f:id:Cerbekos00:20220110231054j:plain
f:id:Cerbekos00:20220110231120j:plain
f:id:Cerbekos00:20220110231105j:plain
左からL1,L2,L3,CAPSLOCK,NUMLOCK

3-7.インジケータのオン/オフ

LOCKインジケータで言及したNUMLOCK/非NUMLOCKのいずれがデフォルトの状態であるかは、人によって変わることとなります。このためNUMLOCKインジケータについては、NUMLOCK中/非NUMLOCK中/オフの3つ状態を切り替えれるような実装を行いました。また、そのほかのインジケータはオン/オフを切り替えれるような実装を行いました。

ここで、インジケータのオフの状態を定義するLEDについては注意が必要で、単純にインジケータ対象のLEDをオフ(rgblight_sethsv_range(HSV_OFF, 21, 5))してしまうと、通常時のアニメーションも点灯しなくなってしまいます。またもっと悪いことに、インジケータの色がそのまま残ってしまうという状態になります。
試行錯誤した結果、存在しないLEDを設定するといういわば”空LED設定”により実装することができました。

//存在しない90番目のLEDをHSV_OFFに設定(空設定)

const rgblight_segment_t PROGMEM my_layerNone_layer[] = RGBLIGHT_LAYER_SEGMENTS(
  {90, 1, HSV_OFF}
);

これをmy_rgb_layersに入れておき、インジケータのオン/オフを判定した結果で呼び出すレイヤを切り替えるようにします。オン/オフの判定はF21~F23キーに割り当てることにしました(process_record_userで実装)。
ついでにオン/オフでは”Lighting layer blink”を用いて視覚的に変わったことをフィードバックするようにしました。

bool process_record_user(uint16_t keycode, keyrecord_t *record) {
  switch (keycode) {
     // num_lock indicator mode switching
    case KC_F22:
      if (record->event.pressed) {
        return false;
      } else {   //キーがリリースされたとき
        layer_state_set(0);
        switch (NL_range_mode) {  //NUMLOCKモードの判定
          case 0: 
            NL_range_mode = 1; //次のNUMLOCKモードへ
            rgblight_blink_layer_repeat(6, 200, 2); //my_rgb_layersに格納されている7番目のレイヤを2回光らせる
            return false; //F22のキーコードは送らない
          case 1:
            NL_range_mode = 2;
            rgblight_blink_layer_repeat(6, 200, 3);
            return false;
          case 2:
            NL_range_mode = 0;
            rgblight_blink_layer_repeat(6, 200, 4);
            return false;
          default:
            return false;
        }
      }

3-8.アンダーグローのオン/オフ

いろいろLEDを触っていると、RGBLightingのアニメーションによっては、中央テンキーのLEDのみを点灯させることでカラフルな色味を集約する(アンダーグローに色を取られないようにする)ほうが綺麗だと感じるものがありました。

f:id:Cerbekos00:20220110231254j:plain
f:id:Cerbekos00:20220110231303j:plain
左:アンダーグローあり、右:アンダーグローなし

ということでアンダーグローをオフにするモードを搭載しました。こちらはレイヤーインジケータ類と異なり、単純にLEDの範囲設定を中央キーのみにすることで実現できます。F24キーを押下することでオン/オフを切り替えます。

bool process_record_user(uint16_t keycode, keyrecord_t *record) {
  switch (keycode) {
    // Backlight range mode switching
    case KC_F24:
      if (record->event.pressed) {
        return false;
      } else {
        layer_state_set(0);
        switch (bl_range_mode) {
          case 0:
            rgblight_set_effect_range(17, 13);
            rgblight_sethsv_range(HSV_OFF, 0, 17);
            rgblight_blink_layer_repeat(6, 200, 2);
            bl_range_mode = 1;
            return false;
          case 1:
            rgblight_set_effect_range(0, 30);
            rgblight_blink_layer_repeat(6, 200, 3);
            bl_range_mode = 0;
            return false;
          default:
            return false;
        }
      }

...

サンドイッチケースの場合は特に中央キーのみバックライトモードはなかなか良い気がしました。

f:id:Cerbekos00:20220110232414j:plain

3-9.ボトムプレートのスリット追加

”Ambi-MINI”で背面にスリットを入れてみたところ、LEDの見え方個人的に良かったと感じたのでこちらにも追加してみました。いい感じですが上方のスリットは無くてもいいかなという印象です(左右非対称ですし)。あとはもう数ミリスリットは長いほうが良さそう。

f:id:Cerbekos00:20220110231616j:plain

f:id:Cerbekos00:20220110232019j:plain

3-10.LED関係のキーマップ

LED関係のキーマップはLayer2に配置してみました。

4.アクリル積層ケースについて

過去に私が設計したアクリル積層ケースでも組んでみました。アクリルはクリア素材のダークグレーですが、LEDとの相性はやはり良い感じでした。

f:id:Cerbekos00:20220110233240j:plain

背面は基板が透けて見えるのがお気に入り。相変わらず彫刻した文字は見えませんが。

f:id:Cerbekos00:20220110084609j:plain

中央テンキーに透明のアルチザンキーキャップを置くと映えます。

f:id:Cerbekos00:20220110084549j:plain

上記で使用しているアクリル積層ケースの詳細はこちらをご参照ください。

cerbekos00.hatenablog.com

また、なんとあの"キムラシンショクバ(@zettai3_reido)"さんが"Tenalice-Ambidextarous"向けに新たなアクリル積層ケースを設計し、そのデータの公開を計画されています!

そのケースについての特徴や使用感についてまとめました!が、ボリュームが多くなったので別の記事にしています。ぜひご覧ください。

cerbekos00.hatenablog.com

おわりに

LEDにこだわりをいっぱい詰め込みました。LEDの実装のためにQMK Firmwareのドキュメントをたくさん追いかけることになりましたが、そのおかげでこれまでの表面的な部分の理解だけでなく、より深いQMKの内容を知ることができました。またQMK Docsの追いかけ方が分かったことで、Docs内の他の様々なトピックを見れるようになったことは、私自身にとって大きな収穫だったように思います。

それでは良いキーボードライフを。

f:id:Cerbekos00:20220110233109j:plain