ErgoDox ではないナニか。オープンソースかつ Bluetooth 接続のキーボード | tech - 氾濫原

まず思いつく現状の不満とかを考えて、それを盛りこんで作ろう、という方針を決めた。つまり

  • 左右分割にしたいなあ
  • UNIX 配列準拠がいいなあ
  • Bluetooth がいいなあ

あたりが最初の方針になる。


できるだけ MacBook 標準のキーボードでも十分開発できるぐらいの状態を保ちたいので、奇抜なキー配置のものは例え身体に良くても精神に悪いので使いたくない。

市販品で近いものを探すと、Kinesis freestyle2 あたりがイメージに近い。これをキーリマッパでカスタマイズすれば実用的にはいいかもなとは思った。

Kinesis Freestyle2 Keyboard [KB820PB-us]【キネシス フリースタイル2(9インチ)+VIP3セット Win版】 -

3.0 / 5.0

あと、普通の(普通ってなんだ?)左右分割キーボードの内側のキーにも不満がある。左右分離の場合、タッチタイピングで左手に所属するキーを右手では決して打てなくなる。

しかしゆるふわタッチタイパー的には、中央付近のキーは右手でも左手でも打ちたい。つまりキーをオーバーラップさせたいが、そんなキーボードはこの世に存在していない。僕は「タッチタイピングの矯正」とか別にしたくなくて、ゆるふわでいきたい。

ErgoDox の設計の分析

まずErgoDox はキー数が少なくて UNIX 準拠にはできない。キー配列の画像を見ればわかると思うが、右側にキーが足りない。例えば HHKB なら P の右には [ と ] と DELETE があり3つのキーが続くが、ErgoDox だと1つしかキーがないので無理。ソフトウェア的になんとかするしかない。

なお ErgoDox は設計段階で左右の基板が共通となっている。両面基板をリバーシブルに使うことで両手に対応させている。これにより基板の製造コストはかなり減る (特に小ロットで外注する場合は半額にできる)。ただし、設計には左右対象であるという制約がつく。

一般的なキーボードは右手担当のキーが多く、左右非対称になっている。左右対象という制約をつけると、一般的なキーボードからかなり離れることになる。これはエルゴノミクス的には正しい気はするがよくわからない。ただ、キーが少ないのは現実的に不便だと思う。

余談だけど、右側のキーが多いことも考えると世の中のキーボードは右利き用ではないかと思った。左利きはキーボードにおいても不利を強いられていないだろうか? (僕は右利きなのでそんなこと思いもよらなかったんだけど)

仕様

そういったことを踏まえて自作するキーボードの以下のように仕様とした。

キー配列の仕様

  • UNIX キーボードを2分割した形を基本にする。つまり HHKB とほぼ同じで、Ctrl キーはAの左、ESC は 1 の左など。
  • 矢印キーはどうしても欲しい (HHKB への大きな不満のひとつ)
  • F1〜F12キーもできれば欲しい (HHKBへの小さな不満のひとつ)
  • 中央のキーを1列分オーバーラップさせる
レイアウトの詳細


HHKB からの変更点

  • スペースキーが2分割に
  • F1〜F6, F7〜F12 キーの新設
  • 矢印キーの新設

まず「ぼくのかんがえたさいきょうのキーボードはいれつ」を Inkscape で書いてレイアウトを検証した。軽く書くというよりは CAD 的にちゃんと書いた。のちのち Inkscape からエクスポートして KiCAD で読みたかったため。

備考

  • 僕は右手のスペースキーをほぼ全く使わないので、実質飾りである。
  • Caps Lock キー? そんなものはない。写真にある Caps Lock は Shift キー(キーが足りなかったので)
  • 矢印キーを置くところがなくて右手親指付近に置いている (が、これはちょっと邪魔だった。あと1キー分左にずれていたほうがいい…)

技術仕様

同時に、いくつかこうしたいという仕様も決めた

  • NiMH 単3バッテリー2本で半年ぐらい持つ (普通の製品ぐらい持つこと)
  • 左右ボード間の接続は有線
  • USB に逃げたくなったとき逃げられるようにしておく
    • 制御用のボードは分離して設計すること

一方、躯体については殆ど考えてなくて、いきあたりばったりで基板を作ってから3層構造にした。製作編で詳しく書く。

