Skip to content

理想の分割キーボードを自作

その他の工作KiCadArduinoC/C++

WARNING

正しい情報を記載するよう努めていますが、それはそれとして当方は一切の責任を負いかねます。

いかなる作業も自己責任で行っていただくようお願いいたします。

はじめに

諸々のデータはGitHubにて公開しております。

asumo-1xts/J2J github.com Just the Two of JIS - My ideal split keyboard.

最終的に完成したもの

最終的に完成したもの

動機

JIS配列かUS配列か?という問いに対して、私は

  • 基本的にはUS配列
  • ただしEnterキーはJIS(ISO)
  • あと変換 / 無変換キーも欲しい

という回答を持っています。そこでJIS配列のREALFORCE R3Sを買ってきて

  • Windows側の設定でUS配列キーボードとして認識させる
  • キーキャップの印字を対応させるため、スライダーをDES-Slidersに全交換してCherry MX軸に対応

というライト魔改造を施し2年ほど使ってきたのですが、その分割バージョンが欲しくなりました。

AliExpressで買ったキーキャップがかわいいAliExpressで買ったキーキャップがかわいい

AliExpressで買ったキーキャップがかわいい

当然そんなものはありません。仕方がないので、Just the Two of JIS[1]と銘打って理想の一台を作ってみることにしました。

教材

基本的には以下の教材に従って作業を進めたので、本稿ではそれに補足する形でtipsを共有できればと思います。なおとても良い書でした。やる気はあるけど何をやって良いか分からないぜ!という方は必読です。

自作キーボード設計ガイド Vol1 設計入門編 - 自キ温泉街販売所 - BOOTH booth.pm 自作キーボードの設計入門本です。 表紙にもなっている分割型のキーボードであるGuide68というキーボードの設計を例にし、方針の決定から実際の設計、ファームウェアの作成までを丁寧に解説しています。 また、手順に直接関係ありませんが、キーボードの構造やファームウェアの種類、果ては自動配線ツールの使い方までも解説しており、自作キーボード設計を趣味として続けるために必要十分な情報を記載しています。 推奨ハッシュタグ:#自キ設計ガイド

環境

  • Windows 11
  • QMK 1.2.0
  • KiCad 10.0.1
  • FreeCAD 1.1.1

構想

改めてキー配列から考え始めて、以下のような仕様に落ち着きました。

項目仕様
接続・給電有線のみ
レイアウト疑似JIS 64キー
= US 64キー + ISO Enter + LANG1, LANG2
キーマップ変更
ホットスワップ
LEDライティング
完成してから気付いたけど、Bキーは右手側の方が良かった

完成してから気付いたけど、Bキーは右手側の方が良かった

また、以前何かの拍子に購入したKailh Deep Sea Silent mini Isletを手元で持て余していたので、ひとまずロープロファイルで作ることにしました[2]

PCB基板

兎にも角にも、回路図を引いてPCB基板を設計します。

左手側 | 右手側左手側 | 右手側

左手側 | 右手側

ProMicroを諦めよう

自作キーボードのデファクトスタンダードに倣ってSparkFun ProMicroを使う気でいたのですが、キースイッチの裏にProMicroを隠そうとするとキーボードがその分だけ分厚くなってしまうことに気付きました。かと言ってキースイッチの無いところにProMicroを置くと今度はキーボードの面積が大きくなってしまいます。

仕方が無いので、SparkFunが公開しているProMicroの回路図を基に、ATmega32u4およびその他の関連部品を自前で基板に直付けすることにしました。

これには以下のような嬉しさが付いてきます。

  • ProMicroが引き出さずに余らせているATmega32u4のI/Oピンをフル活用できる
  • 別にArduinoとして使うわけではないので、ブートローダーを書き込む苦労について心配しなくて良い
IC周りの配線で気が遠くなる!本職の方々はすごいIC周りの配線で気が遠くなる!本職の方々はすごい

IC周りの配線で気が遠くなる!本職の方々はすごい

おすすめフットプリントライブラリ

キースイッチのフットプリントは有志の方々がGitHubに公開してくれているものを使うと良いのですが、如何せん(自作キーボードのコミュニティが広大なおかげで)選択肢が複数あって迷ってしまうかもしれません。私が試した限りでは、「PCBエディタのグリッド間隔を1/8 u (= 19.05/8 mm)にしたとき確実にぴったり並んでくれる」という点においてkoktoh氏の公開しているライブラリが最も良かったです。

koktoh/BrownSugar_KBD_KiCad_Library github.com

Cherry MXシリーズしか収録されていないのでKailh Chocシリーズ等を使う場合には他のライブラリを探す必要がありますが、それでも一旦はこのライブラリのフットプリントで並べておいて後から置換すると確実です。

発注

