自作キーボードPFKの設計の説明
先日, 天下一キーボードわいわい会 Vol.3に参加し, 現在制作中のキーボードを展示してきました。 仕組みに興味を持って下さる方もいらしたので, ここで説明します。
展示では動くところを見せていなかったのもあり, まず動くところの動画です。
一応, Perfect Fluid Keyboard
という名前で作っていたので, 以下PFKと呼びます。
コンセプト
PFKは “キーをできるだけ自由に再配置できるようにする” というコンセプトのもとで設計しています。 このコンセプトは, 自分に最適なキーの配置を見つけるために, 柔軟に配置を変更できるのが良いのではないかと 思い至ったもので, PFK自体は末永く使うよりプロトタイピングのためのものという位置づけで作っています。
数年前, オープンソース化されている自作キーボードの設計をそのまま使ってPCBを発注して組み立てようと考えた時, どうせならキーの配置なども好きにカスタマイズしたいと思ったものの, どういう配置にするべきかが全くイメージできませんでした。 配置を変えて作り直そうとした場合, PCBマウント前提であれば基板を都度発注し直す必要があるし, プレートマウント前提であれば, プレートを作成し直す必要があります。 動作する状態にしようと思えば, それに加えてはんだ付けもしないといけません。 そこで, 最初から配置を変えられるように設計してみようと思ったというのが大体の経緯です。
ちなみに, 設計を始めた時は知らなかったのですが, これと同じようなコンセプトを満たすキーボードとして “Dumang” という製品を既に深圳のベンチャーが製造販売しているようです。 天下一キーボードに持って来て展示している方もいらっしゃいました。 (私の自作キーボードより自由度も高く, 「もうコレで良いのでは…?」という気持ちもありますが, それはそれ)
設計方針
上述のコンセプトを達成する上で, いくつかのアイディアを考えましたが, 必要になるパーツのコスト削減や, 配置変更の容易さなどを求めた結果, 次のような設計方針に至りました。
- キースイッチごとにマイコンを設置し, I2C slaveとして動作させる
- キースイッチとマイコンのついたパーツ(以降, モジュールと呼ぶ)にピンヘッダをつけ,
ピンソケットをたくさん並べた基板(以降, ベースボードと呼ぶ)上の好きな位置に接続する
- ベースボードはI2Cに必要な4線(Vcc, GND, SDA, SCL)からなるバスを張り巡らしており, モジュールはベースボードに挿されることでバスに接続される
- 別途用意したPro Microなどのコントローラーをベースボードと接続し, バス上のI2C masterとしてこのコントローラーを利用する
- コントローラーは随時I2Cを介してキーの押下状態をモジュールに問い合わせ(ポーリング), キー入力等のイベントを検出する
イメージとしては, ブレッドボードが極めて近いと思います。 このようにすることで, ある程度自由な位置にキーを固定できると同時に, 電気的な接続もなされるため, 配置を変更する際にプレートまたはPCBの再作成も必要なければ, はんだ付けも不要となります。
ベースボードにはバスを構成する4線を特定のパターンで張り巡らせていますが, それは次のようなパターンにしています。
文字に起こすと, 以下のようなパターンを並べているような形になります。
G C G -
V D V -
(ここで, G=GND, V=Vcc, C=SCL, D=SDA, -=ピンソケットなし)
この並びにした理由は後ほど出てきますが, 3列ごとに1列空けるような配置にしているのは, 実装上の都合です。 ピンソケットを大量に並べて配置すると, 厚みが2.54mmピッチよりやや厚いのか, だんだん収まらなくなってくることがわかっていたため, 3列ごとに間を空ける形になっています。
問題点
しかしながら, なんの工夫もなく上述の設計を実現することは難しく, 何よりも正しくモジュールのマイコンをI2Cのバスに接続することが困難です。 配置が柔軟に変化するモジュールからすれば, どのピンが4線 (Vcc, GND, SDA, SCL) のどれに接続されているかが定まらないためです。
もちろん, モジュールの配置に強い制約を設けて, 必ず1番ピンがベースボード内の特定の条件を満たす位置に来るようにするといったことは考えられますが, 位置を変えられる刻み幅がどうしても大きくなってしまいます。
この問題に対し, 以下のような工夫をして対応しています。
電源部分の工夫
まず, 電源についてはダイオードブリッジによる整流回路を用意して, 正負の極性が反転しても機能するようにと考えました。 モジュールの位置に関わらず, 整流回路には Vcc と GND を入力する必要があり, そのため先述のパターンのベースボードに対しては, モジュールは適切な配置で4箇所にピンを用意しておくことになります。 (4つのピンが4線のそれぞれに被りなくつながるような配置にする)
しかしながら, 得られた4つの入力をそのまま次のような整流回路に接続すると, SDAやSCLもここに接続されることになり,I2Cの通信が上手くできなくなると予想されます。 そこで, 機械的にSDAとSCLは整流回路に接続されないような工夫を施しました。
具体的には, ピンソケットとピンヘッダにそれぞれ2種類の高さのものを用いて, 高い(長い)もの同士や高い(長い)ものと低い(短い)ものの組み合わせでは導通するが, 低い(短い)もの同士ではピンとソケットがお互い届かずに接点がない状態になるようにしました。 その上で, 長いピンソケットにはVccとGNDのみ接続するようにすると, 短いピンヘッダはモジュールがどこに接続されてもVccかGNDかNC(接続されていない)状態になるため, ブリッジダイオード回路にはVccかGNDしか入力されないことを担保できます。
(写真のように, 右手前と左奥の2本ずつ短いピンヘッダがある)
(見にくいですが, 右から2ピン目は短いピンヘッダとソケットの組み合わせのため導通していません。 左から1ピン目(右から6ピン目)はソケットは短いがヘッダが長いため導通しています。)
こうして, モジュールの位置によらずI2C通信に影響を与えずに電源を確保することができます。
ちなみに, この方法を採用したことが, 先述のようなベースボード配線パターンになった大きな理由です。
2種類のピンソケットを使う時, 実装の手間を考えると列ごとにその種類を分けるほうが効率的です。
さらに, モジュールの機械的な固定を安定させるためには, 高いピンソケットが2列分のスペースに1列は欲しいため,
先に述べたように実装の都合でピンソケット3列ごとに1列スペースを空けることを考えると,
高い-低い-高い
という3列の並びを繰り返す形になる必要があります。
SDAとSCLは低いピンソケットを使う必要があるため, 結果的に先述の配線パターンに落ち着きました。
(さらに余談ですが, モジュールの電源電圧は, ベースボードに印加される5V電源を元に, 整流用にダイオードを通過する分の電圧の降下が見込まれるため, 5Vより幾分低くなります。 SDAやSCLの信号はベースボードに印加される電源電圧のレベルに基づいているため, モジュールのICからすると自身に与えられた電源より外側の電位にまで振れる信号を扱うことになってしまいます。 したがって, ICの選定によってはこれが原因で動作しないこともあるかもしれないという懸念もありますが, 一応はVfの低いダイオードを選定し, 今回はそれ以上は気にしないことにしています。)
I2C接続の工夫
電源と同じくI2C通信用のSDAとSCLに関しても, モジュールの位置によらずI2C slaveになりたいモジュール内のマイコンに上手く接続してやる必要があります。
先に使ったピンヘッダおよびソケットの高さを利用した制御は, よほど端子形状を工夫しない限りそう何パターンも制御できるものではないので, SDAとSCLについてはモジュール側でどのピンがどの線かを動的に検知させることを考えました。
ベースボード上の配線は先述のように同じパターンの繰り返しなので, モジュール側のどのピンがどの線と接続されているかが一箇所でも特定できれば, モジュール内の残りのピンがどの線と接続されているかは自動的に決定できます。
(この方法はモジュールの回転に対しては弱いです。 回転も考えた場合, 1箇所を特定するだけでは残り3つを決定できるとは限らなくなるためです。 PFKで先述のようなパターンにしているのは, このパターンであれば180度単位の回転に関しては 位置関係が維持されるためというのも一因です。)
Vcc, GND, SDA, SCL の中で, 通信の都合で電圧が大きく変動する SDA, SCL を識別するのは比較的複雑と考えられるため, Vccの位置を特定することを考えました。 Vccについては幸い電源の確保のために既に入力があるため, これらのピンの電位を元にすれば, Vccのピン位置がモジュール側から特定でき, そこからの相対位置でどのピンがSDA, SCLかを判定することもできるようになるはずです。
先程の整流回路への入力に用いている4箇所の短いピンヘッダからの入力を, 整流後に得られる仮想グラウンドに向けてプルダウンしておくと, Vccに接続されているものだけがHighで残りがLowという状態を作り出せます。 これを用いればモジュールのどのピンがVccに接続されているかが特定でき, そこからSDA, SCLのピン位置も特定できることになります。
あとは, プルダウンした4つの入力を2回路ORゲートを介し 00/01/10/11 の4パターンの出力に変換させて, アナログマルチプレクサの制御信号として使うことで, SDA, SCLの位置のピンヘッダからの入力を選択してマイコンに接続することが出来ます。 短いピンヘッダはSDA, SCLを拾わないようにしているので, 長いピンヘッダからの入力をここで使うことになります。 先述の配線パターンではSDA, SCLを含む列が4列分のスペースに1列の間隔で並んでいるので, 長いピンヘッダは横方向4ピッチ分の長さのものを2行分並べる必要があります(合計8箇所)。
(このあたりの説明については, 記事の末尾でリンクしているGitHubリポジトリ内にKiCadの回路図があるため, それも参考になるかと思います。)
標準ピッチ対応
核となる部分は以上で説明できたと思いますが, 細かい話として, キーの間隔(ピッチ)の話があります。 標準的なキーボードにおけるキーの間隔(ピッチ)はおよそ19mmで, 大体 0.75inchに相当します。 よくあるピンヘッダやピンソケットのピッチは2.54mm(0.1inch)であり, これに基づいてブレッドボードのように作ると19mmのピッチで配置することはできなくなってしまいます。
そこで, PFKではモジュールのピンヘッダの並びの中心とキースイッチの位置を0.025inch程度ずらすように配置しており, これによって, ベースボードにモジュール挿し込むときに, 向きを180度変えて挿せば0.05inch単位での調整が可能になるようにしています。 (前述のように, 180度の回転は問題ないようにベースボードのパターンを配置している)
これだけだと左右方向または手前・奥の方向しか0.05inchズラすことができませんが, モジュール自体が2つのパーツからなることを利用して前後左右にずらせるようにしています。 というのも, 実装面積の都合でモジュールは, ほぼキースイッチからなる上部パーツと, IC群からなる下部パーツの2つのパーツを, 低頭のピンヘッダ・ピンソケットで接続することで構成されています。 加えて, 上部パーツを下部パーツに対して180度回転して接続できるようにしています。
そのため, 下部パーツについてはピンヘッダの配置を中心から左右方向に0.025inchずらし, 上部パーツについては前後方向に0.025inchずらしてやることで, 下部パーツごと180度回せば左右に0.05inch, 上部パーツのみ180度回せば前後方向に0.05inch調整できるようになっています。 そのため, 0.75inchの標準ピッチでの配置も可能となっています。
課題
- まだ片手側しか完成していないので, 両手分を作る
- キーの高さ自体は, モジュールの上部パーツを工夫すればできると思うので, 取り組んでみたい
- (あくまでプロトタイピング用で作っているので, 最終的に求めるキーボードが得られるのはいつになることか…)