🎛️

GL516互換でロータリーエンコーダ搭載なキーボードのファームウェアを作る

2023/02/16に公開

この記事が何であるか

GL516デザインガイドをベースに、エンコーダ対応、特に、エンコーダの割り当てをRemapから変更したい場合の変更点・追加点を列挙していきます。そのため、ここで記述されていない部分についてはGL516デザインガイドを参照してください。
https://zenn.dev/salicylic_acid3/books/gl516_design_guide

この記事が何ではないか

  • キーボード設計の話ではありません。
  • Specificなキーボードの話ではありません。
  • GL516互換ファームウェアを1から作ると言う話ではありません。
  • エンコーダ以外の追加機能については一切触れません。
  • BMPを利用する場合の設定方法については今のところ触れていません。
BMPについて

こちらは筆者の都合で申し訳ありませんが、BMPを利用したことがないため「Chapter 09 BMP用の設定ファイルを作成する」の部分については解説を用意できません…何かの拍子に書けそうだったら追記しておきます。

読み方

この記事はすでに「GL516互換でロータリーエンコーダ搭載なキーボード」をつくることを決めていて、これから作り始めるという段階でGL516デザインガイドと並行して読み進めることを想定しています。各Chapterや節の番号はGL516デザインガイドのものと対応しているので、対応する部分まで来たらこちらに戻ってくるような感じで利用してみてください。

Chapter 03 キーレイアウトを検討する

1. Keyboard Layout Editorでキーレイアウトを検討する

レイアウト検討の段階で、エンコーダをどこに置くか・番号割り振りをしておきます。

通常キーの配置

プッシュ付きエンコーダを利用する場合、通常キーのマトリクスにエンコーダのプッシュボタンをキーとして含めておくと便利です。
この記事では例として、左右に分かれた48キーと、中央にプッシュ付きエンコーダ三つを実装します。
KLEでの通常キーの配置
Download JSONでダウンロードしたファイル(名前を変更していなければkeyboard-layout.json)をコピーし、別名を付けておきます。

エンコーダ用のダミーキーの配置

別名を付けたほうのファイルをさらに編集していきます。
プッシュ付きエンコーダのボタン(プッシュ付きでない場合、エンコーダを置きたい場所)の近くに、エンコーダ一つにつき二つのキーを置きます。これはエンコーダの左回転・右回転にそれぞれ対応し、のちにキーマップを保存するためのダミーキーになります。
エンコーダ用ダミーキーの配置
画像では半分の幅になっていますが通常の幅でも構いませんし、左右に置かず上下や横並びにおいても構いません。各エンコーダに二つずつあることが大事です。

Chapter 04~Chapter 07

エンコーダ部分に通常キーではなくエンコーダを利用する以外、特に変更点はありません。
回路及び基板はこの記事の範疇外なので、参考資料を貼るにとどめます。
https://25keys.com/2021/12/15/rotary_encoder/
https://scrapbox.io/self-made-kbds-ja/ロータリーエンコーダ
https://qiita.com/Ninagawa_Izumi/items/d2792b10c4860d41a88a

Chapter 08 QMKファームウェアを作成する

本番です。

8. VIA用JSONファイルを作成する

順番が前後しますが、こちらの一部を先にやったほうが都合がよいので途中まで進めていきます。

KLEでキーレイアウトを作成する

エンコーダ用のダミーキーの配置で編集したキーマップをさらに編集し、各キー(エンコーダ用のキー含む)にマトリクス番号を記入します。
通常キー及びエンコーダのプッシュスイッチ部分には、回路図においてどのRow、Colにつながっているかを確認し、Row,Colの順で記入します。ダイオードが上向きになっている部分につなげるスイッチについてのみ、Rowを5増やした値を利用します。(画像右側など)
通常キーのマトリクス番号
エンコーダの左右回転に対応するダミーキー部分には、回路図作成時に削除したキーのRow、Colの組み合わせを選び記入します。左右が連番になる必要はありませんが、選ぶ余裕があるなら連番のほうが後々わかりやすいです。
ダミーキーのマトリクス番号

5. config.hを編集する

キーマトリクスのサイズを変更する

MATRIX_ROWS・MATRIX_COLSには、VIA用JSONにてエンコーダ用ダミーキーに割り振ったRow・Colも含めた数を記入します。
MATRIX_ROW_PINS・MATRIX_COL_PINSでは、行数or列数を減らした かつ、減らした行or列をエンコーダ用ダミーキーに割り振った場合のみ、該当する行or列だけNO_PINを指定します。
MATRIXピン

