34キーメカニカルキーボードを自作した

片手分で 横 98.2 mm、縦 85.7 mm という小さめの34キーの分割キーボードを作ってみました。マイコンを基板裏に隠すようにしたので表から見た姿はだいぶスッキリとしました。

以前作成したキーボードとの比較

なぜ作ったか

今まで片手5列のキーボードをいくつか作ってきましたが、全体のキー数が減ってくるとキーの横に配置したマイコンの存在感が大きくなり5列の割に横幅が大きいと感じるようになってきました。

マイコンをキーの横に置く例

大きいと感じつつも親指キーを私好みに配置をすると横幅が出てしまい、マイコンを表面に配置しようがしまいが横幅に影響は与えなかったので今まではキー横に配置してきました。 ですが、Keyball39 を使用するようになって今まで3つあった右手の親指キーが2つになり、また左右非対称だと気持ち悪かったので左手の親指キーも2つだけを有効にするというキーマップに移行したことで親指キー由来の横幅問題は解消できそうだったので、横幅がほぼキー5個分となるようなキーボードを作ってみることにしました。

横幅重視で設計した代償としてキーボードの高さは犠牲にしました。私は使用していないキーボードのマイコンは基本的に外して、使用するもののみにマイコンを取り付けるようにしているのでピンソケットは必須でまずその分で高さがかさみます。さらに最近使っている磁石式の USB Type C のケーブルの接続部が直径 8.5 mm ほどの円形でマイコンを基板裏に隠すと決めた時点で相当な厚さになることは確定しました。最終的にメインの PCB とボトムプレートの間には 10 mm のスペーサーを挟んでいます。

フラットにおいている場合この高さはとても気になると思いますが、私はテンティングの角度を70度にして使っており、70度だと傾いているというよりほぼ立っているので、腕を横に開けば対応できたため高さに関しては設計段階から特に低く作ろうなどとは考えていませんでした。

スイッチのホットスワップ

マイコンを表面に出さないキーボードは Let's Split のようにマイコンボードを基板裏に配置してマイコンボードのピンの内側にスイッチを配置するか、MCU 直付けにするかの2パターンに分類されると思います。私は MCU 直付けなどという技術は持ち合わせていないのでマイコンボードを愚直に基板裏に配置する方法を取ることにしました。

スイッチはホットスワップにしたかったのですが、マイコンボードを基板裏に配置するキーボードでスイッチをホットスワップにしているものはなかなか見つけることが出来ませんでした。 手元で実物を使って合わせてみる限りいけそうな気がしたものの自信が持てず似たようなことを考えている人はいないかなと探していたところドンピシャのことをやっている方を見つけ事なきを得ました。

設計しているときはマイコンのピンとスイッチが干渉しないことだけを考えていて、スイッチソケットとピンソケットの干渉を考慮しておらず、基板にパーツを合わせてみる段になってようやく干渉することに気づきました。 幸い細身のピンソケットを使うことで干渉問題は解決しました。 Kailh Mid-height のようなハウジングサイズが小さいものだったらもうすこし余裕を持って作れると思いますが、普通の CherryMX 互換のスイッチだとなかなかシビアな間隔です。

GND ベタ

ノイズ対策になるらしいと聞いて今まで GND ベタを入れてきましたが、静電容量式ならまだしもメカニカルキーボードに GND ベタは果たして必要なのか?と前々から疑問に思っていたので今回は GND ベタなしで作ってみました。

今のところ入力が荒ぶるという現象も起こっていないので、メカニカルキーボードであれば GND ベタはなくてもよいかなというのが個人的な感想です。

XIAO RP2040

今まで作ってきたキーボードは ProMicro を使ってきましたが、今回はじめて XIAO RP2040 で作ってみました。 私が作るキーボードのキー数だと XIAO RP2040 のピン数で十分ということと USB Type C なのに安い(秋月電子で私が購入したときは750円だった。2022/12/25 時点では830円)ので今後は XIAO RP2040 を基本にキーボードを作っていきたいと思ったのが主な理由です。

