Helixキーボードにホイールとトラックポイントを付けてみた

![IMG_1886.JPEG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310294/c58da2a1-b76d-fa33-5c9a-3bf4038c7e74.jpeg)

# 動機
- HelixにThinkPadトラックポイントキーボードみたいなポインティングデバイスを付けて、片手で色々済ませたい
- ホイールも付けて快適にブラウジングしたい

# 前提
- Helixベース（はじめからホイールが付いたrev3ではないやつ）
- トラックポイントはThinkpadからの移植ではなく市販のジョイスティックを使う
    - 　本稿では秋月で販売している「ジョイスティックＲＫＪＸＹ１０００００６　ＤＩＰ化キット」を使用

# 失うもの
- OLEDディスプレイ
    - Pro Microのピン数の関係でI2Cを無効化する
    - OLEDディスプレイが実装されていたスペースにジョイスティックを設置する
- QMK Configuratorによる簡単なキーマップ変更
    - CLIでmakeやflashする必要があるため
- Helixのシンプルでエレガントな外観
    - 拡張基板をプリント基板化すれば美しく作れるかも

# 手順① Pro Microのピンアサインを決める
- ジョイスティックはアナログIO対応ポートを2つ使用　⇒未使用のB5とB6を使用する
- エンコーダはデジタルIO対応ポートを2つ使用　⇒空きがないのでI2CのSDAとSCLに使っていたD0とD1を使う

![1.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310294/72574e9c-01a7-1826-02dd-5825dcbebe3d.png)

# 手順② ハードウェア加工
- 拡張基板を作る
    - SU120自作キーボード用基板から切り出したキースイッチ基板、エンコーダ基板とユニバーサル基板をつなげる
        - 基板のつなぎ方はいろいろあると思うが、作例ではリード線でつないでからはんだ付け
    - キースイッチソケット、ダイオード、ジョイスティック用のフレキシブルケーブル接続コネクタなどをはんだ付けする 
![IMG_1883.JPEG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310294/a180a3a0-a683-c322-7cfe-5822b5f82ad8.jpeg)

- Helix基板からOLEDディスプレイ用のピンソケットを取り外す
    - ジョイスティック固定用のスペーサーと干渉するため
    - ジョイスティックの実装場所によってはこの作業は不要
- Helix基板と拡張基板をつなげる
    - Helix基板側の穴ははんだがつかないのでエポキシ等で固定
- GND、D0、D1とエンコーダを接続する
    - 今回はピンが足りないのでプッシュボタンは未接続
- VCC、GND、B5、B6とジョイスティックを接続する
![2.PNG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310294/303cb368-7ca8-2b3f-a8a0-4cc0ab37e27d.png)

- マウスボタンとして使うキースイッチを接続する
    - HelixではRow×5行、Col×7列の35キーのうち32キーを使用し、また1キーを分離キーボードの左右検知に使用しているため、残り2キーのみが使用可能　    ⇒マウスの左ボタン、右ボタンに割り当てる（中ボタンは諦める）
    - 拡張基板のColをB2、2つのRowをそれぞれD4とC6に接続
        - Helix基板のPro Microの足付近は込み合っているので、基板上のどこかはんだ付けしやすいところに付ける
        
- Helix基板にスペーサーを2本取り付け、ネジでジョイスティックを固定（偶然ぴったり合う）
    - 以下の写真はジョイスティックの頭部を削ってThinkPadトラックポイント用のゴムをはめたもの
![IMG_1887.JPEG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310294/d90b5726-a699-b1c8-1069-4405a8c70033.jpeg)