なお省電力であればあるほどいいけど、そこそこ電波が出るデバイスなので、BLE が生きるぐらいの省電力にはならないだろうという気はしてた。

左右のキーボード間も無線にしたかったが、セキュアにしようと思うと BLE Nano 2台でそれぞれHIDキーボードにしてしまうのが楽ということになってしまう。今回はそういうことはしたくなかったので、ここは有線で妥協した。

ただ、左右どちらも回路構成が完全に一緒なので、単に制御用の基板を2つ用意して取り付ければそれぞれHIDキーボードとして使うことができるようにはした。

つづく → 自作キーボードの製作 — 回路設計とアートワーク・ハードの製作編 | tech - 氾濫原

  1. トップ
  2. tech
  3. 自作キーボードの製作 — コンセンプトとキーレイアウトおよび技術仕様編

ErgoDox ではないナニか。オープンソースかつ Bluetooth 接続のキーボード | tech - 氾濫原

回路設計

仕様とともに回路の設計もしはじめた。単にスイッチがいっぱいついてるだけなので、回路的には難しいところは一切ないといってもよい。問題はPCとのインターフェイス部分になる。

キースイッチ

キースイッチは Cherry MX 系がいいなと思った結果 Gateron (Cherry MX 互換) にした。

  • 安い
  • 品質もそれほど悪くはない (というか ErgoDox Lite に採用されてる)
  • 入手性が良い (いろんな色が ebay 経由で買える状態だった)

あたりで決定した。

BLE Nano

Bluetooth 接続したいので、技適を通っている Bluetooth モジュールを考える。ちょうど BLE Nano という製品が技適を通っていて mbed 対応だったため、これをメインMCUとして使用することとした。 mbed で公式にサポートされているUSBボードと比べて圧倒的に小さく、ライターとともに購入してもなお安いというのもあった。ただし BLE Nano は名前の通り Blueooth LE (4.0) のモジュールなので、多少の不安はあった。

I2C GPIO MCP23017

キーマトリクスのために I2C GPIO IC を使うことにした。これはMCP23017という Microchip 社のものとした。BLE Nano の GPIO は少ないので、左右で1つずつの MCP23017 を使い、この2つを同一の I2C バスに接続する。MCP23017は3bit分スレーブアドレスを変えられるようになっているので、2つのアドレスをわける。ちなみに ErgoDox にも MCP23018 というほぼ同じものが使われている。MCP23017 は秋月で取り扱いがある。

消費電力削減のためハード設計の段階で MCP23017 の割込み生成を使うこととした。MCP23017 側でピン変更を検知した場合 INT ピンを通じて BLE Nano 側に割込みを発生させる。MCP23017 は2つ使うが、割込み生成は1つで良いので、割込みピンを BLE Nano 側でプルアップし、2つのMCP23017はオープンドレインで割込みを生成するように設定する。

割り込みを使わない場合、常時I2Cで通信してキーの状態を調べなければならないが、割り込みを使えば何も変化がないときにはデバイス全体をほぼ完全にスリープさせることができる。BLEによる無線接続は必然的にバッテリ駆動となるので、これは必要だと思った。

左右キーボード間の接続コネクタ

左右分割キーボード間の接続は

  • SCL
  • SCK
  • VDD
  • GND
  • INT

と5ピン必要になった。しかし

  • 5ピン以上
  • 小型・
  • 対称・
  • ケーブルの入手性が良い

あたりを満たすコネクタというのが壊滅的に存在しない。4ピンであれば ErgoDox と同様にTRRSコネクタ(4端子ミニプラグ)が使えるが、INT ピンを入れて5ピンにするのは譲れない仕様なため困難が生じた。VDD を INT と併用するという考えも浮かんだが、キー割込みはI2C経由で読むまで解除されないので厳しいと思った。

結局のところはLANコネクタ(8P8C・RJ45)とした。USB Type-C コネクタがナウいので、可能なら使いたいと思ったが、現状では入手性が悪く、ケーブルも高価なのでやめた。LANコネクタは比較的大きいということ以外は要件を満たしている。ケーブルも安いので優秀なコネクタだと思う。

回路図やボードレイアウトの作成

Eagle だとフリー版にはボードサイズに制限があってキーボードぐらいの大きさのものは作れないので、いよいよ KiCAD に移行することとした。なので KiCAD の使いかたレベルから学習する必要があった。これについては別途エントリを書いてきた。