Firmware は QMK と KMK で書いてみてどちらでも使えることを確認しました。KMK で本格的なキーボードの Firmware を書くのは初めてでしたが直感的でとても書きやすいと思いました。欠点としては Python なのでミスした場合ランタイムで落ちるのが面倒というところでしょうか。何度かプログラムの書き込みができなくなってその度に全データを消してました。

おわり

マイコンを基板裏に配置したり、GNDベタやめてみたり、XIAO RP2040 を使ってみたりとやってみたかったことを一挙に試すことができたなかなか面白いキーボード作成でした。

ちなみにキーマップはこんな感じです

_lower = 1
_raise = 2
_adjust = 3

EscGUI = KC.MT(KC.ESC, KC.RGUI)
LowMins = KC.LT(_lower, KC.MINS)
AdjEnt = KC.LT(_adjust, KC.ENT)
AdjMins = KC.LT(_adjust, KC.MINS)
RaiEnt = KC.LT(_raise, KC.ENT)
Sands = KC.MT(KC.SPC, KC.RSFT)

keyboard.keymap = [
    # default layer
    [
        KC.QUOT, KC.COMM, KC.DOT , KC.P   , KC.Y   ,  KC.F   , KC.G   , KC.C   , KC.R   , KC.L   ,
        KC.A   , KC.O   , KC.E   , KC.U   , KC.I   ,  KC.D   , KC.H   , KC.T   , KC.N   , KC.S   ,
        KC.SLSH, KC.Q   , KC.J   , KC.K   , KC.X   ,  KC.B   , KC.M   , KC.W   , KC.V   , KC.Z   ,
                          KC.NO  , EscGUI , LowMins,  RaiEnt , Sands  , KC.NO
    ],
    # lower
    [
        KC.QUOT, KC.COMM, KC.DOT , KC.P   , KC.Y   ,  KC.CIRC, KC.AMPR, KC.UP  , KC.LPRN, KC.RPRN,
        KC.A   , KC.O   , KC.E   , KC.U   , KC.I   ,  KC.HOME, KC.LEFT, KC.DOWN, KC.RIGHT, KC.BSPC,
        KC.SLSH, KC.Q   , KC.J   , KC.K   , KC.X   ,  KC.END , KC.ENT , KC.LBRC, KC.RBRC , KC.DEL ,
                          KC.NO  , EscGUI , LowMins,  AdjEnt , Sands  , KC.NO
    ],
    # raise
    [
        KC.N1  , KC.N2  , KC.N3  , KC.N4  , KC.N5  ,  KC.LBRC, KC.RBRC, KC.TAB , KC.SLSH, KC.QUES,
        KC.N6  , KC.N7  , KC.N8  , KC.N9  , KC.N0  ,  KC.PIPE, KC.BSLS, KC.GRV , KC.EQL , KC.RSFT,
        KC.LCTL, KC.LSFT, KC.J   , KC.K   , KC.X   ,  KC.ENT , KC.PLUS, KC.TILD, KC.NO  , KC.RSFT,
                          KC.NO  , EscGUI , AdjMins,  AdjEnt , Sands  , KC.NO
    ],
    # adjust
    [
        KC.EXLM, KC.AT  , KC.HASH, KC.DLR , KC.PERC,  KC.CIRC, KC.AMPR, KC.ASTR, KC.LBRC, KC.RBRC,
        KC.NO  , KC.NO  , KC.NO  , KC.NO  , KC.NO  ,  KC.PIPE, KC.BSLS, KC.GRV , KC.LCBR, KC.RCBR,
        KC.F1  , KC.F2  , KC.F3  , KC.F4  , KC.F5  ,  KC.F6  , KC.F7  , KC.F8  , KC.F9  , KC.F10 ,
                          KC.NO  , EscGUI , AdjMins,  AdjEnt , Sands  , KC.NO
    ],
]