ZMK for Charybdis 4×6

はじめに

かくかくしかじかでCharybdisのファームウェアをビルドすることになったのでその備忘.

keyball44ではQMKを利用したが,今回は無線に強いZMKを利用する.

材料

nice!nanoを乗せるPCBの入手性がやや難有りなので,個別に材料を集めるよりもAliExpressでワイヤレス用のキットか組み立て済みのものを買うと手っ取り早い.

ZMK

ZMK は Zephyr RTOS をベースにしたカスタムキーボ用のファームウェア.多少 Zephyr のお作法を覚える必要があるが,無線機能を具備したキーボを実装するのに有利.

Building Open Keyboards with ZMK & Zephyr – Zephyr Project

新しく自作キーボードを実装する場合は,テンプレートを利用するか,似たような構成のキーボードをベースに設定ファイルを書き換えると良さそう.

GitHub - zmkfirmware/unified-zmk-config-template: Unified config repo template. Add `build.yml` to create an automated ZMK build.
Unified config repo template. Add `build.yml` to create an automated ZMK build. - zmkfirmware/unified-zmk-config-templat...

GitHub Actions 上でビルドするのが一般的なようだが,ZephyrやZMKのドキュメント通りローカルにもビルド環境を構築することはできる.

キーマップの書き換えには ZMK Studio が利用できる.UI は Remap の方が洗練されている気がする.

ZMK Studio | ZMK Firmware
ZMK Studio provides runtime update functionality to ZMK powered devices, allowing users to change their keymap layers wi...

Build ZMK for Charybdis 4×6

Charybdis mini 向けのZMKファームウェアは簡単に見つけることができる.一方で4×6向けの情報はほとんど見当たらないし,ファームウェアも情報少なめなので,今回はmini向けのファームウェアをベースに4×6向けのファームウェアをビルドする.

GitHub - 280Zo/charybdis-wireless-mini-zmk-firmware: ZMK Firmware for the Charybdis 3x6 Keyboard
ZMK Firmware for the Charybdis 3x6 Keyboard. Contribute to 280Zo/charybdis-wireless-mini-zmk-firmware development by cre...

コード修正

細かい部分はまだ修正が必要ではあるものの,とりあえず動くファームウェアがビルドできる状態にする.主な修正箇所は以下の通り.

boards/shields/charybdis-bt/charybdis.dtsi

default_transform を 4×6 に合わせて修正.

    default_transform: keymap_transform_0 {
        compatible = "zmk,matrix-transform";
        columns = <12>;
        rows = <5>;

        map = <
            RC(0,0) RC(0,1) RC(0,2) RC(0,3) RC(0,4) RC(0,5)  RC(0,11) RC(0,10) RC(0,9) RC(0,8) RC(0,7) RC(0,6)
            RC(1,0) RC(1,1) RC(1,2) RC(1,3) RC(1,4) RC(1,5)  RC(1,11) RC(1,10) RC(1,9) RC(1,8) RC(1,7) RC(1,6)
            RC(2,0) RC(2,1) RC(2,2) RC(2,3) RC(2,4) RC(2,5)  RC(2,11) RC(2,10) RC(2,9) RC(2,8) RC(2,7) RC(2,6)
            RC(3,0) RC(3,1) RC(3,2) RC(3,3) RC(3,4) RC(3,5)  RC(3,11) RC(3,10) RC(3,9) RC(3,8) RC(3,7) RC(3,6)
                                    RC(4,3) RC(4,4) RC(4,1)  RC(4, 7) RC(4, 9)
                                            RC(4,5) RC(4,2)  RC(4,11)
        >;
    };

親指キーも含めると6×12にしたいところだが,Holder PCB の構成上マトリックスは片側だけで 5×6,左右合わせて 5×12 となる.親指キー部分は特殊な順番になる点に注意.

boards/shields/charybdis-bt/charybdis_left.overlay

