Open21

ヒトは知識ゼロから自作キーボードを作れるか?

Kotone/NanoKotone/Nano

筆者のレベル

ソフトウェア

大学の研究でCを書いていた程度、国立研究所でスパコン向けにC++を書いていた程度、民間企業でWeb開発をしている程度

ハードウェア

大学の授業でマイコンで遊んでいた程度

座学

理論

https://voyage4bliss.com/diode-neccesity/

作り方

https://zenn.dev/niw/articles/my_first_keyboard_60

PCB設計

https://zenn.dev/kuzumotch/books/a1f8f540f775b2/viewer/ad9a49

無線化

https://sekigon-gonnoc.github.io/BLE-Micro-Pro/#/
https://blog.object1037.dev/posts/20220725

Kotone/NanoKotone/Nano

キーが干渉しないかチェック、18×17で組んだのでChocFoxキーキャップがぴったり

はんだ付け後の状態、やってみてわかったのはSMDの方がはんだ付けが簡単で足を切らなくていいので楽
ただTHTだとPCB設計中にviaとしての役割も担えるので便利は便利(viaを綺麗に配置する方法を知らないだけと言われればそう)

キースイッチとキャップをはめた状態で試打
まず親指の一番内側のキーを1.5Uにしようと思ってたけど90°回転させないといけないのを見落としていた
縦コンボは押せるけど最適ではなさそうなのでちゃんと動いたらChicago StenoかKLP Lameを検討したい

なお何も考えずにPro Microを表裏逆にピンソケットに付けてしまった(本当に頭がバグってた)ので後日つけなおし

Kotone/NanoKotone/Nano

シフトレジスタを用いた出力ピン増設

https://zmk.dev/docs/development/hardware-integration/shift-registers
https://lastminuteengineers.com/74hc595-shift-register-arduino-tutorial/#google_vignette

あるピンの入力がクロック信号ごとにHIGHかLOWか(シリアル信号)によってレジスタに書き込んでLATCHピンに入力を与えるとレジスタのビット値に対応する出力ピンがHIGH/LOWになったり(パラレル信号)、逆に複数の入力ピンのHIGHかLOWか(パラレル信号)をクロック信号ごとに出力する(シリアル信号)仕組み

前者をSIPO、後者をPISOという

マイコンボードのピン的にはそれぞれMOSI/MISO線を使う、MISO線はクロックごとに入力を走査する必要があり電力消費が大きいというデメリットがある

キーボードの用途では例えば75%で80キーとちょっと

例としてseeed XIAO BLEにアナログスティックを2つ繋ぎつつLiPoバッテリーを充電できるようにするとアナログ線5本が必要で残るピンの数は6本、3×3=9キーまでしか配置できない
しかしSIPOのシフトレジスタを使えばシリアル信号、クロック信号、レジスタロック(ラッチ)信号の三本のピンを8本に増やすことができる
さらにシフトレジスタのシリアル出力とマイコンのクロック・レジスタロックを他のシフトレジスタに繋いでやれば+8本、3本のピンを16本に増やすことができる

https://meyon.gonna.jp/study/electronic/9765/

Kotone/NanoKotone/Nano

ここまでの軌跡

  1. とりあえず適当にHID Reportをでっちあげてみる(敗北)
  2. インターネットにあるHID Reportを参考に書いてみる(GamePad Testerは認識するがFF14が認識しない
  3. Vendor IDとProduct IDを無理やり設定してみる(ここで丸一日溶かす、単純に検索するとSDPでやる方法しか出てこない、なんかよくわからないけどGATTでできるらしいと知る、仕様書を漁ったら見つかる、CircuitPythonのコードを読んで実装を追加、PRを出してマージされる、FF14が認識するようになるが入力には反応しないの)
  4. WindowsにBLEで繋ぐと明らかにリファレンスのGuliKit KK3 Maxと挙動が違うのでHID Reportの形式が微妙に違うと信じたいが、rreport ID 2-3を実装しないといけなくなるとCircuitPythonの根元に手を入れることになるので大変
  5. 一旦BLEの通信内容をWiresharkでSniffingしてみたいがなんか出てこない