最初とても辛かったが、なんとか慣れてきた。いままで Eagle でやっていたことをすべて KiCAD で可能にするためにかなりヤックシェイビング的なことをした。特にPCB Millingまわりの環境再構築が大変だった。

最終的には pcb2gcode にパッチ送ったりしてなんとかなる環境をつくった。

回路図



Root.sch / Main.sch / KeyModule-L.sch / KeyModule-R.sch となっている。これはKiCAD で複数ボードプロジェクトを運用する
に詳細を書いた。

左・右のそれぞれのキーマトリクスは BLE によるファームウェアの部分と独立させたかった (つまりBLEではなくUSB接続とした場合でも基板自体の変更がいらないようにしたかった) のでメインの制御基板を別にしてある。

ボードレイアウト



Inkscape から左と右にわけてレイアウトを DXF ファイルを出力し、pcbnew にインポートした。キーの配置はこの状態から DXF のガイドにあわせて手動で移動させて行なった。

レイアウトの仕様は以下のようにした

  • PCB Milling 前提
    • 少しでも作りやすくするため、デザインルールで最小幅を0.3mmに
  • 基本1層基板 (裏面配線のみ)
  • ジャンパ部分は極力わかりやすくする

結構大きな基板になるので格安PCBサービスでも結構高額になってしまう。なので手元でできる PCB Milling (CNCフライスによる基板切削)でやることにした。

しかしこの制約はかなり厳しくて、なかなかレイアウトが決まらなかった。両面にすればよかったが、基板作成の手順が倍以上になるのでそうしなかった。

試行錯誤してオートルートさせてなんとかした。ジャンパなしはできなかったので、ある程度ジャンパを許容してオートルートさせてから、自力でジャンパしやすいように、直線にしたり100mil単位になるようにとかと修正を加えた。

基板の製作



左側

まず先に左だけ作って様子を見ることにした。左側だけでもブレッドボードに組んだ制御基板と配線すれば使うことができるため、出来を確かめることができる。

余談だけど、既存キーボードと併用して Karabiner を使えば実際に左右分割で使えるはず、と思ったが、どうもそれができなかった。修飾キーの共有が BLE キーボードだとうまくいかないみたいだった。Karabiner からもキーボードデバイスとして認識されず謎。これは未だ謎。入力はできてるけどキーボードデバイスとして認識されてない。


それはともかく、使ってみると結構基板がたわんでしまうことがわかったので、下側のプレートにナットだけを増やして力を受けるようにした。キースイッチの実装面には隙間がほとんどないので、裏側から短いビスでナットを止めて隙間を埋めて力をうける構造になっている。


最終的な構造をいまいち考えれてなかったが、結局3層を単純に重ねる形とした。つまり、化粧板・基板・裏板を15mmのビスで共締めしている。

化粧板は特に強度が必要ないので1mm、裏板には多少強度がいるので2mmとした。結果として以下のような層になった。

  • 化粧板 1mm
  • ナット 5mm
  • 基板 1.6mm
  • ナット 3mm
  • 裏板 2mm
  • ナット3mm

できるだけ薄くて机にキーが近いほうがいいけど、このぐらいが限界だった。

化粧板と裏板の切り出し

いずれも外形カットと穴開けが必要だったため、基板と同様にCNCフライスで切り出している。

この際、CAD は KiCAD の pcbnew をそのまま流用した。KiCAD のユーザー定義レイヤーが2層あるので、ここに切削ラインを書いて、ガーバーに書き出し、外形レイヤー扱いで pcb2gcode で gcode 化した。

ただし、pcb2gcode は現時点では「外形カット」しかできないので、内側に書いたラインも外側を削る挙動になってしまう。pcb2gcode 側に対応をいれたかったが面倒なので、図面の段階でエンドミル径分を考慮して線をひいた。

右側

左側を作った結果をうけていろいろ改良を加えて右側を作った。

以下らへんを改良

  • 角丸に
  • 固定用のビス穴を大幅に増やした

やっぱ角丸にしないとこういうのはきついよなと思った。左側はあとからリューターで削って角丸にしたけど、右側は切削時点で角丸になるように外形を描きなおした。

固定用の穴は多めにあったほうが圧倒的にしっかりするのでケチらないで開けたほうが良い。実際、右側は左側と比べてかなりしっかりした構造にできた。

