見出し画像

vial-qmk: Planck rev7 + encoders 修正進捗

この記事では、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ケーブル(たまに接続不良)


不具合について

公式DiscordのForumで以下通りやりとりさせてもらい、認識はされているけど、直っていない不具合ということが分かっている。
また 9d9cdaaa2d035787b0b50c26f2975695fdbc16f4 のコミットを使う事により問題無いことが分かっている。

Issue with Rotary Encoders on Planck rev 7

Hello,

I am currently facing an issue with setting up Rotary Encoders on my Planck rev 7 keyboard. I have tried using the default Planck rev 7 rules.mk file with the ENCODER_ENABLE = yes configuration, but the encoders are not functioning as expected.

I have tried using the PEC12R-4222F-S0024 encoder from Yushakobo, as well as other may compatible encoders from Aliexpress. However, none of them seem to work properly. The encoders respond to both clockwise and counterclockwise rotations, but the values of index and clockwise passed to the encoder_update_user function are incorrect.

I have soldered the encoders to Number 0, 3, and 7, but the behavior is the same bugs. For example, when rotating the encoder connected to Number 3 clockwise, the `clockwise` value is 0 and the `index` value is 5, 7, or random (occasionally, the `clockwise` value is 1 and the correct `index` is passed).

I have checked the soldering connections multiple times, but everything seems fine. I have also confirmed that the `ENCODER_RESOLUTION` value is set to 4, which is the default.
I have checked the datesheet of PEC12R-4222F-S0024 and PEC11R-4215F-S0024.
I have included some sample output from the HID console below:

keymap.c

```
bool encoder_update_user(uint8_t index, bool clockwise) {
printf("encoder_update_user\n");
printf("+ index: %d\n", index);
printf("+ clockwise: %d\n", clockwise);
printf("+ get_highest_layer(layer_state): %d\n", get_highest_layer(layer_state));
```


HID console

```
> encoder_update_user
> + index: 6
> + clockwise: 0
> + get_highest_layer(layer_state): 0
> encoder_update_user
> + index: 2
> + clockwise: 0
> + get_highest_layer(layer_state): 0
> encoder_update_user
> + index: 5
> + clockwise: 0
> + get_highest_layer(layer_state): 0
> encoder_update_user
> + index: 1
> + clockwise: 0
> + get_highest_layer(layer_state): 0
> encoder_update_user
> + index: 5
> + clockwise: 0
> + get_highest_layer(layer_state): 0
```

QMK の公式DiscordのForumに投稿された内容より

yeah, there is an issue with the encoder code for the rev7
git revert 9d9cdaaa2d035787b0b50c26f2975695fdbc16f4 should fix that, short term

QMK の公式DiscordのForumに投稿された内容より

yeah, that commit is adding abstraction/driver support for encoders, and changes the code for the planck rev7. Unfortunately, it looks like there is some issues with the changes, and ideally need somebody with a rev7 to do some testing/etc.
and you're not the first to have issues with this

QMK の公式DiscordのForumに投稿された内容より

めっちゃyeah yeah言いよる。中華系カナダ人の友人が、何か言うと4回ぐらいyeah言う人だったことを思い出した。中身同一人物か?ってレベル。

進捗

  • [済み] 最新のコードに追随できていない

    • driver や quantum の更新についていけていない

  • [済み] 不具合

  • [済み] ENCODER_MAP_ENABLE関連

    • [済み] PlanckがENCODER_MAP_ENABLEに対応していない

    • [済み] Planckに装備されているロータリエンコーダーにあてられるキーコードをVIALなどで変更できない

  • [着手中] QMK本体へのPull Requestと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. 不具合

不具合は上記のPRで混入した。おそらく、PRを出した人はエンコーダーが複数設定されることを想定していなかったのではないか。
というのも、PRの実装では何度もロータリエンコーダーを初期化するような処理が走るせいで、不具合について に記載された挙動をするようになってしまっている。
どのように、修正すればいいか分からないため、Jack Humbert氏が作ったものをほぼそのまま移行する形で修正した。
具体的には encoder_driver_task というドライバー側の処理を上書きする形で、その修正をした。
コードレビュー時に抽象化したコードを使えという話になったので、PINの状態読み取りを同時ではなない形で強制されることとなっている。従って、若干のラグはあるかもしれないが、他のキーボードと同じなので分からない程度だとおもう。
ただし、修正した後に確認が入っていないので時間が掛かりそう

修正済みコミット:

encoder_quadrature_read_pin の呼び出し元が、 encoder_driver_taskなので、そこから上書きをしてしまえばいいという作戦である。
もっと良い形があるならば教えてほしい。

もし、この作戦がダメでQuadratureのドライバを使うことがだめならば、自身で書いてやらないといけなくなる。大変だ…。

3-1. Planck が ENCODER_MAP_ENABLE に対応していない

これはハードウェア的な問題ではなくソフトウェア(QMK)的な問題だったはず。というのも、最新の状態ではENCODER_MAP_ENABLEに対応しているかのような状態で、encoder_mapで定義が出来た(はず)

この「はず」というところがキモで、エンコーダーを0番、3番、7番でつかっていたときに問題無く動いていた気がする..。という曖昧な記憶に基づくもののため。

では、実際にはどうだったかというと、ソフトウエア的な問題だった。
以下にあるコミットでは encoder_map で定義できるようになっている

修正済みコミット

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を書いておいた方が使用者の為と考え、その形で修正をした。

使用している KLEファイル: ピンク色がロータリーエンコーダー関連になるところ。(もちろん、無駄が不要な方は http://www.keyboard-layout-editor.com/#/gists/f8c286f3f31edb0aa95ef9a51ab251b3 のようにしてもいいはず)

8つのエンコーダーに対応したPlanckのKLE。0,1 や 1,1 といったlegendとeが大切。(index, Clockwise) といった並び順。3番と7番なら3,0 と 3,1 と7,0 と 7,1の定義が必要
Planck が ENCODER_MAP_ENABLE に対応し、encoder_mapで各ロータリエンコーダーを変更できる状態の画面

以下のPullRequestで修正済み。

  • QMKへのPullRequestで修正に使っている ブランチ

  • VIAL-QMK で修正しているときに使っているブランチ

    • こちらの方が実用的だが、QMK側の若干コードが異なる(matrix.cがほぼ同じなので大丈夫なはず)

調査方法
quantum/dynamic_keymap.c の dynamic_keymap_reset でENCODER_MAP_ENABLEが定義されているときに dynamic_keymap_set_encoderが登録されるのは分かっているが、VIAL_ENABLEが有効なときの挙動についてうまく理解できていない。
おそらく、VIALなどを使わず、QMK単体で使うなら、ここは意識しなくて良いかもしれない。



感想、ほか

  • 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上でやりとり中。

  • ロータリエンコーダーの挙動については以下の記事がすごく勉強になった。encoder_update を使った実装は ENCODER_MAP_ENABLEを使う実装とは少し違うので、あくまで一般的なロータリエンコーダーの実装についての学習という形で役に立った。2ビットの動きで回転を表現するってのがよくわかった。

  • 猫山王 氏 の記事でいろいろやりとりさせてもらい、この修正に至っている。色々、ありがとうございました。https://note.com/nekoyamaou/n/nffc1742e6930 https://note.com/nekoyamaou/n/nef832302f7c5


この記事が気に入ったらサポートをしてみませんか?