Vial + Planck rev7 + Rotary Encoders 修正進捗
2024/10/28: Vialのvialブランチに修正が反映されました。よって修正作業は完了となります。数ヶ月間、ありがとうございました。
以下の文章は、いつかのために残しておきますが、QMKのmasterブランチやVialのvialブランチというリリース対象となるブランチを使うことにより、Planck rev7 にエンコーダーを搭載して快適に使えるようになっています。
この記事は、Planck に ロータリエンコーダー を装備させたときにQMKで発生する不具合とその修正具合についてまとめていた記事である。
画像:
* Planck rev7
* DROP + THE LORD OF THE RINGS™ MT3 ELVISH KEYCAP SET(ET3プロファイル エルフ語キーキャップ)
* 2 Encoders(BOURNS PEC11R-4015F-S0024 デテント無し)
* readme.md 上ではデテントが必要のようだが実際はデテント無しでも大丈夫そう。(ただし、反応が悪い時ある気がする。追記: 接触不良の可能性大。)
* 2 WUQUE STUDIO Zoom75 Extra knob
* アリエクの光るUSBケーブル(たまに接続不良)
進捗・まとめ
[済み] 最新のコードに追随できていない
[済み] 不具合
[済み] ENCODER_MAP_ENABLE関連
[済み] QMKレポジトリ、developブランチへのMerge
developブランチへMerge済み https://github.com/qmk/qmk_firmware/pull/23967
[済み] QMKレポジトリ、masterブランチへのMerge
2024/08/26: Merge済み。0.26.0でmasterブランチ入り
[済み] VIAL へのPullRequestとMerge
2024/10/27: Merge済み。
修正進捗
問題が多いので少しずつクリアしていく。作業時のメモを含むため本章の記載は古い可能性がある。
最新の状態は上記の「進捗・まとめ」を参照すること。
1. 最新のコードに追随できていない
keyboards/planck/rev7/matrix.c に記載されているコードを更新する。
具体的には https://github.com/qmk/qmk_firmware/blob/master/docs/ChangeLog/20240225.md#notable-core-changes-notable-core に記載のことができていない。もちろん、まだ、下位互換がまだあるようだが、そのうち使えなくなるはず。
追記: ここは既にqmk本体側で対応済みだった。vial側でも次第に対応されるはず。
追記2: Mergeされる直前にRGB関連のキーコードの修正があることに気が付いたため、対応した。
2. 不具合について
公式DiscordのForumで以下通りやりとりさせてもらい、認識はされているけど、直っていない不具合ということが分かっている。
また 9d9cdaaa2d035787b0b50c26f2975695fdbc16f4 のコミットを使う事により問題無いことが分かっている。
めっちゃyeah yeah言いよる。中華系カナダ人の友人が、何か言うと4回ぐらいyeah言う人だったことを思い出した。中身同一人物か?ってレベル。
不具合は上記のPRで混入した。おそらく、PRを出した人はエンコーダーが複数設定されることを想定していなかったのではないか。
というのも、PRの実装では何度もPIN読み取りを初期化するような処理が走るせいで、変な挙動をする。どのように、修正すればいいか分からないため、Jack Humbert氏が作ったものをほぼそのまま移行する形で修正した。コードレビュー時に抽象化したコードを使えという話になったので、PINの状態読み取りを同時ではなない形で強制されることとなっている。従って、若干のラグはあるかもしれないが、他のキーボードと同じなので分からない程度だとおもう。
具体的には encoder_driver_task というドライバー側の処理を上書きする形で、その修正をした。
encoder_quadrature_read_pin の呼び出し元が、 encoder_driver_taskなので、そこから上書きをしてしまえばいいという作戦である。
もっと良い形があるならば教えてほしい。もし、この作戦がダメでQuadratureのドライバを使うことがだめならば、自身で書いてやらないといけなくなる。大変だ…。
3-1. Planck が ENCODER_MAP_ENABLE に対応していない
これはハードウェア的な問題ではなくソフトウェア(QMK)的な問題だったはず。というのも、最新の状態ではENCODER_MAP_ENABLEに対応しているかのような状態で、encoder_mapで定義が出来た(はず)この「はず」というところがキモで、エンコーダーを0番、3番、7番でつかっていたときに問題無く動いていた気がする..。という曖昧な記憶に基づくもののため。では、実際にはどうだったかというと、ソフトウェア的な問題だった。
3-2. Planckに装備されているロータリエンコーダーにあてられるキーコードをVIALなどで変更できない
以下のコードに書いておいたが、VIALの画面で設定できる場所と、コンパイル時?に使われるものが違う。
ただ、単純に設定方法が待ちがっているだけ… という気もしている。凡ミスが原因な気もするので、時間かければ直る気がする。
const uint16_t PROGMEM encoder_map[][NUM_ENCODERS][NUM_DIRECTIONS] = {
// 不具合: VIALの画面とコンパイラで参照する場所が違う
[0] = { ENCODER_CCW_CW(KC_A, KC_S)/* ←VIALの画面的には3番目のエンコーダ */, ENCODER_CCW_CW(KC_D, KC_F) /* ←VIALの画面的には7番目のエンコーダ */, ENCODER_CCW_CW(KC_G, KC_H), ENCODER_CCW_CW(KC_J, KC_K)/* ←コンパイラ的には3番目のエンコーダ */, ENCODER_CCW_CW(KC_L, KC_Z), ENCODER_CCW_CW(KC_X, KC_C), ENCODER_CCW_CW(KC_V, KC_B), ENCODER_CCW_CW(KC_N, KC_M)/*←コンパイラ的には7番目のエンコーダ */ },
[1] = { ENCODER_CCW_CW(KC_A, KC_S), ENCODER_CCW_CW(KC_D, KC_F), ENCODER_CCW_CW(KC_G, KC_H), ENCODER_CCW_CW(KC_J, KC_K), ENCODER_CCW_CW(KC_L, KC_Z), ENCODER_CCW_CW(KC_X, KC_C), ENCODER_CCW_CW(KC_V, KC_B), ENCODER_CCW_CW(KC_N, KC_M) },
[2] = { ENCODER_CCW_CW(KC_A, KC_S), ENCODER_CCW_CW(KC_D, KC_F), ENCODER_CCW_CW(KC_G, KC_H), ENCODER_CCW_CW(KC_J, KC_K), ENCODER_CCW_CW(KC_L, KC_Z), ENCODER_CCW_CW(KC_X, KC_C), ENCODER_CCW_CW(KC_V, KC_B), ENCODER_CCW_CW(KC_N, KC_M) },
[3] = { ENCODER_CCW_CW(KC_A, KC_S), ENCODER_CCW_CW(KC_D, KC_F), ENCODER_CCW_CW(KC_G, KC_H), ENCODER_CCW_CW(KC_J, KC_K), ENCODER_CCW_CW(KC_L, KC_Z), ENCODER_CCW_CW(KC_X, KC_C), ENCODER_CCW_CW(KC_V, KC_B), ENCODER_CCW_CW(KC_N, KC_M) },
};
こちら、修正完了済みである。Planckの良いところといえば、8つのエンコーダーに対応と考えている。それならば元から8つのエンコーダーに対応したvial.jsonを書いておいた方が使用者の為と考え、その形で修正をした。
(追記: この思想でPullRequestをおくってMergeされるかは分からない。)
使用している KLEファイル: ピンク色がロータリーエンコーダー関連になるところ。(もちろん、無駄が不要な方は http://www.keyboard-layout-editor.com/#/gists/f8c286f3f31edb0aa95ef9a51ab251b3 のようにしてもいいはず)
追記(2024/09/09): Planckを初めて触ったとき、エンコーダーの設定方法がサッパリ分からなかったことを記憶しています。そのため、エンコーダーを含むvial.jsonをVialのPRに反映する予定でしたが、Layoutタブにてエンコーダーの有無を選択出来るようにしました。(つまり、エンコーダーが欲しい人と欲しくない人が同じvial.jsonを利用出来るようにしたいと考えてます)
追記(2024/10/28): 一部、レイアウトをVialブランチに既にあるものを基準に修正したものをvialブランチにMergeしてもらいました。そのため、私の作業ブランチにあるレイアウトとは少々違うものとなっています。1U*2といった構成を使っている方は大丈夫だと思いますが、2U + 2U といった構成などであると不都合があるかもしれません。
MEMO 調査方法quantum/dynamic_keymap.c の dynamic_keymap_reset でENCODER_MAP_ENABLEが定義されているときに dynamic_keymap_set_encoderが登録されるのは分かっているが、VIAL_ENABLEが有効なときの挙動についてうまく理解できていない。
おそらく、VIALなどを使わず、QMK単体で使うなら、ここは意識しなくて良いかもしれない。
MEMO 利用価値のありそうなデバッグメッセージ
ファイル: drivers/encoder/encoder_quadrature.c
// static int8_t encoder_LUT[] = {0, -1, 1, 0, 1, 0, 0, -1, -1, 0, 0, 1, 0, 1, -1, 0};
void encoder_quadrature_handle_read(uint8_t index, uint8_t pin_a_state, uint8_t pin_b_state) {
// 2ビットの状態を作成する bit的には ba の形になる。
// uint8_t state = pin_a_state | (pin_b_state << 1);
uint8_t state = (pin_a_state << 0) | (pin_b_state << 1);
// (encoder_state[index] & 0x3) が記録されている最後の状態。stateが今の状態
if ((encoder_state[index] & 0x3) != state) {
//printf("<eqhr> %d is before %d, will state: %d\n", index, (encoder_state[index] & 0x3), (state & 0x3));
// 左に2ビットシフトして、新しいのを入れられるようにする
encoder_state[index] <<= 2;
// 空いたところの2ビットに新しい状態を保存する
encoder_state[index] |= state;
// イベントを発火
encoder_handle_state_change(index, encoder_state[index]);
}
}
QMK/VIA、VialのPullRequestについてMEMO
次回以降のために、感じたことを書く。
QMK/VIA
Discordで事前に連絡をしておくと、かなりスムーズにPullRequestの確認を進めてくれる。
実装がよくないため、ほぼ確実にChange requestな状態になるとおもうが、それらを踏まえるとdevelopブランチにMergeされるのが2週間から3週間かかる。
masterブランチにMergeされる(リリースされる)のは、おおよそ3ヶ月おき。(5月末→8月末→11月末(?))
その間の小さい修正は、逐次リリースされる。
VIA キーマップは変更しなくてもMergeされる。(たぶん)
PullRequestのテンプレートに書いてある文章が長い。頑張って読む必要がある。
Vial
QMKのmasterブランチが定期的に取り込まれる
QMKがリリースされると、リリースブランチのようなブランチがQMKのリリース後1週間程度で作られ、その後、数日でvialブランチにMergeされる。ただ、Mergeに1ヶ月程度掛かることもあるようだ。
vialブランチは、vial-qmkのmasterとなるブランチ。HEADとなるブランチ。
QMK側で管理するコードには手をいれるべきではない。(たとえば、defaultキーマップなど)
vialキーマップのみ手を入れた方が良さそう。Vialの問題ではないものは、QMKをまず修正するべき。
PullRequestのテンプレートに書いてある文章は大した量はない。読むしかない。
Mergeは非常にスムーズ、一瞬で終わる。
QMK と Vial
* だいたい、PRだしてから3ヶ月ぐらいかかる。Vialに反映されるまで。
感想・雑記
2024/06/20 昼:
本業がphp、rails、iOSという感じで、レイヤーが高い人間なので、低レイヤーの実装は久々である。Obj-Cを含めずに最後にC-lang一族とふれあったのはOpenCVのときでほぼ前世なので今世は初めて。組み込み系などのビット列を意識した実装も前世以来である。そもそもQMKを自身で使うのは初めてで、不具合が多く感じてだいぶ印象が悪い。2024/06/20 夜:
時間をみつけて、少し触っていたらvial.jsonを間違って書いていたことに気が付く。ロータリエンコーダーを0番に設定していたときにうっすらと問題無く動いていた気がするのがきっかけで気が付けた。あとはPullRequestに向けてコードを整え、削除しすぎた箇所はもとにもどせば良いだけとなった。とても達成感がある。2024/06/21 昼:
PullRequestを送った後、DiscordのForumにコメントを書いておいたら直ぐに対応してくれた。一部、よくない実装があったようで、どのようにすればいいかPullRequest上でやりとり中。2024/07/08 昼:
今朝、developブランチへMergeされたとの通知あり。
2024/07/12 昼:
qmk側masterブランチにMergeされていないが、developブランチにMergeされてしばらくたっているので、そのうちmasterにMergeされるだろう。また、VIAL側にqmkのdevelopにMergeされたコードをもってきて動作確認したが、問題はなさそうである。
2024/08/28 昼:
26日にQMKにMergeされた。あとは、Vial側対応となる。が、Vial側にQMKのmasterブランチがMergeされていない。そのため、再開できない…もどかしい。
2024/09/09 深夜:
VialのコードをPullRequest向けに整える作業中。vial.jsonのlayoutにエンコーダーを使うか使わないか設定を含ませる修正をして、エンコーダーを使わないPlanck使いからの批判を避けたいと考えている。
2024/09/10 昼:
VialへのPullRequest準備完了。ロータリエンコーダー有無のレイアウトを整えた。(一旦、エンコーダーがあるか、ないかだけのチェックにする)
PullRequest時に、個別にエンコーダーの有無を変更出来るようにしろという話があれば、そのようになるとおもうが、現状でいいのでは?と思っている。(いまのレイアウトはエンコーダーを使いたい初学者に対して厳しいから、マシになるのは絶対なはずなので)
2024/09/26 夜:
Vialにqmkのmasterブランチ取り込みがまだされない。
以前のログから考えると、変
2024/10/08 昼:
あと少しでPR出せますが、時間を作れていないのでまだ時間かかります。
2024/10/20 昼:
仕事が忙しくなってしまい土日すらない状態が継続中。まだ時間かかります。
2024/10/26 昼:
時間が作れたのでPullRequest作りました。
2024/10/28 夜:
無事、Mergeされました。終わりました。
参考資料、ほか
ロータリエンコーダーの挙動については以下の記事がすごく勉強になった。encoder_update を使った実装は ENCODER_MAP_ENABLEを使う実装とは少し違うので、あくまで一般的なロータリエンコーダーの実装についての学習という形で役に立った。2ビットの動きで回転を表現するってのがよくわかった。
猫山王 氏 の記事でいろいろやりとりさせてもらい、この修正に至っている。色々、ありがとうございました。https://note.com/nekoyamaou/n/nffc1742e6930 https://note.com/nekoyamaou/n/nef832302f7c5