なお右側は左側に比べてキーの数がかなり多く、基板のサイズもぎりぎりになっている。配線もこちらのほうが大変。基板の原点をちょっと適当に設定しまって、基板は上側が実は足りてない(配線的には問題なし)

作ってみて

これで左右が揃ったので、ファームウェアのクオリティはともかく、ちゃんと打てるようになった。

基本的に HHKB と完全に一緒のキー配置なので、ほとんど違和感なく使える。ただ、物理カールキーをつけたのに関わらず、HHKB のカーソルキー移動に思ったよりも慣れていることが発覚した。Fn キー相当の位置に未割当キーはあるので、ファームウェアで対応した。

カーソルキーを制限のあるなか、なんとか配置したのはよかったが、思ったよりも右手の親指と干渉してしまった。あと1キー分左にあったほうが良いかもしれないけど、ぎりぎりすぎる。右のスペースキーは僕は使うことが全くなくて飾りなので、そこに別のキーを配置してもいいかもしれない。

なお自作する場合、CNCフライスの加工限界によって基板のサイズに制限があり、左右分割でないとそもそも作るのが難しいというのを感じた。

あと細く���短いLANケーブルがなかなかなくて難儀する。多少長くても細いほうが取り回しはよさそう。あんまり長いケーブルだとI2Cのドライブ範囲を超えるのでバグりやすくなる。

つづく → 自作キーボードの製作 — ファームウェアの実装編 | tech - 氾濫原

  1. トップ
  2. tech
  3. 自作キーボードの製作 — 回路設計とアートワーク・ハードの製作編

ErgoDox ではないナニか。オープンソースかつ Bluetooth 接続のキーボード | tech - 氾濫原

とにかくこれが一番大変だった。BLE + mbed + HID キーボードでちゃんと動くもののサンプルっていうのが見つからないので、そこそこ動くサンプルから頑張らないといけない。

ほとんど作り終わってから気付いたけど先に言っておくと、mbed のオンラインコンパイラ環境で BLE Nano の開発をするのは筋が悪い。RedBear も Keil 使って Nordic SDK 直接使って開発しろみたいなことを言ってる。ただ、今回はどうしても、キーカスタマイズとかのために開発環境をゴリゴリ用意するというのが嫌だったので、オンラインコンパイラに拘った。

依存と罠

まず、現状の mbed ライブラリと nRF のSDK のどちらにもあるヘッダファイルが競合していて、まともにコンパイルできなかった。mbed を依存からはずして、mbed-dev をインポートして、該当するヘッダファイルをリネームして対応した。しょっぱなからひどい目にあった。

BLE_HID というライブラリもあって「お、これいいじゃん」という感じだけど、OSX + BLE で HID over GATT でペアリング(bonding)ができなくてハマった | tech - 氾濫原 にある通り、さっぱりペアリングできなくてハマった。

BLE_HID は結局中の構造をいじることが多かったので、プロジェクト内にファイルをコピーして依存から消している (競合するので)。

セキュリティまわり

これまたハマりまくるポイントで困る。上記のようにそもそもペアリングできないというのもあったし、普通に使えるレベルとするにはペアリング情報を覚えてて自動再接続してほしいところだけど、どうやるかさっぱりわからなかった。

結論からいうとセキュリティまわりの処理が終わったら該当デバイスをホワイトリストに入れれば良い。しかし BLE_API のホワイトリストまわり、experimental 扱いになっていて不穏な空気を感じる。

BLE と OS X

まず、よくわからないけど OS X が BLE キーボードをキーボードとしてちゃんと認識しない (具体的にはアイコンが汎用デバイス扱いになるし、バッテリーステータスもちゃんと表示されない。ちゃんと GATT で提供してるのに……)

ただ、ペアリングするとちゃんと入力できるので対応されてないわけではない。

あと、Bluetooth の環境設定が頻繁に固まる。ジョブズが生きていればこんなことには……

Apple Magic Keyboard (US配列) MLA22LL/A -

2.0 / 5.0

Apple Magic Keyboard (Wireless Keyboard ではなく) は BLE 接続らしいけど、どうなってるのかよくわからない。DeviceInformationService で PnP ID を偽称してみたりしてみたけど、うまく認識しなかった。このキーボード、思いのほか高価なので試しに買ってみて調べるみたいなこともできずモヤモヤした。

