Introduction

キーボードを作りたくなった。
いまの仕事を抽象化すれば、キーボードを叩く仕事です。ただ、ノートPCのパンタグラフ式キーボードは打鍵音が高くてうるさい。
転職して組み込み半導体に関する仕事をするようになったので、USBペリフェラルの勉強もかねて自作キーボードに挑戦した。


1. 構想と勉強

キー配置を決め、キーボードの仕様を固めていく。また、ソフトウェア開発で重要となるUSB通信の基礎を学ぶ。

1.1. キー配置

理想のキー配置を考えるが、型にはまった思考しかできないので、結局ありきたりなISO60%になった。守破離の守ってことで。
60%レイアウトは、特殊キー(矢印、page upなど)とファンクションキーが無い分、コンパクトな構成だ。ただ、矢印キーはコーディングで頻繁に使うので、スペースキーの幅を減らして、キースペースを確保した。

キー配置はkeyboard-layout-editor.com(kle)でデザインを作成した。後の基板設計でこのデータを使うので、ページ右上の[Download]からJSONファイルをダウンロードしておく。

1.2. 部品選定

キーボード部品の選定

自作キーボードの一番の楽しみは、遊舎工房でお気に入りのキースイッチとキーキャップを探すことだと思います。
僕は”LeleLab Supsup SuperX White Keycap“というスケルトンのキーキャップに魅了されたので、これに合うキースイッチを選んだ。
キースイッチとキーキャップ、スタビライザーを購入して、合計13,694円。

回路部品の選定

まず、回路の主要部品となるMCUを選定した。JLCPCBのPCBAサービスを利用してPCBを作製するので、そのサービスで利用できる部品の中から選定する。また、後述のファームウェア開発でQMKを使いたいので、対応MCU一覧に記載されているSTM32F072を採用した。
他の部品については、以下のとおりです。

Category Parts Number Detail
MCU STM32F072VBT6 外付け水晶振動子(48MHz)無しでUSB機能を使える。ピン数が多いパッケージ(LQFP-100)なのでパターン設計が楽(←めっちゃ大事!)。
USB U262-161N-4BVC11 USB-Cのレセプタクル。この世の全てのケーブルをtype-Cで統一したい
LDO LM3940IMPX-3.3/NOPB USB電源からMCU電源を生成する低損失のLDO。出力電流は1Aもいらないと思うけど、ヒートシンク無しだから余裕をもって
ESD ESD122DMXR USBのデータラインのESD対策
Schottky Diode SS34 USB電源(VBUS)への逆流防止用
Diode 1N1418W キーマトリクス用の整流ダイオード


1.3 ファームウェア

自作キーボードはハードウェア(HW)設計がメインで、ファームウェア(FW)はQMKというオープン・ソースのFWを使うのが一般的らしい。キー配置のjsonを作成してビルドすれば、FWを簡単に生成できるので、FW開発の面倒さがない。最高やん!
僕自身、FWへのこだわりはなく、マクロ機能を追加したいくらい。QMKで十分である。

USB機器の勉強

QMKを使うなら、USBペリフェラルの動作を気にする必要はないですが、せっかくなのでUSBの基礎知識を以下の資料で学んだ。

2. ハードウェア作製

PCB設計・発注、ケース3Dプリントまでの製作過程をまとめる。大まかな流れは以下のとおりです。

  1. KiCADで回路図設計
  2. KiCADでPCBレイアウト設計
  3. JLCPCBで基板作製の注文


完成したキーボードはこちら。


2.1 回路設計

まず、回路図を設計する。
KiCADを触るのは8年ぶりなので、使い方の勉強から始める。調べながらやっていくよりも体系的にまとまった資料を読んだ方が早いので、適当な入門書を借りてHands-Onした。
キーボードの回路はシンプルなので、自作キーボード界隈の先人の回路図を読めば、必要な機能を把握できる。
私の作成した回路図もGitHubにあげているので、参考になれば幸いです。

回路の主な特徴は

  • USB-Cレセプタクル
    USBの仕様で、22Ωのダンピング抵抗やCCラインのプルダウン抵抗、データ線のプルアップ抵抗が必要。(参考: STM community)
  • 電源回路
    USBのVBUS(5V)→ ショットキーバリアダイオード(SBD)→ LDO → MCU電源(3.3V)
  • ESD
    静電気対策でUSBのデータ線にはESD保護を付けている。USBでなくても、外部I/Fをもつ信号ラインにはESDは必須。
  • キーマトリクス回路
    ikejiのblogを参考にしてください

2.2 レイアウト設計

次に、PCBのレイアウトを設計する。キーボードのレイアウト設計で便利なツールを紹介する。

  • キースイッチのlibrary
    foostan/kbdをインポートする。
    回路設計の嫌いな作業ランキング1位「部品ライブラリの作成」を回避できます。
  • kicad-kbplacer
    kicad-kbplacerというプラグインをインストールする。
    kleで作成したキー配置のJSONファイルから、PCB上でキースイッチを自動配置してくれるツール。
    回路設計の嫌いな作業ランキング同率1位「PCBの部品配置」を回避できます。
  • デザインルール
    PCBを発注するならば、基板メーカーの設計ガイドラインに準拠する必要がある(参考: KiCad)

ちなみに、回路設計の嫌いな作業ランキング同率1位「パターン設計」は回避できません。数が多いから面倒くさい。


2.3 PCB発注

KiCADの設計データをもとに、JLCPCBへ発注する。

