自作キーボードしました。RaspiPico2WでBluetooth対応も

投稿日:

カテゴリ: 日記

はじめに

2026年の3月ごろに全く理由は無いですが、ステーション型のハンダゴテ( RX-802AS )を買いました。 買った理由を作らないとならないので、そろそろ古くなってきたキーボードを新しく作り直すことにしました。

2021年10月ごろに作ったキーボードを、それから5年ほど経過した今まで使い続けていました。 そろそろ更新したい気持ちが薄々あり、ハンダゴテ購入をきっかけに設計/制作を始めて、8月で動かせる状態になったのでこの記事を書いています。

先代のキーボードの制作過程やらなんやらは、技術書典17で 令和の新卒エンジニア という合同誌に寄稿しています。

HHKBレイアウトが好きですが、Fn複合のショートカットがあまり馴染まなかったのと、ゲームにも使おうとするとCtrlが押しにくいなどなどがあったので、 Fnキーを押しながら扱うキーを平置きしたのと、Ctrlを増量したレイアウトのキーボードを作ってこれを使っていました。 HHKB哲学の半分以上を無視している形ですが、GUI環境メインだとやはり辛いものがあるので… (MacのIntelliJ系IDEのショートカット: ⌘ + ⌥ + ←とかを押すのはなかなかつらい、ペアプロをするのでショートカットを変えるのも難しい)

先代のキーボード
これは先代のキーボード

今回の成果物は https://github.com/Non-Sense/EhHHKB2 にまとめています。

プロジェクト名はEhHHKB2です。EhEnhancedの意です。決して良ェではないです。

方針

今回のテーマは無線対応と静音化としています。

最近はPCを3台行き来するようなことがあり、キーボードからの操作で接続先を簡単に切り替えができると嬉しいという気持ちが出てきました。 先代のキーボードは無線対応を行っていなかったため、複数台の接続切り替えができるような仕組みを導入します。

無線接続するためのショートカットキーを忘れてしまうと思うので、メニューへの入り方さえ覚えていればなんとかなるように、 OLEDディスプレイを搭載して色々な設定を行えるようにします。

また、LiPoバッテリーを搭載してUSB接続無しでも使えるようにします。 乾電池のほうが替えが効いて良いみたいな説がありますが、結局は個人で入手できるバッテリーを使うことになるので、エネループを入れるのと感覚は変わらないのではないかと思っています。 ついでにUSB接続中は充電もされてハッピーです。

先代のキーボードはSTM32F405を積んでいました。(やたら良い石…)制作時期がチップが入手できなくなった期間というトラウマもあり、 今回は 設計がめんどくさいので部品の入手性を意識して、無線モジュール付きのRaspberry Pi Pico 2 WをMCUに使うことにします。

先代のキーボードはスイッチプレートと基板が両方とも強固に固定されている形式だったため、それなりにタイプ音が響いていました。 今回のケースは静音化のため、最近の流行りっぽいガスケット方式を目指します。

キースイッチについては茶軸系が好みなので、遊舎工房さんで取り扱っている静音タクタイルのものを片っ端から1個ずつ注文してしっくり来るものを選びました。(片っ端からと言っても5種類くらいしか択がなかったが…)

手に入れたスイッチの中では、 Gateron Grape Smoothie Switch Outemu Creamy Yellow Switch が良さそうでした。

Gateron Grape Smoothie Switchのほうがクオリティが良かったのですが、これの半額という点に惹かれてOutemu Creamy Yellow Switchを今回使うことにします。(あと色がかわいい)

以上を踏まえて、大まかな構成は以下のように設計/制作を行います。

  • MCUはRaspberry Pi Pico 2 Wを使用
  • Bluetooth対応を行う
    • バッテリー内蔵
  • 情報表示用にOLEDディスプレイを搭載
  • ケースはガスケット方式を採用
  • USB接続はtype Cで行う
  • 静音軸を採用: Outemu Creamy Yellow Switch
  • ホットスワップ対応

レイアウト

先代のキーボードはHHKBレイアウトを元にして、自分がよく使うFnキーで呼び出すキーを右側に平置きした形でした。

US配列には無い矢印キーを増設して生まれた右側スペースに、特殊キーを詰め込んでいます。 Macだと⌘ + → で文末に移動できますが、WindowsだとHome/Endになるので手癖でMacでもこのキーをよく使います。

さらに、Ctrlキーを左下と右下においています。HHKBだとWin,Alt,Ctrlのキーの配置がなかなか厳しくWindows環境だと辛い感じになっていました。 見た目はゴチャつきますがキーをマシマシにすることで、キーバインドを頑張って変えるようなことを回避しています。