# 手順③ QMKビルド環境の構築
- QMK MSYSを導入
    - [こちら](https://msys.qmk.fm/)からQMK_MSYS.exeのLatest Versionをダウンロードしてインストールする
    - QMK MSYSを実行し、プロンプトに促されるままにqmk setupをする
    - qmk_firmwareディレクトリに移動し、ためしにHelixの標準のファームウェアをメイクしてみる
        ``` 
        qmk compile -kb helix/rev3_5rows -km default
        ```
    - makeが無事に終了し、ローカルディレクトリに helix_rev3_5rows_default.hex ファイルが生成されていたら成功

# 手順④ QMKの作業
- rev3_5rowのコピー
    ```
    cp -r keyboards/helix/rev3_5rows/ keyboards/helix/joywheel
    ```
- qmk_firmware\keyboards\helix\helix.hに以下を追加
    ```qmk_firmware\keyboards\helix\helix.h
    #ifdef KEYBOARD_helix_joywheel
        #include "joywheel.h"
    #endif
    ```
- qmk_firmware\keyboards\helix\joywheel\rules.mkの編集
    ```qmk_firmware\keyboards\helix\joywheel\rules.mk
    # 以下をyesからnoに変更
    OLED_ENABLE = no

    # 以下をコメントアウト
    # SRC += oled_display.c

    # 以下を追加
    POINTING_DEVICE_ENABLE = yes
    POINTING_DEVICE_DRIVER = analog_joystick
    MOUSEKEY_ENABLE = yes
    ```
- qmk_firmware\keyboards\helix\joywheel\config.hの編集
    ```qmk_firmware\keyboards\helix\joywheel\config.h
    //以下をB6、B5からD1、D0に変更
    #define ENCODERS_PAD_A { D1 }
    #define ENCODERS_PAD_B { D0 }

    //以下を追加
    #define ANALOG_JOYSTICK_X_AXIS_PIN B5
    #define ANALOG_JOYSTICK_Y_AXIS_PIN B6
    #define ANALOG_JOYSTICK_AXIS_MIN 0
    #define ANALOG_JOYSTICK_AXIS_MAX 1023
    #define ANALOG_JOYSTICK_SPEED_REGULATOR 10
    #define ANALOG_JOYSTICK_READ_INTERVAL 10
    #define ANALOG_JOYSTICK_SPEED_MAX 10
    //#define ANALOG_JOYSTICK_CLICK_PIN = <PIN>
    //#define POINTING_DEVICE_INVERT_X
    #define POINTING_DEVICE_INVERT_Y
    ```
- keyboards/helix/joywheel/info.jsonの編集
    - {"x":6, "y":0}, {"x":8, "y":0},　と　{"x":6, "y":1}, {"x":8, "y":1}, を追記
    ```keyboards/helix/joywheel/info.json
    (略)
          "layout": [
        {"x":0, "y":0}, {"x":1, "y":0}, {"x":2, "y":0}, {"x":3, "y":0}, {"x":4, "y":0}, {"x":5, "y":0}, {"x":6, "y":0}, {"x":8, "y":0}, {"x":9, "y":0}, {"x":10, "y":0}, {"x":11, "y":0}, {"x":12, "y":0}, {"x":13, "y":0}, {"x":14, "y":0},
        {"x":0, "y":1}, {"x":1, "y":1}, {"x":2, "y":1}, {"x":3, "y":1}, {"x":4, "y":1}, {"x":5, "y":1}, {"x":6, "y":1}, {"x":8, "y":1}, {"x":9, "y":1}, {"x":10, "y":1}, {"x":11, "y":1}, {"x":12, "y":1}, {"x":13, "y":1}, {"x":14, "y":1},
        {"x":0, "y":2}, {"x":1, "y":2}, {"x":2, "y":2}, {"x":3, "y":2}, {"x":4, "y":2}, {"x":5, "y":2},                                 {"x":9, "y":2}, {"x":10, "y":2}, {"x":11, "y":2}, {"x":12, "y":2}, {"x":13, "y":2}, {"x":14, "y":2},
        {"x":0, "y":3}, {"x":1, "y":3}, {"x":2, "y":3}, {"x":3, "y":3}, {"x":4, "y":3}, {"x":5, "y":3}, {"x":6, "y":3}, {"x":8, "y":3}, {"x":9, "y":3}, {"x":10, "y":3}, {"x":11, "y":3}, {"x":12, "y":3}, {"x":13, "y":3}, {"x":14, "y":3},
        {"x":0, "y":4}, {"x":1, "y":4}, {"x":2, "y":4}, {"x":3, "y":4}, {"x":4, "y":4}, {"x":5, "y":4}, {"x":6, "y":4}, {"x":8, "y":4}, {"x":9, "y":4}, {"x":10, "y":4}, {"x":11, "y":4}, {"x":12, "y":4}, {"x":13, "y":4}, {"x":14, "y":4}
      ]
    (略)
    ```
-  keyboards/helix/joywheel/rev3_5rows.c　を joywheel.c に名前変更
    ```
    mv keyboards/helix/joywheel/rev3_5rows.c keyboards/helix/joywheel/joywheel.c
    ```
-  keyboards/helix/joywheel/rev3_5rows.h　を joywheel.h に名前変更し編集
    ```
    mv keyboards/helix/joywheel/rev3_5rows.h keyboards/helix/joywheel/joywheel.h
    ```

    ```keyboards/helix/joywheel/joywheel.h
    // L06、R06、L16、R16を追記
    #define LAYOUT( \
      L00, L01, L02, L03, L04, L05, L06, R06, R00, R01, R02, R03, R04, R05, \
      L10, L11, L12, L13, L14, L15, L16, R16, R10, R11, R12, R13, R14, R15, \
      L20, L21, L22, L23, L24, L25,           R20, R21, R22, R23, R24, R25, \
      L30, L31, L32, L33, L34, L35, L36, R36, R30, R31, R32, R33, R34, R35, \
      L40, L41, L42, L43, L44, L45, L46, R46, R40, R41, R42, R43, R44, R45  \
      ) \
      { \
        { L00, L01, L02, L03, L04, L05, L06 }, \
        { L10, L11, L12, L13, L14, L15, L16 }, \
        { L20, L21, L22, L23, L24, L25, KC_NO }, \
        { L30, L31, L32, L33, L34, L35, L36 }, \
        { L40, L41, L42, L43, L44, L45, L46 }, \
        { R05, R04, R03, R02, R01, R00, R06 }, \
        { R15, R14, R13, R12, R11, R10, R16 }, \
        { R25, R24, R23, R22, R21, R20, KC_NO }, \
        { R35, R34, R33, R32, R31, R30, R36 }, \
        { R45, R44, R43, R42, R41, R40, R46 } \
     }

    ```
- qmk_firmware\keyboards\helix\joywheel\keymaps\default\keymap.cの編集
    ```qmk_firmware\keyboards\helix\joywheel\keymaps\default\keymap.c
    (略)
    // KC_BTN2,KC_NO,　とKC_BTN1,KC_NO, を追加
  [_QWERTY] = LAYOUT(
      KC_GRV,  KC_1,    KC_2,    KC_3,    KC_4,    KC_5,    KC_BTN2, KC_NO,   KC_6,    KC_7,    KC_8,    KC_9,    KC_0,    KC_DEL,
      KC_TAB,  KC_Q,    KC_W,    KC_E,    KC_R,    KC_T,    KC_BTN1, KC_NO,   KC_Y,    KC_U,    KC_I,    KC_O,    KC_P,    KC_BSPC,
      KC_LCTL, KC_A,    KC_S,    KC_D,    KC_F,    KC_G,                      KC_H,    KC_J,    KC_K,    KC_L,    KC_SCLN, KC_QUOT,
      KC_LSFT, KC_Z,    KC_X,    KC_C,    KC_V,    KC_B,    KC_LBRC, KC_RBRC, KC_N,    KC_M,    KC_COMM, KC_DOT,  KC_SLSH, KC_ENT ,
      ADJUST,  KC_ESC,  KC_LALT, KC_LGUI, EISU,    LOWER,   KC_SPC,  KC_SPC,  RAISE,   KANA,    KC_LEFT, KC_DOWN, KC_UP,   KC_RGHT
    ),

    // 同様に[_LOWER]や[_RAISE]や[_ADJUST]のレイヤにもKC_BTN2,KC_NO,とKC_BTN1,KC_NO, を追加

    (略) KC_PGDNとKC_PGUPをKC_WH_UとKC_WH_Dに変更
    bool encoder_update_user(uint8_t index, bool clockwise) {
    if (index == 0) { /* Left side encoder */
        if (clockwise) {
            tap_code(KC_WH_U);
        } else {
            tap_code(KC_WH_D);
        }
    (略)
    ```
- makeとflash
    ```
    qmk flash -kb helix/joywheel -km default
    ```
    - Waiting for USB serial port - reset your controller now (Ctrl+C to cancel).....と出たらHelix基板上のResetボタンを押す
    - 以下のような表示になったら成功!!!
    ```
    Reading | ################################################## | 100% 0.70s
    avrdude.exe: 21566 bytes of flash verified
    avrdude.exe done.  Thank you.
    ```
- 調整（qmk_firmware\keyboards\helix\joywheel\config.h）
    - ホイールの回転方向を逆にしたかったら#define ENCODERS_PAD_Aと#define ENCODERS_PAD_Bのピンを入れ替える
    - トラックポイントの縦横が逆だったら#define ANALOG_JOYSTICK_X_AXIS_PINと#define ANALOG_JOYSTICK_Y_AXIS_PINのピンを入れ替える
    - トラックポイントの動く方向が逆だったら#define POINTING_DEVICE_INVERT_Xや#define POINTING_DEVICE_INVERT_Yを定義する・コメントアウトする
    - トラックポイントの動きが鈍かったら#define ANALOG_JOYSTICK_SPEED_REGULATOR の値を小さくする・敏感過ぎたら値を大きくする
    - トラックポイントの最大移動速度が速すぎたら#define ANALOG_JOYSTICK_SPEED_MAX 10の値を大きくする・遅すぎたら値を大きくする
- ENJOY!!
![IMG_1884.JPEG](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/310294/9589315e-04c2-3bb6-74c7-ccef05c55f2b.jpeg)

# 感想・学んだこと
- トラックポイントに適したジョイスティックモジュールはなかなかない。いろいろ購入して試したが、今回使ったもの以外は動作が重かったり精度が悪かったりして実用的ではなかった。
    - Nintendo Switchのジョイコン用交換パーツも使用感はまあまあで、かつプッシュ機能があってよさそうだったが、フレキケーブルのコネクタ変換が大変そうだったため見送った。
- ジョイスティックモジュールにThinkpadトラックポイント用のゴムを付けると使用感がよくなる。
- ホイールは横置きにして円盤を大きくすると、マウスの縦置きホイールよりずっと快適になる。
- エンコーダのクリック感は、分解して山を潰せば軽くすることが出来る。
- アロンアルファは空気に触れないと固まらないので穴の充填には使えない。

# 今後の課題
- つぎはぎ基板は美しくないので、できればプリント基板化したい
    - そこまでやるならキーボードごと新規設計したほうが良いかも…
# 参考リンク
- [Helix](https://github.com/MakotoKurauchi/helix)・・左右分離型の自作キーボード基板
- [SU120](https://e3w2q.github.io/9/)・・最大120キーまで拡張可能な自作キーボード基板
- [ジョイスティックモジュール(秋月電子)](https://akizukidenshi.com/catalog/g/gK-15425/)
- [QMK](https://docs.qmk.fm/#/)・・自作キーボード用ファームウェア
- [QMK MSYS](https://msys.qmk.fm/)・・QMK用開発環境
- [遊舎工房](https://yushakobo.jp/)  ・・自作キーボード専門店　Helix基板を販売
- [TALP KEYBOARD](https://talpkeyboard.net/) ・・自作キーボード専門店　SU120基板を販売

# 謝辞
- Helixを開発された ないん様、SU120を開発されたe3w2q様に謝意を表します。