JLCPCBはPCBを作るだけでなくて、そのPCBに電子部品をはんだ付けしてくれるPCBAサービスをやっている。 自分でチップコンデンサやICを購入して、はんだ付けするコストを考えると、JLCPCBに任せる方が安上がりなので、今回はPCBAサービスを利用する。 PCBAサービスの利用方法は、JH4VAJさんのブログを参考にしてください。
KiCADでガーバデータとBOMを作成したら、JLCPCBの注文画面でアップロードするだけ。

参考までに、PCBの作成が$20.6、PCBアセンブリサービスが$101.34で、送料とクーポンを合わせて$126.14(=20,725円)だった。(財布が)厳しいって。

注文して2日で出荷。仕事が早すぎる。

届いたPCBにキースイッチと電解コンデンサをはんだ付けして、ハードウェアの回路部分は完成。

2.4 ケース作製

Fusion360で設計して、JLC3DPで3Dプリントしてもらった。

画像のようなキーボードの土台となる部分を印刷してもらう。金欠だから、上側のカバーは無い。

印刷方式はSLAで材料は9600 Resin、値段は$24.75。送料と割引クーポンを合わせて$35.28(=5,737円)だった。

注文時期がLunar New Yearとかぶってしまったので、2週間ほどかかったが、平常時であれば1週間で出荷するらしい。便利な世の中になったな~。


3. ソフトウェア作成

QMKと自作ファームウェア、それぞれの開発をまとめる。
QMKを使うつもりだったが、接続周りのデバッグをしていたら、結局ファームウェアも自作した。詳細は省略する。

3.1. QMK

QMKは、自作キーボード向けのオープンソースファームウェアフレームワーク。
MCUのピン配置やキーマトリクスなどのハードウェア情報keyboards/ディレクトリに、キー配置やレイヤー・マクロなどのロジックをkeymap.cに定義して、qmk compileコマンドでビルドすれば、FWが完成する。コードを書かなくていいけど、定義ファイルの量が多すぎて、自動化スクリプトが欲しい。

  • 開発環境: Ubuntu 22.04
  • Debugger Probe: ST-LINK v2
    • MCUへのFW書き込み・デバッグ用

3.2. 自作ファームウェア

次節の4. つまづきのとおり、開発の途中で発生した問題の解決のため、FWを自作した。ソースはGitHubで公開している。

  • 開発環境: Windows 11
  • IDE: STM32cubeIDE v1.18.1
    • 最新バージョンではGUIのコンフィグツールSW4STM32がIDEと別々になって、使いにくいので昔のバージョン
  • Debugger Probe: ST-LINK v2

特徴的な機能は

  • JIS配列
    ISO60%の物理配置はそのままに、キーコードだけJIS配列へ割り当てている。キーキャップはUS配列なので、キーコードとキーキャップの動作が一致するように頑張って設定した。
  • マクロ
    特定のキーを押すと、複数のキー入力を連続で送信できる。ログイン処理や、よく使う定型文の入力を1キーに割り当てている。
  • レイヤーキー
    Fnキーを押している間だけ、他のキーの役割を切り替えられる。60%レイアウトで足りない機能をこのレイヤーに割り当てて補っている。

4. つまづき

いろいろ多分、思うようにはならへん。

— 岡林風穂『キャットファイト』

Ubuntu PCに挿して使おうとすると、なぜかキー入力をできない。何回も挿しなおしたら、たまに入力できるけど。
ターミナルでlsusbコマンドを使って、PCに接続されているUSB機器一覧を表示すると、確かに表示されている。キーボードの電源LEDも光ってるから、USBコネクタの接触不良ではなさそう。なぜだろう。
試しに、別のWindows PCへ接続すると、キーボードが認識されない。デバイスドライバに表示されてないじゃん。

FWの問題かもしれないと考えて、QMKから自作ファームウェアに変更した。しかし、状況は変わらず。

ようやく「ハード側に問題があるかもしれない」と気づき、USB周辺の回路図を見直す。

CCやMCUとの接続は問題がなさそうなので、クロックに問題があるかもしれない。
「crystal-lessの力を過信したな」と言われてる気がした。(百錬三郎)

ただ、PCBにテストピンを付けていないので、オシロスコープでクロック波形を観察するのが面倒だった。この検証は後回しにしよう。

回路の問題の99%は設計者による技術資料の確認不足が原因(ソース不明)なので、STM32F072のデータシートとリファレンス・マニュアルのUSBに関する内容を読み直す。

データシートの3.21 Universal serial bus (USB)を読むと、

The STM32F072x8/xB embeds a full-speed USB device peripheral compliant with the USB specification version 2.0. The internal USB PHY supports USB FS signaling, embedded DP pull-up and also battery charging detection according to Battery Charging Specification Revision 1.2. The USB interface implements a full-speed (12 Mbit/s) function interface with added support for USB 2.0 Link Power Management.

と書いてある。
データラインのプルアップ抵抗は内蔵されていて、転送速度はFSに設定されてるんかい!

キーボードはLSが一般的なので、USB_DMへプルアップ抵抗を接続していた。(下図の赤枠)
しかし、そのせいで、データラインが両方プルアップされてしまい、ホスト側で転送速度が分からなくなっていたらしい。


プルアップ抵抗R5を基板から外して、無事解決しました。
ちなみに、Ubuntuでたまに動く理由は、OSのUSBスタックが転送速度が異常でも寛容だから。


Summary

キーボードのキーキャップ以外を自作した。茶軸の「スコスコ」とした打鍵音が良い。
IKEA効果も相まって、気に入っている。

…総額40,156円。あれ?HHKBを購入できる金額では?
これが、大量生産の妙か。