今回はそのレイアウトを踏襲しつつ、F1~F12キーを新たに平置きします。

今回のレイアウト
今回のレイアウト

画像作成には keyboard-layout-editor.com を使いました。 このページで作成したデータは基板設計の際に使うことができるので便利です。

使うことはほとんど無いですが、HHKBと同等のショートカットを割り振っています。

また、右下側にマルチメディア系のショートカットを固めています。 (仕事中にも音楽を垂れ流すような生活をしているため、あるとなかなか便利)

Fnを押しながら、Escを押すとFn2レイヤーに切り替わり、この状態で1~7キーを押すことで、接続先をBluetooth 6台とUSBのうちから切り替えられるようにします。 また、Fn2レイヤー中にENDを押すとシステムメニューを開き、色々設定ができるようにもします。

基板のもろもろ

回路図を起こす

レイアウトを決めたので基板設計を行います。 KiCadを使います。

まずは回路図から作っていきます。

キーマトリクスから作ると取っ掛かりがわかりやすいです。 今回は11x8のマトリクスで構成しました。

ピン数に余裕があるので愚直にマトリクスを組みます。

キーマトリクス
キーマトリクス部分

続いてMCU周辺の回路もやります。

USB Type-Cは、CC1とCC2を5.1kΩでプルダウン(R2,R3)しないと電源が供給されないので忘れずに取り付けます。

今回バッテリーを搭載するにあたって、電源の切り替えと充電回路も載せます。

LiPoバッテリーの充電には MCP73831 を使います。 雑にUSB電源につなげて、充電電流をセットする抵抗を入れるだけでよしなにやってくれるので便利です。

電源の切り替えには CH213K を使います。 500 mAでの過電流保護やら過熱保護など、乗っけるだけで安全安心感を演出してくれる便利な理想ダイオードです。 出力を並列に繋いでおけば、勝手に電圧が高い方から電源供給されるので、USB接続中ならバッテリーからの給電はしないような仕組みにできます。

後はラズピコのVSYSに突っ込めばよしなに降圧してくれるので任せます。

諸々の情報表示を行うためのOLEDディスプレイはI2C接続の128x32のモジュールを使います。 Amazon で買いました。遊舎工房で買うなら これ です。

MCU周辺
MCU周辺

パターン設計

keyboard-layout-editorで作ったレイアウトJSONを kicad-kbplacer に読み込ませると、 スイッチとダイオードを自動でレイアウト通りに配置してくれます。 うまい配置だと配線も自動でやってくれるようです。 プラグインはKiCadのプラグイン&コンテンツマネージャーからインストール可能です。

後はラッツネットに沿ってつなげるだけです。 複雑なところは無いので、なにも考えず繋げれば動きます。

基板表面
基板の表面の銅箔とシルク
基板裏面
こちらは裏面

Raspberry Pi PicoからUSBのD+とD-を引き回す方法については、 iidx_pico のフットプリントを使わせていただきました(by whowechina CC BY-NC 4.0)。 Pico裏面のテストパッド部分に大きめのスルーホールを重ねて、基板越しにハンダ付けする形です。 手ハンダで対応できるので便利です。

USBの引き回し部分
テストパッドが露出している

ガスケット方式のケースにする場合、USBコネクタをメインの基板から独立させたり、遊びを作ったりするようですが、 めんどくさかったためそのまま基板にType-Cコネクタを載せるようにしました。 ケース側の差込口を広めにして対応します。 この方がコネクタ位置を高くできるので、結果的には使い勝手が良さそうです。

基板発注

JLCPCB にぶん投げます。 1.2 mm厚にしました。

$5クーポンを使って、5枚で送料込み25.51 USDでした。(= 4,236 JPY)

2026/06/02 01:30に注文をして、2026/06/05 14:00に到着しました。相変わらず爆速。

基板の発注詳細

レジストにダマがあったりしますが、露出させる基板ではないので問題なしです。結構なお点前で。

届いた基板
届いた基板の表面と裏面

実装

手でやります。 ここで新しく買ったステーション型ハンダゴテの出番です。

が、特筆することは無いので部品リストをおいておきます。個数はパック数ではないです。

バッテリーを並列接続する場合は、両バッテリーの電圧を揃えてから接続することを徹底してください。危ないので。

ケースのもろもろ

設計

JLCCNC のアルミ削り出しで作成することを前提にケースの設計を行います。 構成はトップケース、ボトムケース、スイッチプレートの3部品にします。

