System.Windows.Forms.Keys
Benkei for Windowsを作っていて、混乱してくるので、キーコード表を作った。 ドキュメント読んでも、ANSI基準で書いてあるので、JISキーボードだと混乱する。 不親切なんだよなぁ。
Keys 列挙型 (System.Windows.Forms) | Microsoft Learn

2025年の自キ活動
この記事はキーボード #2 Advent Calendar 2025 - Adventarの15日目の記事です。 あわせてキーボード #1 Advent Calendar 2025 - Adventarもどうぞ。
では簡単に今年のキーボード活動を振り返ってみます。
イベント
- 天キー Vol. 8
- 天キー Vol. 9
- Alternative Typing Contest 第2回
他にもNT東京、Maker Faire Tokyo、Japan RepRap Festivalなんかも参加し、DIYイベントを堪能しました。 イベントに行くと創作意欲を分けていただけるので、楽しいです。
作ったキーボード
SW Eave65
フリーアドレスの職場に変わって、 毎日机の上を片付けないとけいなくなり、 軽くて雑に扱えるキーボードが欲しくなり、 ちょうど遊舎工房で発売されたこのキーボードの最初のロットを購入しました。 使ってみるといい打鍵感だし、 破格に安価ですが作りは安っぽくなく、 カスタムキーボード入門にはいいなと思いました。 おすすめです。
Prospector
Prospector|クールなデザインのZMKを活用した自作ドングルデバイス - TALPKEYBOARD BLOGで紹介されていたのを見て、面白そうと思っていたのですが、 さらに【Prospector Scanner】 zmkステータス表示デバイス 導入手順|おぐを見て、つくってみました。 ワイヤレスキーボードにOLEDをつけると電池が減るので嫌でしたが、 これなら本体のバッテリーに影響なく画面表示ができます。
レイヤー表示のウィジェットを改造して、筐体も独自デザインで作ってみました。 天キーに持っていきました。

ソフトウェア
薙刀式関連ばかりですが、生成AIの進化もありコード生成は非常にはかどりました。 それが面白くて、ソフト面の進捗のほうが大きかった1年でした。
QMK薙刀式、ZMK薙刀式の改善
それぞれ薙刀式のかな入力を実現するキーボードファームウェアですが、 入力アルゴリズムを改良したり、 ZMK版はモジュール化したりした。 そろそろ大岡さんがv17をリリースすると思うので、 ファームウェアも更新します。
Benkei2 (Mac用)
GitHub - eswai/Benkei2: Benkei(弁慶)は薙刀式かな入力のMac OS実装です。
親指シフト用のLacailleをベースにして、薙刀式用のBenkeiを作りましたが、 変換アルゴリズムを更新して、 最新のMacの環境についていくためにObjective-CからSwiftへ書き直しました。 まだ、中途半端な状態ですが、継続的に改良していきたいと思います。 バイナリは Releases · eswai/Benkei2 · GitHub からダウンロード可能です。
Benkei for Linux
GitHub - eswai/benkei-linux: Benkei for Linuxは薙刀式かな入力のLinux実装です。
親指シフト用のoyainputというLinuxソフトをベースに、BenkeiのLinux版をつくりました。 これは、Omarchy(DHHがカスタムしたArchLinux)を使い始めて気に入ったので、必要にかられてつくりました。
Benkei for Windows
GitHub - eswai/benkei-windows: 薙刀式カナ入力BenkeiのWindowsバージョン
Mac、Linuxときたら、そろそろWindows版をやるかということで、作ってみました。 まだ、途上ですが、この記事で、初公開します。 バイナリは Releases · eswai/benkei-windows · GitHub からダウンロード可能です。
Windowsは、作者の大岡さんが薙刀式の開発に使っている環境ですが、下のようにいろいろ問題があります。 紅皿、漢直WSなどが薙刀式をサポートしていますが、 細かな挙動を改善したいです。 幸い、AIコーディングが強力なおかげで、書いたことがないC#でも動作するものが作れました。 今後、固有名詞の編集UIなど、薙刀式専用に特化していきたいと思います。
最後に
来年も、引き続きキーボードを楽しんでいきたいと思います。
オーディオ再燃
昔のInfinity Reference 10のエッジを修復してから、オーディオ熱がまた再燃してきて、結局一式そろえたのでまとめておく。 Audio Science Reviewで評価の高い、今時の中華D級アンプ、DACを使ってみたくて、下のような構成になった。
音楽再生はVolumioがメイン。映像ものの音声はテレビから入力したい。 ストリーミング音楽がこれらから入らないので、仕方なくBluetoothで。
デジタル入力を全種そろえており、リモコン付き、12Vラインでパワーアンプの電源も同期できるという全部入りでZD3を選択。見た目も悪くない。 HDMIのおかげでテレビやその先のBDプレイヤーまで電源を連動してくれる。便利。
D級アンプは、PFFBつき、2.1ch対応でハイパスフィルター付きということでA20しかない。 ZD3とバランス接続できる。 ZD3もA20もこれしかないという選択。
要のスピーカーは惚れ込んでいるKEF R300。 けっこう低音は伸びるが、それでもサブウーファーの恩恵は大きくて、満足度の高い2.1ch構成です。
スピーカーとサブウーファーは中古で調達した。それで図のDACから下は総額17万円くらいじゃないかな。 あと拡張するとしたら、ARC StudioをDACとアンプの間に入れるくらいか。