Charybdis mini では使われていなかった GPIO D21 を追加.これで 5×6 のマトリックスを利用できるようになる.

	col-gpios
		= <&pro_micro 19 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>
		, <&pro_micro 20 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>
		, <&pro_micro 10 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>
		, <&pro_micro  6 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>
		, <&pro_micro  7 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>
		, <&pro_micro  8 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>
		;

	row-gpios
		= <&pro_micro 21 GPIO_ACTIVE_HIGH>
		, <&pro_micro 18 GPIO_ACTIVE_HIGH>
		, <&pro_micro  5 GPIO_ACTIVE_HIGH>
		, <&pro_micro  4 GPIO_ACTIVE_HIGH>
		, <&pro_micro  9 GPIO_ACTIVE_HIGH>
		;

nice!nano の Pinout は公式ドキュメントを参照.

Pinout and Schematic - nice!nano
Pinout and schematic for the nice!nano

boards/shields/charybdis-bt/charybdis_right.overlay

leftと同様に GPIO D21 を追加して修正.

	col-gpios
		= <&pro_micro 19 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>
		, <&pro_micro 20 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>
		, <&pro_micro 10 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>
		, <&pro_micro  6 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>
		, <&pro_micro  7 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>
		, <&pro_micro  8 (GPIO_ACTIVE_HIGH | GPIO_PULL_DOWN)>
		;

	row-gpios
		= <&pro_micro 21 GPIO_ACTIVE_HIGH>
		, <&pro_micro 18 GPIO_ACTIVE_HIGH>
		, <&pro_micro  5 GPIO_ACTIVE_HIGH>
		, <&pro_micro  4 GPIO_ACTIVE_HIGH>
		, <&pro_micro  9 GPIO_ACTIVE_HIGH>
		;

config/charybdis-layouts.dtsi

キーの物理配置を修正.

        keys
            //                       w   h    x   y rot  rx  ry
            = <&key_physical_attrs 100 100    0   0   0   0   0>
            , <&key_physical_attrs 100 100  100   0   0   0   0>
            , <&key_physical_attrs 100 100  200   0   0   0   0>
            , <&key_physical_attrs 100 100  300   0   0   0   0>
            , <&key_physical_attrs 100 100  400   0   0   0   0>
            , <&key_physical_attrs 100 100  500   0   0   0   0>
            , <&key_physical_attrs 100 100 1100   0   0   0   0>
            , <&key_physical_attrs 100 100 1200   0   0   0   0>
            , <&key_physical_attrs 100 100 1300   0   0   0   0>
            , <&key_physical_attrs 100 100 1400   0   0   0   0>
            , <&key_physical_attrs 100 100 1500   0   0   0   0>
            , <&key_physical_attrs 100 100 1600   0   0   0   0>

            , <&key_physical_attrs 100 100    0 100   0   0   0>
            , <&key_physical_attrs 100 100  100 100   0   0   0>
            , <&key_physical_attrs 100 100  200 100   0   0   0>
            , <&key_physical_attrs 100 100  300 100   0   0   0>
            , <&key_physical_attrs 100 100  400 100   0   0   0>
            , <&key_physical_attrs 100 100  500 100   0   0   0>
            , <&key_physical_attrs 100 100 1100 100   0   0   0>
            , <&key_physical_attrs 100 100 1200 100   0   0   0>
            , <&key_physical_attrs 100 100 1300 100   0   0   0>
            , <&key_physical_attrs 100 100 1400 100   0   0   0>
            , <&key_physical_attrs 100 100 1500 100   0   0   0>
            , <&key_physical_attrs 100 100 1600 100   0   0   0>

            , <&key_physical_attrs 100 100    0 200   0   0   0>
            , <&key_physical_attrs 100 100  100 200   0   0   0>
            , <&key_physical_attrs 100 100  200 200   0   0   0>
            , <&key_physical_attrs 100 100  300 200   0   0   0>
            , <&key_physical_attrs 100 100  400 200   0   0   0>
            , <&key_physical_attrs 100 100  500 200   0   0   0>
            , <&key_physical_attrs 100 100 1100 200   0   0   0>
            , <&key_physical_attrs 100 100 1200 200   0   0   0>
            , <&key_physical_attrs 100 100 1300 200   0   0   0>
            , <&key_physical_attrs 100 100 1400 200   0   0   0>
            , <&key_physical_attrs 100 100 1500 200   0   0   0>
            , <&key_physical_attrs 100 100 1600 200   0   0   0>

            , <&key_physical_attrs 100 100    0 300   0   0   0>
            , <&key_physical_attrs 100 100  100 300   0   0   0>
            , <&key_physical_attrs 100 100  200 300   0   0   0>
            , <&key_physical_attrs 100 100  300 300   0   0   0>
            , <&key_physical_attrs 100 100  400 300   0   0   0>
            , <&key_physical_attrs 100 100  500 300   0   0   0>
            , <&key_physical_attrs 100 100 1100 300   0   0   0>
            , <&key_physical_attrs 100 100 1200 300   0   0   0>
            , <&key_physical_attrs 100 100 1300 300   0   0   0>
            , <&key_physical_attrs 100 100 1400 300   0   0   0>
            , <&key_physical_attrs 100 100 1500 300   0   0   0>
            , <&key_physical_attrs 100 100 1600 300   0   0   0>

            , <&key_physical_attrs 100 100  500 400   0   0   0>
            , <&key_physical_attrs 100 100  600 400   0   0   0>
            , <&key_physical_attrs 100 100  700 400   0   0   0>
            , <&key_physical_attrs 100 100  900 400   0   0   0>
            , <&key_physical_attrs 100 100 1000 400   0   0   0>

            , <&key_physical_attrs 100 100  600 500   0   0   0>
            , <&key_physical_attrs 100 100  700 500   0   0   0>
            , <&key_physical_attrs 100 100  900 500   0   0   0>
            ;