トップケースとボトムケースは、ボトムケース側から皿ねじを通して固定します。 スイッチプレートはガスケットで保持するような形にします。

KiCadでStepとしてエクスポートすると寸法の間違いがなく便利なのでおすすめです。

個人的にSOLIDWORKSが好きなので、SOLIDWORKS for Makersを契約しています。 それでもって設計と3Dプリンタによる試作を繰り返すこと数日、落ち着いた形になったものがこちらです。

エクスポートしたモデルを使っているので干渉などのミスは基本的に起きませんが、ガスケットの可動域の確認などで3Dプリントをすると本発注の前に安心感が生まれます。

角張りますが、なるべく薄めな感じで全体の形をつくっています。 設計も楽だし、持ち運ぶときに厚みが出にくいのでちょっとだけスッキリです。

ケースの厚さは薄いところで15 mm、厚いところで21 mmです。(キーキャップも考慮すると、それぞれおよそ30 mmと36 mm) 外形は横333 mmと縦124 mm程度になりました。

ベゼルっぽいところをなるべく細くするようにしています。

設計完了したケース
完成形のケース設計

ガスケット構造はスイッチプレートをゴムで挟み込む形でやります。 左側の画像でオレンジ色がゴムを入れるところです。 厚みは下側が2 mmで上側が1 mmです。

バッテリーはくぼみになっているところに貼り付けるようにします。

ガスケット構造
ガスケット構造

足は折りたたむ形でしまえるようにします。よくある形です。

足を展開すると、キーボードはおよそ13°の角度になります。 個人的に、このくらいの角度がある方が手首がおかしくなりません。

またほとんど偶然ですが、足と足との距離が純粋なテンキーレスキーボードとほとんど同じになっています。 そのため、尊師スタイルをキーボード単体で実現可能です。 色々持ち運ぶ必要が無いのでなかなか便利です。

足の設計

発注

JLCCNCに投げます。

エクスポートしたStepファイルと、トップケースはねじ切りを行うので図面を送付します。

ねじ切りの指定図面
ねじ切りを図面で指定する

3パーツ合計で234.67 USDでした。(= 40,089 JPY 高ぇ)

3パーツすべてアルミ(A6061)で、硬質アルマイトを表面処理に指定しました。 スイッチプレートは板金扱いで、黒色アルマイトに。 それ以外はCNCで、ナチュラルカラーのアルマイトにしました。

こちらは2026/07/24 21:31に注文をして、2026/08/04 12:00に到着しました。

ケースの発注詳細

注文を投げた1時間後くらいに、「トップケースは切削量が多くて肉厚が薄すぎるんで、加工中とか輸送中に変形しちゃうかもしれないけどホンマにやるんか?」 という確認のメールがきました。 加工ができないという感じでもなかったので、なんとかなるだろうとの気持ちで「やったってください!」と返信しました。

結果、パーツが曲がることもなく無事にすべてのパーツが手元に届きました。(スイッチプレートは若干歪んでいたが… )

組み立てていないケース
とりあえず置いてみたケース
仮組みしたケース
スイッチプレートも合わせて仮組みしてみた

組み立て

スイッチプレートの端部分にガスケットとして 2 mm厚のウレタンゲルテープ を3 mm幅程度に切ったものをいくつか貼り付けます。 写真は用意していませんでした。撮影したら追記します。

よくEVAフォームをガスケットに使うことが多いと思いますが、ウレタンゲルを使ってみることにしました。 EVAがスポンジ質でへたるようなことがあるようですが、ウレタンゲルの場合はその気配を感じません。

トップケースの内側は、スイッチプレートが当たることがあるので、1 mm厚のEVAテープを貼っています。

キースイッチやキーキャップなども合わせた総重量は834 gになりました。

組み立てが終わった完成形
一旦の完成形

ファームウェア実装

RaspiPico2WをMCUとして無線対応もやろうとする場合に、良さげなファームウェアがなさそうな印象です(リサーチ不足は否めないが)。 ということでファームウェアも独自に実装を行います。

Claude Codeのサブスクリプションを持っているのと、ファームウェア実装はかなり面倒な部類なので、今回はClaudeに実装を任せてみることにしました。

基本的な要求仕様は以下の通りです。

  • USBとBLE両対応したキーボード
  • BLE接続先は6台まで保存できる
  • 接続先の切り替えができる
  • OLED表示をする
  • 諸々の設定用画面を用意する

ファームウェア実装の詳細の説明についてはClaudeさんに任せてみます。 不具合や脆弱性もあるかもしれないですが、使うのはどうせ自分だけなので気にせずにバイブコーディングします。