配線とビアを何とか引き回して、JLCPCBに発注しました[3]

TIP

RGBカラーLEDの定番であるWS2812BやSK6812MINI-EはJLCPCBのPCBAサービスにおいてエコノミープラン対象外らしく、実装してもらうためにはさらに大きめのお金を積んでスタンダードプランで発注する必要があるとのことでした。大量生産する訳でもないので今回は自前で買ってきてはんだ付けしました。

ファームウェア

ソースコードを貼ると長くなってしまうので、冒頭のGitHubリポジトリを参照してください。

幸いにも教材のお手本モデルが分割キーボードだったので、QMK周りであまり躓かずに済みました。QMKは現在も開発が続いており、特にその破壊的変更の影響で新しそうに見えるネット上の情報が少し古かったりします[4]

不要な機能を無効化してファームウェアを削れるだけ削って、

  • 電源投入時・スリープ時のLEDアニメーション
  • MIDIモード

まで実装できました。

TAP機能だけは公式な方法で無効化できず謎のエラーを吐いたので、Vial-QMKのquantum/ディレクトリにあるソースファイル3つを下記の通り手元で編集してしまいました。

c
// 他の部分はそのまま残す

#ifdef FLOW_TAP_TERM
    flow_tap_update_last_event(record);
#endif FLOW_TAP_TERM
c
// ほとんど全削除!
// 完全に白紙にしてしまうとmakeが通らなくなるので以下を残す

#ifndef NO_ACTION_TAPPING
#endif
c
#pragma once

#ifndef TAPPING_TERM
#define TAPPING_TERM 200
#endif

#if !defined(QUICK_TAP_TERM) || QUICK_TAP_TERM > TAPPING_TERM
#define QUICK_TAP_TERM TAPPING_TERM
#endif

#ifndef TAPPING_TOGGLE
#define TAPPING_TOGGLE 5
#endif

#ifndef NO_ACTION_TAPPING
uint16_t get_record_keycode(keyrecord_t *record, bool update_layer_cache);
uint16_t get_event_keycode(keyevent_t event, bool update_layer_cache);
void action_tapping_process(keyrecord_t record);
#endif

uint16_t get_tapping_term(uint16_t keycode, keyrecord_t *record);
uint16_t get_quick_tap_term(uint16_t keycode, keyrecord_t *record);
bool get_permissive_hold(uint16_t keycode, keyrecord_t *record);
bool get_retro_tapping(uint16_t keycode, keyrecord_t *record);
bool get_hold_on_other_key_press(uint16_t keycode, keyrecord_t *record);

#ifdef CHORDAL_HOLD
bool get_chordal_hold(uint16_t tap_hold_keycode, keyrecord_t *tap_hold_record,
                      uint16_t other_keycode, keyrecord_t *other_record);
bool get_chordal_hold_default(keyrecord_t *tap_hold_record,
                              keyrecord_t *other_record);
#endif

#ifdef FLOW_TAP_TERM
bool is_flow_tap_key(uint16_t keycode);
uint16_t get_flow_tap_term(uint16_t keycode, keyrecord_t *record,
                           uint16_t prev_keycode);
#endif

#ifdef DYNAMIC_TAPPING_TERM_ENABLE
extern uint16_t g_tapping_term;
#endif

#if defined(TAPPING_TERM_PER_KEY) && !defined(NO_ACTION_TAPPING)
#define GET_TAPPING_TERM(keycode, record) get_tapping_term(keycode, record)
#elif defined(DYNAMIC_TAPPING_TERM_ENABLE) && !defined(NO_ACTION_TAPPING)
#define GET_TAPPING_TERM(keycode, record) g_tapping_term
#else
#define GET_TAPPING_TERM(keycode, record) (TAPPING_TERM)
#endif

#ifdef QUICK_TAP_TERM_PER_KEY
#define GET_QUICK_TAP_TERM(keycode, record) get_quick_tap_term(keycode, record)
#else
#define GET_QUICK_TAP_TERM(keycode, record) (QUICK_TAP_TERM)
#endif

ファームウェア容量はかなりギリギリで警告も出ていますが、ちょっとした処理ならまだ追加できそうです。

shell
Checking file size of j2j_vial.hex  [WARNINGS]

* The firmware size is approaching the maximum - 27810/28672 (96%, 862 bytes free)

筐体

設計

当初はPC基板3枚による単純なサンドイッチ方式を考えていたのですが、周囲にスペーサーを積層して隙間を無くしたいなと思い直し、どうせならプレートと周囲のスペーサーを一体化して3Dプリントするのが良いのでは?というところに行き着きました。

私は3DCAD全般があまり得意でないので、KiCadで平面パーツを作ってSTEPファイルに書き出してから、FreeCADでそれらを縦に積みました。A2plusというワークベンチを利用して面と穴の拘束条件を与えると所望の立体が完成します。最後にそれぞれ結合させるのをお忘れなく!