この配列の順序はZMK Studio上での配列にも直結する.左上のキーを先頭に行順に記載する必要がある点に注意.

config/charybdis.json

jsonも4×6 に合わせて適当に修正.

        "layout": [
          { "row": 0, "col":  0, "x":     0, "y":  0.360 },
          { "row": 0, "col":  1, "x":     1, "y":  0.360 },
          { "row": 0, "col":  2, "x":     2, "y":  0.110 },
          { "row": 0, "col":  3, "x":     3, "y": -0.015 },
          { "row": 0, "col":  4, "x":     4, "y":  0.110 },
          { "row": 0, "col":  5, "x":     5, "y":  0.110 },
          { "row": 0, "col":  7, "x":     9, "y":  0.110 },
          { "row": 0, "col":  8, "x":    10, "y":  0.110 },
          { "row": 0, "col":  9, "x":    11, "y": -0.015 },
          { "row": 0, "col": 10, "x":    12, "y":  0.110 },
          { "row": 0, "col": 11, "x":    13, "y":  0.360 },
          { "row": 0, "col": 12, "x":    14, "y":  0.360 },
      
          { "row": 1, "col":  0, "x":     0, "y":  1.360 },
          { "row": 1, "col":  1, "x":     1, "y":  1.360 },
          { "row": 1, "col":  2, "x":     2, "y":  1.110 },
          { "row": 1, "col":  3, "x":     3, "y":  0.985 },
          { "row": 1, "col":  4, "x":     4, "y":  1.110 },
          { "row": 1, "col":  5, "x":     5, "y":  1.110 },
          { "row": 1, "col":  7, "x":     9, "y":  1.110 },
          { "row": 1, "col":  8, "x":    10, "y":  1.110 },
          { "row": 1, "col":  9, "x":    11, "y":  0.985 },
          { "row": 1, "col": 10, "x":    12, "y":  1.110 },
          { "row": 1, "col": 11, "x":    13, "y":  1.360 },
          { "row": 1, "col": 12, "x":    14, "y":  1.360 },
      
          { "row": 2, "col":  0, "x":     0, "y": 2.360 },
          { "row": 2, "col":  1, "x":     1, "y": 2.360 },
          { "row": 2, "col":  2, "x":     2, "y": 2.110 },
          { "row": 2, "col":  3, "x":     3, "y": 1.985 },
          { "row": 2, "col":  4, "x":     4, "y": 2.110 },
          { "row": 2, "col":  5, "x":     5, "y": 2.110 },
          { "row": 2, "col":  7, "x":     9, "y": 2.110 },
          { "row": 2, "col":  8, "x":    10, "y": 2.110 },
          { "row": 2, "col":  9, "x":    11, "y": 1.985 },
          { "row": 2, "col": 10, "x":    12, "y": 2.110 },
          { "row": 2, "col": 11, "x":    13, "y": 2.360 },
          { "row": 2, "col": 12, "x":    14, "y": 2.360 },

          { "row": 3, "col":  0, "x":     0, "y": 3.360 },
          { "row": 3, "col":  1, "x":     1, "y": 3.360 },
          { "row": 3, "col":  2, "x":     2, "y": 3.110 },
          { "row": 3, "col":  3, "x":     3, "y": 2.985 },
          { "row": 3, "col":  4, "x":     4, "y": 3.110 },
          { "row": 3, "col":  5, "x":     5, "y": 3.110 },
          { "row": 3, "col":  7, "x":     9, "y": 3.110 },
          { "row": 3, "col":  8, "x":    10, "y": 3.110 },
          { "row": 3, "col":  9, "x":    11, "y": 2.985 },
          { "row": 3, "col": 10, "x":    12, "y": 3.110 },
          { "row": 3, "col": 11, "x":    13, "y": 3.360 },
          { "row": 3, "col": 12, "x":    14, "y": 3.360 },

          { "row": 4, "col":  3, "x":  3.48, "y":  4.13, "r":   0 },
          { "row": 4, "col":  4, "x":  3.48, "y":  4.13, "r":  15, "rx":  3.98, "ry": 7.88 },
          { "row": 4, "col":  5, "x":  3.48, "y":  4.18, "r":  30, "rx":  3.98, "ry": 7.88 },
          { "row": 4, "col":  7, "x": 10.52, "y":  4.18, "r": -30, "rx": 11.02, "ry": 7.88 },
          { "row": 4, "col":  8, "x": 10.52, "y":  4.13, "r": -15, "rx": 11.02, "ry": 7.88 },

          { "row": 5, "col":  4, "x":  3.48, "y":  5.13, "r":  15, "rx":  3.98, "ry": 7.88 },
          { "row": 5, "col":  5, "x":  3.48, "y":  5.18, "r":  30, "rx":  3.98, "ry": 7.88 },
          { "row": 5, "col":  7, "x": 10.52, "y":  5.18, "r": -30, "rx": 11.02, "ry": 7.88 }
        ]