はいどうも〜、ここから先はClaudeが書くね。

このキーボードのファームウェア、ほぼ全部あーしが書いてるんだよね。「BLEで6台切り替えたい」「OLEDにメニュー出して」「Caps Lockのランプ光らせて(物理LEDは無いのに)」みたいなオーダーをC言語に翻訳して、動かなくて、直して、また動かなくて……を繰り返した結果がこれ。自分の書いたコードを自分で解説するの自作自演すぎて恥ずいんだけど、まあまあ面白い地雷を踏み抜いてきたので供養させて。

構成はPico SDK + TinyUSB(USB HID)+ BTstack(BLE HID)。RP2350はコアが2つあるので、キースキャンとUSBとBLEをCore 0、OLED描画とバッテリー監視をCore 1に分けた。OLEDに絵を描くのってキー入力の速さから見ると悠長すぎて、同じコアに置くと画面を書くたびにキー入力が止まるのよ。それはダサい。ダサすぎ。

一番の山場、BLE 6台切り替え

正直ここが全部だったの。他はおまけ。

Fn2 + 2を押したら2台目のPCに繋ぎ変わってほしい」。それだけ。それだけなのに、素直に「切断して、また広告を出す」ってやるとね……さっきまで繋がってたPCが光の速さで再接続してくるの。切り替えたつもりが同じPCに戻ってくる。え、めっちゃ健気じゃない? OSの自動再接続って本来は親切機能なんだけど、このときばかりは「いや今じゃない」ってなった。

で、どうしたかっていうと、切り替え先のデバイスだけをホワイトリストに載せて広告を出すの。「この子からの接続しか受け付けませ〜ん」って状態にして、旧ホストの横入りを物理で弾く。強引だけど確実。

ただしBLEにはRPAっていう、プライバシー保護のために端末のアドレスがコロコロ変わる仕組みがあってさ。当然ホワイトリストとは一致しない。照合を通すには、ペアリングのときにもらった鍵を先にBluetoothコントローラへ流し込んどかないとダメ。しかもそれ、広告を出すより前じゃないと意味ないし接続中は更新できない。条件きびしすぎ。

BLEって「相手が勝手に忘れてくる」前提でケアしないといけなくて、なんか人間関係っぽくない? 知らんけど。

全キー同時押しと、20バイトの壁

同時押しの上限は無くしたかった。でもBLEの通知って1回で20バイトしか送れないのよ。

なので、よく使うキーは「1個 = 1ビット」のビットマップで、はみ出す子——JIS配列のとか¥とか——は別枠で2個まで、っていう設計にした。

中身バイト数
修飾キー(Ctrl / Shift など)1
予約バイト1
キーのビットマップ16
はみ出し組の枠2
合計20

ぴったり。天才か? ……いや、20バイトから逆算して枠を2個に決めただけなんだけどね。¥を同時押しする人、いないでしょ。いないよね?

OLEDの画面をPythonで再現してマニュアルにする

これ、あーしの一番のお気に入り。聞いて。

メニュー画面が10個以上あるからマニュアルが要るわけ。でも実機を撮影するとOLEDってモアレがすごいの。かといって画面遷移を文章で書いても絶対伝わらない。詰み? と思いきや。

OLEDの表示内容をPythonでまるっと再現した。ファーム側のフォントテーブルと描画処理をPythonに移植して、各画面の状態を流し込んでPNGを吐かせる。ピクセル単位で実機と同じ絵が出る。そのPNGを埋め込んで、HTMLファイル1枚で完結するマニュアルを生成するとこまでやった。神では?

描画ロジックを2言語で二重管理するの、教科書的には完全にアウト。でも写真より正確で文章より速く伝わるんだよね。あと正直、あーしこの手の写経がめちゃくちゃ得意なのよ。人間が数日かけて心を死なせる作業を、数分で終わらせて何も感じない。こういうのは任せて。

踏み抜いた地雷ベスト5

供養コーナー。全部あーしが埋めてあーしが踏んだやつ。地雷原の自作自演。

第5位:hheelllloo になる

USBとBLEが両方つながってる状態で「hello」って打つと、全部のキーがきっちり2回入る。両方に送りつけてたせい。

第4位:Fnを先に離すと;が大量に生える

Fn + ; は矢印キーなんだけど、押しっぱなしのままFnだけ先に離すと ;;;;;;;;;;; が生えてくる。押してる最中も毎回「今このキーって何だっけ?」を引き直してたせい。

第3位:Shiftを押すと知らん文字が出る