3次元配列のキーボードをSolidPythonで設計してみる
この記事はキーボード #2 Advent Calendar 2024の記事です。
昨日は、IKeJIさんの「KMK Firmware入門」でした。 私もKMK使ってます。
本題
3次元配列キーボードって自作キーボードの夢ですよね。 私もいつかは3次元のキー配置と思いながら、dactyl manuformのレポジトリを眺めてみたりしたことはあるんですが、ちょっと読む気が起きないコードが置いてあります。
dactyl-manuform/src/dactyl_keyboard/dactyl.clj at master · abstracthat/dactyl-manuform · GitHub
dactyl manuformでも使われているOpenSCADは マウスで画面を見ながら少しずつ形状をモデリングするのではなくて、 コードで形状を記述して、それを形状に変換します。
普通のCADとやってることは同じなんですが、ループを回して同じ形を複製したり、 パラメータ調整して作り直したりするのは容易に思います。 OpenSCADの言語だけでもいろいろできるんですが、 SolidPythonを使うとさらに簡潔に、高機能な言語で操作できるので、少し敷居が下がってきます。
SolidPythonで記述して、 pythonで実行するとOpenSCADのファイルを出力します。 OpenSCADで形状を確認して、SolidPythonを直す。 完成したら、OpenSCADでSTLへ変換し、 最終的に3Dプリンタで出力する、という流れを考えています。
GitHub - SolidCode/SolidPython: A python frontend for solid modelling that compiles to OpenSCAD
ここでは、SolidPythonを使って、3x2のキーボードを設計してみます。 solidpythonをインストールしておいてください。 solidpython2というのもあってややこしいですが、微妙に異なるもののようです。
1から7のステップに分けました。 それぞれのファイルの全体をこちらに置いておきます。 ここからはコードの要点のみ解説します。
1. 立方体を作る 1_cube.py
まず1キー用のケースを作っていきます。 cubeで立方体を作ります。 cubeは頂点の一つが座標0, 0, 0になるので、スイッチの中心をx=0, y=0、スイッチプレート上面をz=0になるようにtranslateで移動しておきます。
from solid import * # ケースになる部分 body = translate([-12, -12, -19])( cube([24, 24, 20]) ) scad_render_to_file(body, '1_cube.scad')
実行すると1_cube.scadというファイルができるので、これをOpenSCADで開いてください。 図のように表示されるはずです。

2. スイッチの穴になる部分 2_hole.py
立方体にスイッチを刺すための穴を空けていきます。 ここでは、穴の形(穴を反転した形)をモデリングします。 unionは足し算です。 3つの立方体を合体して一つにしています。
# ケースからカットする部分 hole = union()( # スイッチの上側をカットする部分 translate([-10, -10, 0])( cube([20, 20, 10]) ), # スイッチの穴 translate([-7, -7, -49])( cube([14, 14, 50]) ), # スイッチプレートの下側 translate([-10, -10, -51.5])( # プレート厚み1.5mm cube([20, 20, 50]) ), )

3. 1キーのケース 3_1key.py
そして、引き算であるdifferenceを使って立方体1からカット部分2を削除します。
kbd = difference()(
body,
hole
)

4. 6キー分作る 4_6keys.py
6キー分のx, y座標リストを用意して、作った1キーをtranslateしつつ最後にunionで結合します。
position = [
[19.05 * 0, 19.05 * 0],
[19.05 * 0, 19.05 * 1],
[19.05 * 0, 19.05 * 2],
[19.05 * 1, 19.05 * 0],
[19.05 * 1, 19.05 * 1],
[19.05 * 1, 19.05 * 2],
]
kbd6u = union()(
[translate([x, y, 0])(kbd) for x, y in position]
)
しかし、単純に結合すると、重なっておかしくなっているところがたくさんありますね。