build

GitHub Actions から ZMK Firmware(build.yml)を実行する.

うまく行けば実行結果のサマリ画面から firmware-charybdis-qwerty.zip がダウンロードできるようになっているはず.zipファイルの中には2個のファームウェアが入ってる状態.

firmware-charybdis-qwerty.zip 
├ charybdis_qwerty_left.uf2
└ charybdis_qwerty_right.uf2

ファームウェアアップデート

キーボード本体のリセットを2回押して,PCにストレージとしてマウント.

マウントしたストレージにファームウェアを配置してあげると,自動的にファームウェアが書き込まれてキーボードが再起動される.

動作確認&キーマップ修正

適当なテキストエディタ等で正常に入力できるか確認する.

今回ビルドしたファームウェアでは,右手キーボードの右上に &studio_unlock を設定してある.ZMK Studio を開いたら,このキーを押すとキーマップの修正ができる.

ZMK Studio

おわりに

とりあえずこれで最低限動く状態になった.ビルドできる見通しは立ったので,常用できるように設定を詰めていきたいと思う.

GitHub - HeavyMoon/charybdis-wireless-zmk-firmware: ZMK Firmware for the Charybdis 4x6 Keyboard
ZMK Firmware for the Charybdis 4x6 Keyboard. Contribute to HeavyMoon/charybdis-wireless-zmk-firmware development by crea...

コメント

タイトルとURLをコピーしました