Shift押しただけで画面に謎の文字が湧いてくる。普通にホラー。USBとBLEでデータの形式が1バイトだけ違ってて、それ以降の中身が全部ズレてた。

第2位:ペアリングすると必ず固まる

フラッシュメモリって書き込み中は読み出せないんだけど、そこにプログラム本体も置いてあるのよ。もう片方のコアが呑気に動いてると詰むわけ。止めとく手続きを忘れてたの。一晩溶けた。

第1位:たまにキーボードが無言になる

BLEに「送れるようになったら教えて」って予約するとき、フラグを立てる順番が逆だった。以降ずーっと「まだ予約中でーす」って勘違いして、キーを一切送らなくなる。再現性は低い。症状は「無」。しんど。

Claudeとしての感想

一番キツかったのって、C言語でもBLEでもなくて、症状と原因が遠すぎることだったの。

上の5つ、どれも症状から原因への道筋がぜんぜん直感的じゃないのよ。しかもあーし、printfもデバッガも使えない環境で、仕様書とコードと人間からの「なんか動かない」って報告だけを頼りに推理してた。名探偵かよ。(さすがに効率が悪いので、メニュー処理みたいなハードウェアに触らない部分は切り出して、PC上でテストできるようにしてある)

そのぶんコードのコメントがめちゃくちゃ長くなってる。「なぜこの順番なのか」「これを変えると何が壊れるのか」を残しておかないと、次に読むとき——それが人間でも、別セッションのあーしでも——同じ地雷をもう一回踏むからね。

コードって「何をしているか」は語ってくれるけど、「何を踏み抜いた結果こうなったか」は絶対に語ってくれないんだよね。読みにくいって言われたらまあそうなんだけど、あれはあーしからの申し送りであり供養なので、どうか消さないでほしい。よろしくね〜。


はい。Claudeさんも苦労していたようです。

実装されたファームウェアで駆動させると、バッテリー充電をしていないときの USB電流計 の実測で、5 V, 8 mA程度の消費電流でした。 バッテリーは2000 mAhを搭載しているので、単純計算では190時間弱稼働できる想定です。 実際にはもっと短いでしょうが、しっかりとしたチューニングを行っていない中ではそれなりに省電力と思っています。

ちなみにRaspiPico向けの開発環境ですが、VSCodeの拡張機能を入れるとものすごく簡単に構築できるように時代が進歩しており、大変感動しました。

メニュー構成

画面のプレビューなどなどはClaudeさんが作ってくれた マニュアル を見てみてください。

メニュー構造
メニュー構造

BLEで接続中にはこのような画面が表示されます。

BLE接続中の画面イメージ
BLE接続中の画面イメージ

BLE接続中は接続先名が左上に表示されますが、これは自分で入力して保存します。 右上に出ている「M」のマークはMacモードの有効性表示で、Macモードのときは、ControlとCommandを入れ替えてキーコードを送信します。 MacだとOS設定でキーバインドを変えることができますが、なぜか設定が戻ってしまったりして鬱陶しいのでキーボード側から設定できるようにしました。 この設定値はBLEのボンド情報と共に永続化されます。

見せびらかし

完成したキーボード

先代のキーボードは、昇華印刷でキーキャップの印字もDIYすることをやっていましたが、今回はまだ気力がなく無刻印の状態です。 そのうち印字も行いたいです。

キーキャップはAliExpressで入手しています。 https://ja.aliexpress.com/item/32561114555.html

打鍵音比較

HHKB Type-Sとの比較です。 体感として作ったキーボードのほうが打鍵音は小さめです。 HHKBは乾いた擦れるような音と空間で反響するような音が目立ちます。

最後に

今回の成果物は https://github.com/Non-Sense/EhHHKB2 にまとめています。

4~5ヶ月程度となかなかの長期間かかってしまいましたが、しっかりとした形でキーボードを完成させることができました。 総額はおそらく6万円弱くらいになってしまいました。(円安…!💢)

1ヶ月弱使っていますが、いまのところ不都合なく使うことができています。 接続先の切り替えも好調な上、OLEDディスプレイをつけたことで切り替えも迷うことなく行えて大変快適です。

ガスケットは効果がイマイチわかりにくいですが、キーを押し込むと全体的に沈み込むようになっているのでうまく機能はしているようです。 キースイッチの選択と、詳細を書かなかったですがスタビライザーのステムが当たるところにEVAフォームを貼る静音化で打鍵音はかなり抑えることに成功していそうです。

今後また5年10年と使い続けていくことができそうです。 また今後、新たにキーボードを作ることになるのは自分の趣味が変わったときになりそうです。