BLE と Windows

Windows とのペアリングは非常にスムーズで問題がなかった。ちゃんとキーボードとして認識されるし、OS X よりマトモ。ただ Windows でもバッテリーステータスを確認する方法がわからなかった。

BLE と Android

さすがにスマフォは BLE の対応がしっかりしていて、まともにペアリングできるし、ちゃんと使える。

nRF Connect で GATT 情報を見ると OS X 上で LightBlue を使って見るよりも多くの情報を得られる。BLE に関してはスマフォも活用してデバッグしたほうが捗る。

特にハマったところ

別途エントリに起こしたけど、ここらへんでそれぞれハマってる。

あとエントリに起こしていないけど、とにかくメモリが足りなくて苦労する。現状の BLE Nano (v1.5) は 32kb RAM があるのだけど、mbed がサポートしておらず、16kb しか使えない。そして SoftDevice とかの使用を除いて 6kb ぐらいしかアプリケーションが使えるメモリ量がない。この中で抽象化された mbed の BLE_API を使うと本当にすぐにメモリが枯渇する。

メモリが枯渇してもハードフォルトでランダムに stuck したりする感じなので、おそろしく原因究明が難しい。ヒープが上書きされても致命的でなければ動き続けるわけだし、ヒープの正確な使用容量を知るよしはないし、SoftDevice の割込みのために一定量のスタックメモリも残しておかなければならないしで、とにかくつらい。32kb になれば余裕になるので、さっさと 32kb 対応してほしい。

現状のメモリ量だと、たとえばマウスをサービスしたいと思っても不可能だと思う。

消費電力の削減


最初にやったのはこれだった。製品に近いぐらいにはしたいという気持ちがあったのと、消費電力削減はテスターで見てすぐ効果が数値でわかるので好きというのもある。

別途エントリにした 16MHz HFCLK をオフにするというのが一番支配的だったけど、他にも細かいところに気をつかったつもりではある。

必要ないペリフェラルはできるだけ止めているつもり。UART だけデバッグの都合でスリープに入る前後のタイミングで止めてからスリープに入って起きたら再開するというコードになっている。ただし、UART も RX は一切行わないので止めている。

また、無接続ピンもプルアップして中途半端な状態にならないようにしている。中途半端な電位になると、他のところとの電位差で無駄に電流が流れたりするので気をつける必要がある。これは直接レジスタをいじっていて、mbed の DigitalIn とかは使ってない。メモリ節約のため。

キー入力間でチャタリング防止のつもりで5msのインターバルをいれているけど、これも安易に wait_us(5000) とかにせず、Timeout による割込みをしかけて waitForEvent して寝るという実装にしてある。CPU をスリープさせない限り消費電力は減らないので、起きている時間をとにかく短くしたい。

起きている時間をとにかく短く、という視点で、I2C の速度を 250khz に上げてある。100khz よりも2.5倍早いので、I2Cで消費する電力は半減ぐらいになる。ただ、電源電圧が低いので速度をあげると安定性が失われる。オシロで波形を見ると結構なまっている。

BLE のコネクションパラメータで一番効果が高いのは slave latency だった。このパラメータは、ホストからのリクエストを一定個数無視するというもので、スリープ中の消費電力を結構減らせる。

一方、空中線電力は下げてもそれほど効果がなかった。コンスタントに消費はあるが、極めて短時間なので平均的には支配率が低いように感じた。

安定性改善

前述したが特定の変数を宣言するだけで stuck するみたいな挙動で原因がわからずとても苦労した。結局メモリ不足でヒープが上書きくらってたみたいだけど、そんなに使ってるつもりないのに死ぬのでなかなかメモリ量が問題と思いあたらなかった。

また MIC エラーもとにかくハマっていた。メモリ使いすぎの件があったので、これもそういう系なのだと思って原因をさがしていたが、そうではなかった。BLE Nano (nRF51) + mbed でセキュリティ付きペアリングをして 0x3d エラーがでる | tech - 氾濫原

レイヤー

めんどくさくて最初は実装してなかったけど、思いのほかHHKB式のカーソルキーにも慣れていることがわかって、仕方なしに実装した。

レイヤーの部分はいちいち実機デバッグするのが面倒だったので、ユニットテストを雑に書いてある。