ImageGroup - big

TIP

KiCadの基板厚はPCBエディタの「ファイル > 基板の設定 > 物理的スタックアップ」から設定できます。基板ではない、ただのオブジェクトとして3Dモデルに出力したときの最終的な厚みは、中央の「誘電体 1」の値がそのまま反映されることにご注意ください。

このウィンドウはKiCad v9のものです

このウィンドウはKiCad v9のものです

試作

上下方向のクリアランスを考えるのが大変でノイローゼ気味になってしまったので、よほどの空間把握能力をお持ちでない限りは、ある程度まで煮詰まったら安い材料で発注してしまうのが精神衛生のためかもしれません。こういうのって実物の有無で全然違うなと思います。

私の場合は幸運にも会社の同期が3Dプリンターを持っていて、STEPファイルを渡したら全部やってくれました。ありがとう…

持つべきものは3Dプリンターを持っている隣人

持つべきものは3Dプリンターを持っている隣人

なおこれらの固定方法について、3DプリンターでM2ねじのタップを切るのはどうやら非現実的らしいと聞いてセルフタップを採用しました。表側のアセンブリとPCB基板にはΦ2.0 mmの通し穴を、裏側のアセンブリにはΦ1.6 mmの下穴をそれぞれ開けています。

発注

各アセンブリは最終的に以下のようになり、JLC3DPに投げました。

アセンブリ役割 / 備考厚み [mm]
表面プレート
+ スペーサー①
キースイッチをはめ込んでPCB基板までの隙間を埋める。
無くても良いけどあると見栄えが良い
1.2 + 1.0
(PCB基板)最低限これさえあれば良い1.6
スペーサー②
+ 裏面プレート
裏面プレートまでの隙間を埋める。
厚くしすぎるとフィラメント代が嵩むので注意
5.4 + 1.8

組み立て・完成

届いた!まずは基板にファームウェアを書き込んで、適当なキースイッチ端子を導通させてみて、PCにキーボードとして認識されていることを確認します。個人的にここが大きな緊張ポイントだったのですが、大丈夫そうだと分かったのであとは無心で組み立てるのみです。

届いてすぐの状態 | ソケットとLEDを実装 & UVカットスプレーを吹いた状態届いてすぐの状態 | ソケットとLEDを実装 & UVカットスプレーを吹いた状態

届いてすぐの状態 | ソケットとLEDを実装 & UVカットスプレーを吹いた状態

基板を透かしたくて裏面にはクリアレジンを採用しましたが、黄ばみが怖いのでUVカットスプレーを吹いたら半透明になりました。すりガラスみたいで可愛いのでヨシ。

タップを切る工程が一番ドキドキしましたが、割れることもなく無事にねじが通りました。

ImageGroup - doubleImageGroup - double

完成!

贔屓目を抜きにしてもめちゃくちゃ良いです。PCB基板と裏面プレートの間のスペーサーを、部品の合間を埋めるようにして隈なく入れておいたのが正解で、少々お値段が張るのと引き換えにしっかりとした打鍵感を得られています。

1台あたりの原価の概算

ちょっと信じられません。人件費を抜いてこの金額???普通に新品のREALFORCEを買うお金でフルオーダーメイドしたと思えば、まあ…という感じでしょうか。今更ながら大量生産品の価格競争力はすごいです。

部品数量価格(円)
PCB基板左右1組5500
Kailh Choc V2 キースイッチ87個4200
Kailh Choc V2 HotSwapソケット87個1300
Kailh Choc V2 スタビライザー4個300
SK6812MINI-E フルカラーLED87個700
ケース左右上下1組5000
M2 12mmタップねじ42本600
ロープロファイル用キーキャップ1組3300
3.5mm TRRSケーブル1本850
USB Type-Cケーブル1本0
合計21750

おわりに

原価を直視して気が遠くなりましたが、職業プログラマたるもの一度はキーボードの自作を…と長らく思っていたのでなかなか感慨深いです。実物を手にしたときのテンションの上がり具合が思っていたよりずっと高い。MIDIコントローラ然り、「欲しい仕様のものが無いから自分で作る」という純粋なDIYを定期的にやれると良いなと思います。

皆さんも拘りの自作キーボードで周囲のプログラマを威嚇しましょう。



  1. We can make it if we try ... ↩︎

  2. 後から分かったことですが、私は同シリーズのWhale(軸が茶色のやつ)の方が好きでした ↩︎

  3. Enterキーに2uスタビライザー用の穴を空け忘れて一敗 ↩︎

  4. 特にconfig.hkeyboard.jsonの役割が重複しているのが気になる… ↩︎

CC-BY-SA-4.0