NO_PINを指定するパターンと指定する方法

今回の例ではここをカバーできませんでしたが、例えばプッシュ非対応のエンコーダを使うとKLEはこのようになります。
プッシュなしエンコーダの場合
Row通常スイッチ部分にRow4/9がいないため、回路図上では行数が減ります。この場合、MATRIX_ROW_PINSは以下のようになります。

#define MATRIX_ROW_PINS { D1, D0, D4, C6, NO_PIN }

エンコーダのパッドを定義

もとのconfig.hには書いていない、エンコーダ用の定義を追加していきます。
各エンコーダの、AのパッドがつながるピンをENCODERS_PAD_Aに、BのパッドがつながるピンをENCODERS_PAD_Bにそれぞれ列挙していきます。
ENCODERS_PAD
のちのエンコーダの処理ではここに書いた順番で認識されます。

6. 元template.hを編集する

LAYOUTマクロの後半を編集する

エンコーダ用ダミーキーも含め利用しているキーのみ残して、削除したキーをKC_NOに変更します。

LAYOUT後半の行・列を削除する

デザインガイドでは解説されていませんが、左右ともにColを削っている場合やRowを削っている場合など、行or列まるごとKC_NOになる場合があります。列の場合は丸ごと削除、行の場合はL4x・R4x両方が丸ごとKC_NOの場合のみ両方の行を合わせて削除する必要があります。
今回の例では列を二つ削除する必要がありました。
削除する前のLAYOUT後半

LAYOUTの後半部分

7. キーマップを編集する

キーマップそのものについては特に注意することはないと思います。ダミーキーの部分にはエンコーダを回したときのものを書いておきましょう。
キーマップ例

エンコーダの処理を実装

keymap.cの下部に、以下のコードを追加します。

keymap.c
bool encoder_update_user(uint8_t index, bool clockwise){
  keypos_t key;//keymapsから抜き出すキーを指定する構造体
  if(index==0){//一つ目のエンコーダ
    if(clockwise){//時計回りに回したとき、
      key.row=4,key.col=1;//[4,1]のキー(例ではKC_PGDN)
    }else{
      key.row=4,key.col=0;//[4,0]のキー(KC_PGUP)
    }
    tap_code(keymap_key_to_keycode(layer_switch_get_layer(key),key));
  }
  if(index==1){//二つ目のエンコーダ
    if(clockwise){//時計回りに回したとき、
      key.row=4,key.col=3;//[4,3]のキー(KC_VOLD)
    }else{
      key.row=4,key.col=2;//[4,2]のキー(KC_VOLU)
    }
    tap_code(keymap_key_to_keycode(layer_switch_get_layer(key),key));
  }
  if(index==2){//三つ目のエンコーダ
    if(clockwise){//時計回りに回したとき、
      key.row=4,key.col=5;//[4,5]のキー(KC_AGIN)
    }else{
      key.row=4,key.col=4;//[4,4]のキー(KC_UNDO)
    }
    tap_code(keymap_key_to_keycode(layer_switch_get_layer(key),key));
  }
  /*↓必要であれば以下をコピーし、必要事項を書き加えて増やしていく↓
  if(index==  ){//エンコーダの番号を記入
    if(clockwise){//時計回りに回したとき、
      key.row=  ,key.col=  ;//[  ,  ]のキー マトリクス上のRow,Colを記入
    }else{
      key.row=  ,key.col=  ;//[  ,  ]のキー マトリクス上のRow,Colを記入
    }
    tap_code(keymap_key_to_keycode(layer_switch_get_layer(key),key));
  }
  ↑ここまでコピーして増やす↑*/
  return false;
}

【追加作業】デザインガイドで触れていないファイルの編集

追加で編集する必要のあるファイルがあります。

rules.mk

以下の一行を追記します。

rules.mk
ENCODER_ENABLE = yes		# エンコーダの有効化

元template.c

下部に以下の関数を追記します。

template.c
bool encoder_update_kb(uint8_t index, bool clockwise) {
    return encoder_update_user(index, clockwise);
}

終わりに

以上でデザインガイドと異なる部分はおしまいです。
一部大きなコードを書く必要はありますが基本的にコピペで対応できるので、ぜひエンコーダ対応のGL516互換キーボードを作成してみてください。

この記事はcocot46plus 試作基板 with alpaca switchで書きました。

Discussion