バッテリーレベルを mV で見れるようにする

カスタムUUIDを定義して、mV 単位のバッテリーレベルもとれるようにした。カスタムUUIDやってみたかったのと、やっぱ % 単位で見れても実際どうなのか不安なので……

まとめ

まだちょろちょろいじってはいるけど、ほぼ安定した。「もうこれ安定しないんじゃないか」「USB接続に方針を変えたほうがいいんじゃないか」と思うこともあったが、なんとかなったと思う。

  1. トップ
  2. tech
  3. 自作キーボードの製作 — ファームウェアの実装編

ポリスチレンはカッターで切れるのと、プラモデル用の接着剤が使えるのが良い点だなあ。

ASUS ZenFone 2 の Android M (6.0) アップグレードは遅延 | tech - 氾濫原

遅延していた OS アップデートですがようやくきました。8月31日付けで配信開始したようです。リリースノート

ただし WW のみ。JP はいつ……

  1. トップ
  2. tech
  3. ZenFone2 にようやく Android M (Mashmallow) アップデートが降ってきた

ほかにもやりたいことがあるのだが、ここ数ヶ月やってることがなかなか「これでよし」とならなくて、とりかかれない。ぶっちゃけそろそろ飽きてきたのでさっさと日記に書きだして一旦おわりにしたい。

ここ数ヶ月ぐらいキーボードを作っていた。そのためにいろいろ yak-shaving としかいいようがないことも多々していた。

いろいろ書くことが多いので、細かい設計などについては別途エントリを分ける。

  • コンセンプトとキーレイアウトおよび技術仕様の決定
  • 回路設計とアートワーク・実際の製作
  • ファームウェアの実装

あたりをそれぞれ別途詳細なエントリを書く。だいたいの人は細かいことはどうでもいいと思うので、概要のみこのエントリにまとめる。

コンセプトや特長

UNIX ベースのキーレイアウト (というかHHKBをベース) とし、違和感なしに分割キーボードとする。

キー配列

  • UNIX キーボードを2分割した形を基本にする。つまり HHKB とほぼ同じで、Ctrl キーはAの左、ESC は 1 の左など。
  • 矢印キーはどうしても欲しい (HHKB への大きな不満のひとつ)
  • F1〜F12キーもできれば欲しい (HHKBへの小さな不満のひとつ)
  • 中央のキーを1列分オーバーラップさせる (ゆるふわタッチタイピングに必要)

特長

  • Bluetooth 4.0 (Bluetooth LE) HID over GATT 接続。Windows と OS X で接続可能
  • Bluetooth 経由によるファームウェアアップデート
  • mbed オンラインコンパイラによるファームウェア開発環境
  • 全てオープンソース (MIT)
  • 1900mAh の NiMH 充電池で約6ヶ月のバッテリーライフ
    • キー入力時 3.3mA、非アクティブ時10uA〜100uA(OSの挙動による)

FOTA/DFU (Firmware On The Air / Device Firmware Update) かつオンラインコンパイラによりキーカスタマイズのために環境構築が不必要。あるいは MK20 による書きこみなので、3ピンの配線でUSBからマスストレージクラス経由で書きこみ可能。

技術的な仕様

UNIX配列のBluetoothキーボードというのが希少で前々から欲しいと思っていたので、接続インターフェイスは Bluetooth としてみた。

インターフェイスとして RedBear BLE Nano というのを使うことにした。国内技適にも通っており結構安い。mbed が開発環境に使える。名前の通り BLE (Bluetooth 4.0) 接続になる。ただ、なんというか、この選択(無線化)は割と悪夢の始まりだった。

回路設計


BLE Nano はピン数が少ないため、I2C GPIO 拡張の MCP23017 を2つ使っている。消費電力削減のため GPIO の割込みを活用している。キーの部分は単にキーマトリクスなので特におもしろいところはない。

ステータスLEDを1つだけつけている。これはペアリングステータスを示すため。キーボードにLEDあっても見ることないし消費電力の無駄なのでほとんど消灯させておく。

基板設計

KiCAD のプロジェクトは github に置いてあります。https://github.com/cho45/Keble

PCB Milling (CNCフライスによる基板切削) でやることを前提としたので、片面基板+最低限のジャンパで構成した。

