ロータリーエンコーダーを使用した入力デバイスの作り方
はじめに
キーボードにロータリーエンコーダーを搭載する前に、練習としてロータリーエンコーダー単体のデバイスを作成しました。このデバイスを通じて、最新のQMKファームウェア環境でのロータリーエンコーダーの設定方法や、Vial対応の手順、さらには回路図の設計方法について学びましたが、初めて挑戦する方にとって特に悩みが多い部分だと思います。そこで今回の記事では、それぞれのポイントを「やさしく」解説していきます。
対象となる人
エンジニアではない
プログラミングの知識がない
電子工作の知識がない
ロータリーエンコーダーを使用した設計経験がない
Macを使用している(Windowsでも通じる部分はあるかと思います)
必要なもの
Chrome系のWebブラウザ
ターミナル
KiCad
Microsoft Visual Studio Code
大まかな流れ
回路図を作成する
基板とケース設計を行う
QMKファームウェアを作成する
Vial対応を行う
内容が長くなるため、KiCadの操作説明は簡潔にまとめ、QMKファームウェアの解説に重点を置いて進めていきます。
回路図を作成する
今回は、RP2040 Zeroを使用した基板を設計していきます。このボードを採用した理由は、小型サイズにもかかわらず、ResetボタンとBootボタンが搭載されているため、これらのボタンを設計に含める手間が省けますし、価格もそれほど高くないため、とても使いやすいボードだからです。
まずは、KiCadで使用するシンボルやフットプリントのデータを準備します。幸いなことに、先人の方々が作成してくださったデータが公開されていますので、感謝の気持ちを込めてそれらを活用させていただきましょう。
RP2040 Zeroのデータ:is-wateringさん
ロータリーエンコーダーのデータ:koktohさん
緑色の「Code」ボタンをクリックし、Zipファイルをダウンロードします。その後、ダウンロードしたデータをKiCadのシンボルライブラリおよびフットプリントライブラリに追加してください。
ライブラリにデータを追加できたら、回路図エディターを開きます。
以下の画像を参考にしてシンボルを配置して下さい。ラベルの位置などはお好みで大丈夫です。
まだ発注したことがないので、動くのか分からないのですが、キーボードにロータリーエンコーダーを付ける場合は、こんな感じになるかと思います。
基板とケース設計を行う
回路図が完成したら、PCBエディターを開き、フットプリントを配置して配線を行います。
次に、設計した基板をSTEPファイルとして書き出します。そのデータを元に、3D CADソフトを使用してケースやノブを作成していきます。
QMKファームウェアを作成する
説明を省いてきましたが、ここからは「やさしく」いきたいと思います。
まず、QMKファームウェアで新しいキーマップを作成します。作成方法の詳細については、以下の記事の「QMKファームウェアを作成する」セクションも参考にしてください。
次にターミナルを開き、qmk_firmware フォルダに移動します。
「cd」と入力して半角スペースを入れ、続けてフォルダのパスを入力してからEnterキーを押してください。
cd qmk_firmware
以下のコマンドを実行し、新しいキーボード用の設定(キーマップ)を作成します。「xxxx」の部分は作りたいデバイスの名前です。
qmk new-keyboard -kb xxxx
上記のコマンドを実行すると、いくつかの質問が表示されます。それぞれの質問に回答してEnterを押してください。
Your GitHub Username?
→GitHubのアカウント名を入力。アカウントを持っていない場合はネットで使用している名前を入力。Your Real Name?
→ネットで使用している名前を入力。Default Layout?
→「オリジナルのレイアウト」を選ぶ場合、数字で「65」を入力。Is your board using a separate development board, such as a Pro Micro, or is the microcontroller integrated onto the PCB?
→「n」を入力。Microcontroller?
→使用するマイコンに応じて数字を入力。今回はRP2040を使用するので「21」を入力。
すべての質問に答えると、qmk_firmwareフォルダ内のkeyboardsフォルダに、入力した名前のキーボードフォルダが自動的に作成されます。
keyboard.jsonを編集する
Visual Studio Codeでkeyboard.jsonを開きます。
“features” セクション内に以下のコードを追加します。“nkro”: true の行でEnterキーを押して改行し、そこにペーストしてください。その後、“nkro”: trueの末尾に「,」を追加します。
"encoder": true
次に"matrix_pins"セクションの"cols"と"rows"を編集します。回路図を開きRP2040 Zeroのどのピンを使用しているかを確認して下さい。
"cols"はGP28、"rows"はGP27が使用されていますので、以下の画像のように編集します。
恐らくどの位置でも問題ありませんが、"processor"セクションの下に"encoder"セクションを追加します。
"encoder": {
"rotary": [
{ "pin_a": "GP5", "pin_b": "GP4", "resolution": 1 }
]
},
回路図をもう一度確認してみましょう。ロータリーエンコーダーのシンボルの「A」部分には「ro01」のラベルが、「B」の部分には「ro02」のラベルが使用されています。
「ro01」のラベルはRP2040 ZeroのGP05に接続されているため、「“pin_a”: “GP5”」と設定します。「ro02」のラベルはGP04に接続されているため、「“pin_b”: “GP4”」と設定します。
また、「“resolution”: 1」はロータリーエンコーダーを回したときの反応を設定する項目です。例えば、値が「1」の場合はノブを1ノッチ回す前に反応します。「2」にすると1ノッチ回したときに反応し、「3」では1.5ノッチ、「4」では2ノッチ回したときに反応します。好みもありますが、初めて設定する場合は「2」にするのがおすすめです。
最後に"layouts"のセクションですが、今回はレイアウトも何もないので、余計な箇所を削除するだけです。以下の画像を参考に青く囲ったところを削除します。
以上でkeyboard.jsonの編集は終わりです。
keymap.cを編集する
自分のキーボードのフォルダに移動し、keymapsフォルダ内のdefaultフォルダにあるkeymap.cをVisual Studio Codeで開きます。
ここでは、ロータリーエンコーダーを回したときや押し込んだときに、どの入力を実行させるかを設定します。
まず、作業の邪魔なので、以下の画像を参考に青く囲ったところを削除します。
次に、「 { 」の箇所でEnterを押して改行し、以下をコピペします。
[0] = LAYOUT(
KC_A
)
};
「KC_A」と書かれていますが、これはキーコードと呼ばれるもので、キーに割り当てられる入力値を決めるものです。
例えば、KC_Aは「a」が KC_Bだと「b」が入力できるキーコードです。
キーコードについてはこちらを参考にしてください。
この設定項目では、ロータリーエンコーダーを「プッシュ」した時に入力させたい動作を記入して下さい。
また、この後のVial対応の際に必要になりますので、以下の画像を参考に4レイヤー分のキーコードを追加しておきます。
最後にロータリーエンコーダーを回した時の動作を設定します。
最下部にある「 }; 」の行でEnterを押して改行し、以下のコードをペーストします。
#if defined(ENCODER_MAP_ENABLE)
const uint16_t PROGMEM encoder_map[][NUM_ENCODERS][NUM_DIRECTIONS] = {
[0] = { ENCODER_CCW_CW(KC_PAGE_UP, KC_PAGE_DOWN) }
};
#endif
文中に「[0] = { ENCODER_CCW_CW(KC_PAGE_UP, KC_PAGE_DOWN) }」と記載されている部分があります。このキーコードを変更することで、ロータリーエンコーダーを回したときの入力動作を設定できます。
たとえば、現在の設定では「KC_PAGE_UP」と「KC_PAGE_DOWN」が使用されています。これにより、エンコーダーを左に回すとページが上にスクロールし、右に回すとページが下にスクロールする動作になります。必要に応じて、他のキーコードに変更してください。
また、こちらでも以下の画像を参考に、4レイヤー分のキーコードを追加して下さい。
これでkeymap.cの編集は終わりです。
QMKファームウェアをコンパイルする
もしターミナルを閉じたり、別のフォルダに移動してしまった場合は、以下のコマンドを実行してqmk_firmwareフォルダに戻ります。
cd qmk_firmware
下記コマンドをターミナルで実行します。
「xxxx」の部分は自分のキーボードの名前になります。
make xxxx
Vial対応を行う
キーコード書き換えて毎回コンパイルするのは大変なので、最後にVila対応させましょう。
細かい説明は以下も参考にして下さい。
専用のjsonファイルを作成する
まず、Keyboard Layout Editorに遷移し、以下の画像を参考にしながらキーを配置し、文言を入力して下さい。
詳しく説明していきます。
キーの中央に「e」と書かれたキーは、ロータリーエンコーダーが回ったときの動きを表すもので、キーマトリックスには含まれていません。左上の「0,0」「0,1」は、これが1つ目のロータリーエンコーダーだと分かるようにするための番号で、もし2つ目がある場合は「1,0」「1,1」と番号を付けます。
下の「0,0」と書かれたキーは、ロータリーエンコーダーを押したときに反応するキーです。これはキーマトリックスに含まれます。今回はロータリーエンコーダーだけのデバイスなので「0,0」としていますが、キーボードに組み込む場合は、そのキーの位置に合った番号を入力します。
キーの配置と入力が完了したら、Raw dataタブ内の「Download JSONボタン」をクリックし、JSONファイルをダウンロードします。
次に、Visual Studio Codeで新しいページを作成します。新しいページを作成すると、右下に「プレーンテキスト」と表示されているはずです。このままでは、これから行う作業に支障が出る可能性があるため、作業に適した言語モードに切り替える必要があります。
以下の画像を参考に、赤枠で囲んだ箇所をクリックしてください。
すると、VSC中央に言語モードの選択というウィンドウが表示さます。多くの言語モードがありますが、その中から「JSON(json)」を選択します。
作成した新しいページに以下の文言をコピペして下さい。
{
"lighting": "none",
"matrix": {
"rows": 0,
"cols": 0
},
"layouts": {
"keymap":
}
}
先ほどダウンロードしたJSONファイルをVisual Studio Codeで開きます。その後、「“keymap”:」のコロンのところで改行し、開いたJSONファイルの中身を全て貼り付けます。
最後に"matrix"セクション内の「"rows"」と「"cols"」に記載されている「0」を「1」に書き換え、「vial.json」という名前でデスクトップなどに保存します。
作成したvial.jsonファイルの内容が正しいかを確認しましょう。
まずは、公式サイトからVialのソフトウェアをダウンロードします。ダウンロードしたVialを開くと、セキュリティ警告が表示されますので、以下の手順でセキュリティ設定を変更してください。
システム設定を開く
プライバシーとセキュリティを選択する
セキュリティの項目にある「このまま開く」ボタンをクリック
Vialを再度起動する
Vialが開いたら、画面左上のFile内にある、「Load dummy JSON...」をクリックします。
先ほどデスクトップに保存した「vial.jsonファイル」を読み込み、以下の画像と同じレイアウトが表示されれば「vial.json」の完成です。
表示されないキーがある場合、Keyboard Layout Editoで入力した文言が間違っています。例えば「0,0」と入力したつもりが、カンマではなくピリオドになっている可能性が高いです。
必要なファイルを作成する
Vial対応させたいファームウェアが保存されているQMKフォルダ内のキーボードフォルダを、vial-qmkフォルダ内のkeyboardsフォルダにコピーして貼り付けてください。
例
qmk_firmware/keyboards/aaa
「aaa」フォルダをコピー
↓
vial-qmk/keyboards/aaa
Vialの「keyboards」フォルダ内にペースト
コピーしたファイル内にある「keymaps」フォルダを開きます。フォルダ内の空白部分を右クリックし、「新規フォルダ」を選択して、「vial」という名前のフォルダを作成してください。
defaultフォルダ内にあるkeymap.cファイルを、作成したvialフォルダ内にコピーして貼り付けます。
例
vial-qmk/keyboards/aaa/keymaps/default/keymap.c
keymap.cをコピー
↓
vial-qmk/keyboards/aaa/keymaps/vial/keymap.c
vialフォルダにkeymap.cをペースト
先ほどデスクトップに保存したvial.jsonをvialフォルダに移動させます。
ファイルの移動は以上で完了です。
次はrules.mkファイルを作成します。
Visual Studio Codeで新しいページを作成し、以下の内容を貼り付けてください。その後、「rules.mk」と言う名前で、先ほど作成した vialフォルダ内に保存します。
VIA_ENABLE = yes
VIAL_ENABLE = yes
ENCODER_MAP_ENABLE = yes
最後にconfig.hファイルを作成します。
Visual Studio Codeで新しいページを作成し、以下の内容を貼り付けてください。
/* SPDX-License-Identifier: GPL-2.0-or-later */
#pragma once
ターミナルを開き、cdコマンドでVialフォルダーに移動してから以下のコマンドを実行して固有のキーボードIDを作成します。
python3 util/vial_generate_keyboard_uid.py
以下のような結果が表示されますので、内容をコピーし、先ほどVisual Studio Codeで編集したファイルの「#pragma once」の下に貼り付けてください。ランダムな数字になりますので、「xx」の部分は実際の文言と異なります。
#define VIAL_KEYBOARD_UID {0xXX, 0xXX, 0xXX, 0xXX, 0xXX, 0xXX, 0xXX, 0xXX}
最後にロック解除の組み合わせを設定します。
ロック解除の組み合わせとは、悪意を持って勝手にキーボードの重要な設定を変更されるのを防ぐため、特定のキーを押す組み合わせを設定してVialを保護する仕組みです。
まずは、以下の内容を「#define VIAL_KEYBOARD_UID」の下に貼り付けます。
#define VIAL_UNLOCK_COMBO_ROWS {0, 1}
#define VIAL_UNLOCK_COMBO_COLS {0, 1}
このコードをよく見ると、ROWS {0, 1} と COLS {0, 1} と指定されています。例えば、これは、キーボードを作成する際にKeyboard Layout Editor で入力した Row(行)と Col(列)の値を指しています。
少し分かりにくいかもしれませんが、この場合、ROWS と COLS のどちらも「0,1」と設定されているため、1つ目のキーは「0行0列(0,0)」、2つ目のキーは「1行1列(1,1)」です。ですので、ロック解除キーは以下の画像にある白いキーになります。、
今回はプッシュスイッチしかキーがありませんので、取り合えず以下のように指定しておきます。
#define VIAL_UNLOCK_COMBO_ROWS {0, 0}
#define VIAL_UNLOCK_COMBO_COLS {0, 0}
ここまで進むと、Visual Studio Codeのページ内は以下のようになっているはずです。問題がなければ、「config.h」と言う名前でvialフォルダに保存します。
最後にvialフォルダの中身を確認しましょう。以下の画像のようにファイルあ揃っていれば完了です。
vial対応したファームウェアをコンパイルする
まずは、ターミナルで下記のコマンドを実行し、vial-qmkフォルダに移動します。
cd vial-qmk
次に、下記コマンドを実行し、ファームウェアをコンパイルします。「xxxx」の部分は作成したキーボードの名前に変えて下さい。
make xxxx:vial
コンパイルが完了すると、vial-qmkフォルダの中に「xxxx_vial.uf2」というファイルが作成されますので、RP2040 Zeroに書き込めば全ての作業は完了です。
おわりに
ロータリーエンコーダーを使った入力デバイスの作成、お疲れ様でした!
この記事を書きながら作業を進めていましたが、私の環境では問題なくVialの認識までできました。
本当は回路図や基板、ケースの作り方ももっと丁寧に説明したかったのですが、この記事がすでに8,000文字を超えているため、詳細は画像を参考にしていただけると助かります。キーボードにロータリーエンコーダーを組み込む際には、さらに深い知識が必要になるかもしれませんが、新しいQMKファームウェアでロータリーエンコーダーを動かすためのヒントにはなったかと思います。
なお、私の知識や経験に限りがあるため、いただいたご質問にすべてお答えできない場合がある点は、何卒ご理解いただければ幸いです。
この記事はAkashaを使用して書きました。