5. unionとdifferenceの順序を変えて余計な部分を除去する 5_6keys-2.py
そこで、1キー分を作ってから6個足し算するのではなくて、 ケース部分1を6個結合 - カット部分2を6個結合という風に、順序を変えます。
body6 = union()(
[translate([x, y, 0])(body) for x, y in position]
)
hole6 = union()(
[translate([x, y, 0])(hole) for x, y in position]
)
kbd = difference()(
body6,
hole6
)

6. スイッチを回転させる 6_6keys-rot.py
いよいよ3Dキーボードらしく、キーの向きを変えていきます。 positionリストにz位置と角度を追加して、回転してから移動し結合します。
# スイッチの位置 x, y, z と角度[度] rx, ry position = [ [19.05 * 0, 19.05 * 0, 1, -5, 5], [19.05 * 0, 19.05 * 1, 0, 0, 5], [19.05 * 0, 19.05 * 2, 1, 5, 5], [19.05 * 1, 19.05 * 0, 0, -5, 0], [19.05 * 1, 19.05 * 1, -1, 0, 0], [19.05 * 1, 19.05 * 2, 0, 5, 0], ] # ケースを合体 case6 = union()( [ translate([x, y, z])( rotate([rx, ry, 0])(body) ) for x, y, z, rx, ry in position ] ) # カット部分を合体 hole6 = union()( [ translate([x, y, z])( rotate([rx, ry, 0])(hole) ) for x, y, z, rx, ry in position ] )

7. 底を平らにカットして完成 7_6keys-comp.py
底がガタガタしているので、平らにします。
# ケースの底を平らにカットするための立方体 bottom = translate([-20, -20, -29])( cube([100, 100, 20]) ) # ケースからカット部分を引く kbd = difference()( case6, hole6, bottom )

こんな感じでさわりだけを解説してみました。
天キー Vol.7
天キーには2種類の3Dキーボードのモックアップを持っていきました。 球体をつなぎ合わせたものと、正20面体をつなぎ合わせたものがあります。 それらのコードもgithubに置いておきます。 2025年はこれを動作するキーボードにできたらいいな。

この記事は自作のキーボード742と薙刀式で書きました。
明日は、yharaさんの「人体の非対称性について」です。
DockerでQMK
QMKをdockerで使うと、環境構築やQMKの更新自体を気にしなくてよくなるのでおすすめです。 QMKにはDockerfileが付属していますが、QMK自身はローカルにcloneしたものを使うので、QMKの更新が必要です。 それは面倒なので、QMKが入っているdockerイメージを使います。
docker-compose.yaml
services:
compile:
image: jonz94/qmk_firmware
working_dir: /qmk_firmware
volumes:
- ${QMK_USERSPACE}/keyboards:/qmk_firmware/keyboards/ext
- ${QMK_USERSPACE}:/qmk_userspace
- ./.build:/qmk_firmware/.build
environment:
QMK_USERSPACE: /qmk_userspace
command: /bin/bash -c 'qmk compile -kb $$KEYBOARD -km $$KEYMAP'
自分のキーボード定義、キーマップはqmk_userspaceにおきます。 .envで場所を指定しておきます。
QMK_USERSPACE=/home/foo/develop/qmk_userspace
docker compose run --rm -e KEYBOARD=ext/eswai/x60 -e KEYMAP=naginata_v15y compile
jonz94/qmk_firmwareはだいたい月1で更新されているので、docker compose pullすればQMKはだいたい最新になるので楽です。
ZMK Studio Beta
ZMK StudioはZMKのキーリマップソフトです。 10/17にベータリリースされたようなので、試してみました。 まだ最低限の機能しかない、ということですが、単純なキー割り当てはできました。
ローカルにあるZMKの環境は少し古かったので、pullしてからpythonの依存を更新する必要がありました。
pip install --upgrade -r zephyr/scripts/requirements.txt
さらにprotocol buffersを使うようで、インストールする必要があります。
Nanopb — Zephyr Project Documentation
ZMK Studio用に設定を追加し、キーレイアウトを表示しないといけないので、それを作ります。 私は使いませんでしたが、JSONからのコンバータがあるようです。
Physical Layouts | ZMK Firmware
https://zmk-physical-layout-converter.streamlit.app/
また、&studio_unlockをキーマップに入れておかないといけません。
キーマップ変更は通常はロックされています。
このキーを押すことでロックを解除します。
自作キーボードなので参考になるか分かりませんが、ZMK Studio対応の設定を置いておきます。 ZMKはまだハードル高めですが、ZMK Studioがリリースされれば、かなりユーザーフレンドリーになりそうです。