複雑ではないが配線数は多いので、片面という制約をつけると結構厳しい。がオートルータでなんとかなった。製作しやすくするため、デザインルールで最小幅を0.3mmとした。

製作

とりあえず左を作ってファームウェアと共に実装を検証し、それから右側を作った。そのため、右に比べると左側のクオリティが明らかに低い。

設計がちゃんとできている前提で、無心ではんだ付けをするだけ。振動とたわみの負荷がSMDにかかるのがなんとなく嫌で全てリード部品としたため、特に難しいところはない。

基板以外に、バックプレート(2mm)とフロントプレート(1mm)をさらにプラ版から切り出している。なので、3層構造になっている。側面はない。

ファームウェアの実装

mbed レポジトリ

mercurial:

hg clone https://developer.mbed.org/users/cho45/code/keyboard/

前述の通りだけど、今回は mbed のオンラインコンパイラで全て実装した。BLE Nano + mbed でセキュアペアリングして HID デバイスとして動かす例なんてのは例がさっぱりなくて大変苦労した。

HID キーボードとして簡単に動かすぐらいまでは、既にやってる人がいるので難しくない。しかし、実用キーボードとして安定して動かすようにするまでがかなり辛かった。

70%ぐらいの完成度まではすぐできるけど、そこから90%ぐらいまで完成度を上げるには大変な労力がいる。ハマったポイントが蓄積されていて、使えるぐらいに安定して動くコードがある状態にできたので、まぁ良かった…… ハードウェアよりもファームウェアの実装の知見のほうが遥かに価値があると思う……

基本的に mbed 環境でがんばるってのが筋が悪いのだけど、なんとなくオンラインコンパイラにこだわって意固地になって苦労している感じ。

現状の実装クオリティ

主観的には90%といったところと思ってる。温度感としては「ブログ書くぐらいなら全く問題がなく、仕事で使うのにもまぁまぁ使える」ぐらい。

仕事で1日使ったところ、数回再接続(約5〜10秒ぐらい)が必要になったのと、1度完全に刺さった(WDTで復帰せず、リセットで復帰)。0dBmで送信しているので、普通の距離なら物理要因で接続が切れることはないと思うので、他の再接続もファームウェアのバグだと思うが原因不明。

自分の主観的には割と稀ぐらいまできて普通に使える、バリバリ集中してコード書きまくる人だとイライラするかもしれない。

キーマップが HHKB と同じ (Fnキーによる矢印キーも実装してある。レイヤーってやつ)なので、基本的にどっちも全く違和感なく使える。

部品とコスト

  • BLE Nano Kit: 3300円 (Red Bear Store)
  • Gateron Brown キー 108 セット: 3300円 (ebay) 余ります
  • キーキャップ 104 セット: 5700円 (ebay) 余ります (無刻印・メタキー用)
  • キーキャップ 104 セット: 3500円 (AliExpress) 余ります (有刻印)
  • 生基板 1.6×150×250 2枚: 1000円 (monotaro)
  • 1mm プラバン B00CF9RSTU : 540円 (Amazon)
  • 2mm プラバン B001Q0ZHTW : 550円 (Amazon)
  • ビス・ナットなど 500円ぐらい

キーキャップ2セット買ってるがメタキー用の無刻印のものと通常キーの刻印ありのものを分けたかったからで、1セット+必要なキーだけとかならもっと安くはできるはず。いずれにせよキーキャップの原価支配率が高い。これだけ買ってるのに右シフトキーサイズのキーが Caps Lock しかなくて、しかたなく代用している。

基板切削を自力でやっているので注意がいる。もし基板を外注するなら、左右別のデザインにするとサイズ的に5枚組み1万ぐらいはかかるはず。とはいえ、外注しても2〜3万ぐらいの原価なので、趣味で作るのはまぁまぁ現実的といえる。基板をシェアするともだち(笑)がいるならもうちょっと安くて楽をできる。(趣味で、というのは自分の作業コストをゼロとして見積るという意味です)

製作期間

ヤパチーで ErgoDox を見て触発されて、ErgoDox について調べた(買わないけど) | tech - 氾濫原 このエントリを書いた時点でさいきょうのキーボード自作の実現性について考えていたので、そこから約1ヶ月半ぐらい。ebay や aliexpress が部品調達のメインで、かなり待ち時間があるので、実働は1ヶ月ぐらいかな。休日も平日も夜中にしか開発できないので、やる気があれば半月ぐらいで形になりそう。主観的には(大変すぎて)3ヶ月ぐらいずっとやってるつもりだったけど、案外早くできたっぽい……

