うちのキーボードは20キー＋トラックボールですが何か

# はじまり、その沼への入り方は多分おかしい

自作キーボードに興味を持って色々調べ始めたのはたしか2022年の始めごろ。
色々ファームウェアがあるんだなぁと思って、一番メジャーっぽいQMKの対応キーボード一覧を眺めてたらメインキーボードとして使ってるHHKB Lite2があって、マジかよと見に行ったら[HHKB-Lite-2-Teensy](https://github.com/thirteen37/HHKB-Lite-2-Teensy)というHHKB Lite2のキーマトリクス回路をTeensy 2.0マイコンに繋いでQMKなUSBキーボードにしちゃうという力技な代物でしたw
Teensyを持ってないからそれは使えないなと思いつつ、Raspberry Pi Picoは持ってるし、それで動くファームウェア(kmk firmware)もあるみたいだからちょっと挑戦してみたのが事の始まり。

流石にメインキーボード(HHKB Lite2 USB版)を弄るわけにはいかないので、しまい込んでたHHKB Lite2のPS/2版をバラシて、テスターでマトリクスを調べて、Picoを繋げて、code.pyを書いて、デバッグして、問題なくキーボードとして使えるようになったときはうれしかったです(小並感)。
![hhkb-rpi.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23513/f4b2a160-f265-6eb6-a14d-e63a84974ddf.jpeg)

だけど、キーマップを弄ってるとキーマトリクス回路が原因で同時押しが処理できないことに不満が出てきたのです。やはりダイオードを使った同時押し対策済みの回路じゃないとダメだなぁと。かと言ってHHKB Lite2のフィルム回路を弄ってダイオードを挟むとか無理無理無理。
じゃあ、安いゲーミングキーボードを買って同様の改造しちゃおうと、、、
中華のゲーミングキーボードってCherry MX互換スイッチとキーキャップ、etc...のセットと考えると凄く安いと思いませんか？w

# そして真自作キーボードへ

とまぁ、安いゲーミングキーボードを2台手に入れて、改造したり分解してスイッチとキーキャップがそれなりの個数手に入ったし、3Dプリンタも持ってる、thingiverseでキーボードのデータも見つけた、ヨシ。ということで、欲しい物理配列に近かったRedoxの筐体を出力してしばらく使ってみたのですが、せっかくなら本当に自分好みの形状のが欲しいなと思って、オリジナルキーボードの設計を開始したのでした。ずぶずぶずぶ…(深く沈む)
最初はハンドワイヤリングなものを作ってたのですが、PCBじゃないとメンテナンス性が悪いなということで、PCB製造サービスにも手を出すことにw

# mk20 tennet

PCBをいくつか試作して、現在のEndGame的なのがこいつ。
![tennet.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23513/2fab387f-3935-ab4f-a755-21ebac10c485.jpeg)

片側10キーで左右対称なので名前はten-net。

ホームポジションをキープするために、指が届かない位置のキーをすべて切り捨てるという、ホームポジション絶対崩したくないマン向けのトラックボール付きキーボードであるw
基本的には各指2キーずつ担当、ただし小指は1キーでその分人差指が3キー。

なお、キーマップはこんな感じになってます。
![Keymap.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23513/29f96dc5-2e85-4f2a-7a4a-7d0cb78a22e7.jpeg)

最後に押したの何年前？ってくらい使ってないキーは切り捨てまくってます(INSとか)。
ファンクションキーはOpenSCADで使うF6,F7を単体で、F4は使うことは使うけどAlt-F4の組合せ限定なので単体ではなく合成で配置。WindowsキーもEとの組合せしか使ってない。

hold-tapなモディファイア付きレイヤー切り替えは用意されてないので、以下のコードで実装。
```
def kcLT(lno, key, mkey = None, ph = True):
    return KC.HT(key, KC.MO(lno) if mkey is None else KC.LM(lno, mkey), prefer_hold = ph)
```

L0のアルファキーの配列はEucalyn, Astarteとか色々な配列を参考にして設定。
L1の右手側はL0に対応する濁音を配置する感じ。
あと、中指列のholdをctrlにしてるので、使用頻度の高めのものを人差指と薬指に配置(このときL0もそれに合わせて再配置)。

L3へ移行するキーはなく、ボールを動かすと自動的にL3に切り替わり、ボールが停止して1秒経つと元のレイヤーに戻ります。

トラックボールはダイソーマウスから取り出したADNS-2610互換の光学ユニットを使って[自作台座](https://gist.github.com/b2ox/a4226ebbacadea8a8a2aa348f800eacf)と[自作モジュール](https://gist.github.com/b2ox/88c651fc0a5232744eccc094e33f7336)で実装してます。

右手側基板のNeoPixelは白いマスキングテープを貼って光を拡散させて見やすくしてます。
使用用途はレイヤーとモディファイアキーの状態表示で、右の3つがAlt,Ctrl,Shift。
左3つがレイヤー番号のビット表示になってます。なお、これも[自作モジュール](https://gist.github.com/b2ox/91ca055f2e90972bf535a8a5df8fae60)で動作。

# トラックボールレイヤーへの切り替え方法の試行錯誤

ボールを動かすと自動でレイヤーが切り替わるのは便利な反面、キー入力時の振動でボールが微妙に動いてしまって意図せずに切り替わってしまうというデメリットもあります。
理想を言えばボールに指が触れている時だけ切り替わってくれるとよいのですが…

ボール操作時には親指の根元が下がってリストレストに近づくので、そのあたりにタッチセンサーを置いたら良さそうってことで、まずはTTP223タッチセンサー基板を使って[自作モジュール](https://gist.github.com/b2ox/69c6b141f833dc3d940ee1c1e8cf999c)書いてそれなりに良い感じに動きました。
が、しばらく使ってるとタッチしてるのに通常レイヤーに戻ってしまったり、また切り替わったりと妙な挙動をすることに気づきました。
どうも10秒以上タッチし続けるとうまく検出できなくなるみたいです(静電容量変化を検出するから長押ししてると変化がなくなって検出できなくなるんだろうと思われる)。
じゃあ、ローテクにマイクロスイッチでやるかと置き換えてみたのですが、長い時間押してるとスイッチに当たる部分が痛いw

非接触でなんとかならないかと色々考えた結果、赤外線反射センサーでボールの上あたりに指があることを検出すれば良さげってことでトラックボールの手前にセンサーを搭載。

![mk20ir.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23513/d2b6343c-5b9c-b821-6af4-adb928ed7874.jpeg)

![irs.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23513/355241b6-ad0f-d76b-b29e-b3fa84aa5563.jpeg)

センサーを中央に置いて、手前方向に検出させる形の方がデザイン的にはおさまりが良さそうだけど、指以外のものにも反応しそうなので、あえて不格好なこの配置。
ほぼ期待通りに動くのでヨシw

# モード切替とかあきらめた方が良くね？

ヨシと言ったな、だがあれは撤回する。
センサーの誤検知とかで意図しない切り替えが発生してしまうのをやっぱりどうにかしたくなって試行錯誤の沼に沈んでいくのでした、ずぶずぶ…

パームレストにマイクロスイッチを仕込んでレイヤー切り替えとか色々試してみたものの結局しっくりこなくて、最終的には切り替えせずに専用のスイッチ類を用意した方がマシという結論に到達したのでした。

![tennet20231203.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/23513/5dc91bd5-4b4a-f877-ea74-d7aeec78cb2e.jpeg)

単体ボタン2つと、スイッチ付きロータリーエンコーダで左右ボタンとホイール＆中ボタンを実装するという極々無難な構成が使い勝手が良いという。
ただ、エンコーダのスイッチが重いからそこはなんとかしたいと思わなくもない。

ロータリーエンコーダのモジュールはkmk firmwareにあるけれど、自分が必要なのとは齟齬があるので、そうだね、[自作](https://gist.github.com/b2ox/a1065fdf712a5f51938a542bf86cbf76)だよ。