ぶっちゃけ1ヶ月ぐらいじっくり取り組むと飽きる。

現時点での感想

キーボード自作は結構面白い。というか奥が深いと感じる。自分が一番よく触るインターフェイスを自分である程度作れるというのは満足度が高い。

いきなりイチから盛り盛りで作ったわりには良くできたと思うが、特にハードウェア部分は製品レベルではない。自分で作って自分で使うぶんには十分といえる。

「さいきょうのきーぼーど」追い求めると沼にハマるので、ほどほどにしたほうがよさそう。

フルキーボード作るのは結構コストがかかるので、既存のキーボードと組合せる前提で、カーソルキーだけとか、ファンクションキーだけ、みたいな無線キーボードなら安く作れて良さそう。そして十分実用にできると思われる。

  1. トップ
  2. tech
  3. ErgoDox ではないナニか。オープンソースかつ Bluetooth 接続のキーボード

BLE Nano は書きこみ器セットで購入しても $32.90 とかなりお得。BLE Nano Kit - Product 単体 なら $17.90。RedBear は香港みたい。公式の通販から最低送料のオプションで買っても割とすぐ届く。

ただのビーコンとして使うには高価に感じるかもしれないが、PCとの低消費電力無線通信デバイスでこの価格帯のものは殆どない。

そしてARM かつ、mbed を開発環境につかえる。なお Arduino からも書きこめる。ナイス。

載っている BLE モジュールも nRF51822 という界隈でデファクトスタンダートみたいなやつなので比較的情報が豊富。

そして小さい。小さいのは正義。その分IOは少ないが割となんとかなる。

  1. トップ
  2. tech
  3. なぜ BLE Nano にご執心なのか

0x3d はMessage Integrity Check (MIC)が失敗した、というエラーらしい。ホスト側で発生する。デバイス側から送られてきたメッセージのセキュリティチェックエラーのようだ。

ということで、デバイススタックの SoftDevice のバグでは? と思うところだけど、そうではないらしい。どうやら mbed と相性が悪いらしい。

解決の糸口

0x3d が出るのは最初はファームウェアのバグでどこかが stuck しているからだと思っていた。しかしどうも stuck していなくても 0x3d が起こることがある。で、そろそろ Nordic スタックのバグを疑ってみる。しかしそこのバグなら既にハマっている人がいるはずなのでググる。

すると Implement BLE security · Issue #44 · lancaster-university/microbit-dal · GitHub あたりに Nordic のバグじゃね? みたいな話がでてくる。そこからサブイシューがつくられている。


MIC failures observed with secure BLE · Issue #61 · lancaster-university/microbit-dal · GitHub

Problem is caused by mbed-classic disabling interrupts when a timer interrupt is triggered. This was too long for the underlying BLE stack to code with during critical radio events.

と原因と、さらに解決策がいくつか示されている。一番簡単なのが3つめなので、このプロジェクトでは3つめが採用されたっぽい。しかし肝心のコミットへのリンクはないので頑張って探す。

Merge branch 'secure-ble' · lancaster-university/microbit-dal@3c31479 · GitHub このコミットをつらつら眺めていくと、どうやら対策コードっぽいものが見つかった。

	// configure the stack to hold on to CPU during critical timing events.
 	// mbed-classic performs __disabe_irq calls in its timers, which can cause MIC failures 
 	// on secure BLE channels.
    ble_common_opt_radio_cpu_mutex_t opt;
    opt.enable = 1;
    sd_ble_opt_set(BLE_COMMON_OPT_RADIO_CPU_MUTEX, (const ble_opt_t *)&opt);

ここで SoftDevice の API を呼んで、無線アクティビティがあるときはCPUを完全にブロックしてアプリケーションの実行を止めるらしい。簡単なコードだ。

コピペしてみるとエラーの発生がなくなった。まじ良かった……

備考:エラーのログ

Apple が提供している Bluetooth Explorer の Event Log を開きっぱなしにしておけば、接続情報について常にデバッグログに残る。

  1. トップ
  2. tech
  3. BLE Nano (nRF51) + mbed でセキュリティ付きペアリングをして 0x3d エラーがでる