見出し画像

自作キーボードを作る備忘録。4 キーマトリクスでピン節約

自作キーボードを基盤からガッツリ作ろうと思います。大学の授業でたまたま集まった6人がメンバーです。でも、誰一人として自作キーボードの知識は(大して)ありません。4ヶ月くらい経ってプロジェクトもちょいちょい進展してきてダニングクルーガーの頂点を超えたあたりになってきたのでここらで整理した形で残しておきます。

前回までのあらすじ

キーボードの原理として1キーキーボードの作り方を習得した後、半田付けの労力を減らすために、(正確に言えば電子工作の世界でのメジャーな接続形式を学ぶために)プルアップ抵抗について学習しました。

前回は、これであとはキー数を増やすだけだ!ってなったけど、ピン数が足らねえ!ってことに気づき、どうしようということになったところで終わりました。

<注意>今回の記事は1キーのキーボードの動作原理やプルアップの仕組みを理解していないと、難しいものになっていると思うので、途中で理解出来なかったら前の記事に戻ったり、番外編の自作キーボードのための電磁気学に戻ってみてください。

キーを増やす方法の思考

問題はキー数がピン数より圧倒的に多いことです。ピン数を無限に増やせるマイコンがあればいいのですが、残念ながらコストの面からしても現実的ではないでしょう。(もしコスト度外視なら市販のCPUを使って強引に解決するかもしれませんね)

これまでに考えていたキーの増やし方はこんな感じです。

画像1

INPUT_PULLUPのピンをそれぞれのキーに対応させることでキーを増やしてきました。では、逆にGNDに相当するピンを他に増やしてみたら良いのでは?と考えてみましょう。

画像2

ちょっとわかりづらいので、マイコンに相当する部分を省略して書いたのがこちらです。

画像3

Aを押したら1からGNDへ。Fを押したら2からGND2へ、というふうに流れる経路を読み取ります。キーと経路を一対一対応させる感覚です。

これならあとはグラウンドに相当するピンを1ピンを増やすごとに4キーずつ増やせるのでかなり効率が良いですね!

と思いきやこれも問題があります。どうやって経路を補足するかという問題です。これまではどのINPUT_PULLUPがLOWになるか、によって押されたキーを把握していました。しかし、どのGNDに電流が流れ込んでいるか、を知る方法はどうやら無さそうです。理由は単純でマイコンには複数のGNDピンがある場合がありますが、その中の配線で、みんな同じところに繋がっているためです。つまり、GNDと書いてあるところはみんな離れていても繋がっていて、マイコンからは同じ様に見えています。

では、どうするか。マイコンのGPIOピンを使います。pinModeにOUTPUTというモードがあります。これは、このピンに電流を流せるよ~というモードです。その点においてはGNDピンと同じです。そして、OUTPUTのときは、電流をそこから出すこともそこに入れることもできます。OUTPUTなのに入れることも出来る点に注意してください。そして、GNDピンとの大きな違いはそのピンの電位がHIGH(3.3V または 5.5V) かLOW(0V = GNDと同じ) かを選択出来ます。

つまり、こんなパターンを作れます。

画像4

逆に5がHIGHで6がLOWにしたいときはスイッチのONOFFを入れ替えてやるだけで出来ます。こうすれば、5がLOWのときに1がLOWになったらAが押された、6がLOWのときに2がLOWになったらFが押された、みたいに判別が可能です。言ってしまえば、1行ずつスキャンしていく感じですね。これでどうやらキーの判別はうまくいきそうです。

デバッグ

新しいものを考えた時は、想定外の使用を考えてこれで本当に問題がないのかを確かめる必要があります。今回もしっかりと考えておきましょう。

といっても、想定外の使用ってどんなんでしょうね。想定内は丁寧に1キーずつ押す人なので、一気にいろんなキーを押す人を想定しましょうか。

とりあえずAとFの2キーを同時におされているときの挙動を見てみましょう。

画像5

AとFを押すから、まず5がLOWのときに1→5に電流が流れます。このとき、6はHIGHなので、2から6には電流は流れません。次に5がHIGHで6がLOWのときも同様ですね。仮に、AとBの同時押しでも、弊害は特におきなさそうなので、どうやら2キーの同時押しは対応しているみたいです。

では3キーのときはどうでしょうか。A,B,Eを同時に押してみましょう。

画像6

5がLOWで6がHIGHのときは1→5,2→5以外に特に電流は流れ無さそうです。5がHIGHで6がLOWのときはどうでしょうか。

画像7

1から6に電流が流れてEがおされた判定がなされます。同時に、Eの導線からAに通じて、AからBに通じるためにBの根本の2ピンもLOWになってしまい、Fが押されたという判定を受けます。これではダメです。(2→B→A→Eと電流が流れる)

電流が意図しない方向に流れることがあり、それを許してしまうと誤作動の原因となるようなので、電流の向きを強引に1→5に限定したりするように回路にダイオード(一方向にしか電流を流さない性質を持つ)をこんなふうに追加します。ダイオードは三角形に棒の記号です。(▷| ←こんなやつ) 図の回路で気をつけるべき点は緑の点が無くて、線が交わっているところは、ただ紙面の都合上交わっているだけで、接点は存在しないということです。なので、左上のIO2RからIO13Rに電流が流れるには必ずD42と書いてあるダイオードを通過することになります。

画像8

これで上から左へ電流が流れるようになって誤作動も起きないし、ピン数が減りましたね!

キーマトリクス

先程のような回路の仕組みをキーマトリクスと言います。一般的にキーボードなどでよく用いられる仕組みで、ピン数を節約しつつ、より多くのスイッチを確保するために使われます。

画像9

理論上はx行y列ならばxy個のスイッチが置けます。つまり、スイッチの数がn個のとき、2√n 個以上のスイッチがあれば、すべてのスイッチを判別可能ということです。(オーダー的にいえば、O(n)とO(√n)です。プログラマーならわかると思います。)

画像10

ということで、必要なピン数をグラフで表してみると、マトリクスを使わないときとの差は歴然ですね。一般的な分割キーボードは大体30~40キーくらい片方に使うので、キーマトリクスは必須です。

もっとキー数を増やしたいあなたへDuplexMatrix

え?フルサイズキーボードが作りたいから100個のスイッチを判別したくて、最低でも20ピン(10×10)必要で足りない?可変抵抗使ってボリュームスイッチ使いたいから、もっとピンがいる?なんとか減らせないか?

そんなあなたにまだ減らす方法をお伝えします。DuplexMatrixと名付けられたこのスキャン方式は自キー界隈では2年前に登場した比較的新参者(?)です。

DuplexMatrixの考え方はこうです。「OUTPUTのHIGHかLOWかだけなんてもったいない。もっと柔軟にGPIOピンを使おう。」ということで、これまでOUTPUT専門だったピンはINPUT_PULLUPを担うようになるし、INPUT_PULLUP専門だったピンはOUTPUTも担うようになります。下の図を見てください。

画像11

IO2R~4RがINPUT_PULLUPでIO12R,13RがOUTPUTだったのがこれまで通りのやつです。ここで逆方向のダイオード(D3とかD4とかD7とか)を付与されたスイッチを追加します。そして、IO2R~4RをOUTPUTにし、IO12R,13RをINPUT_PULLUPとします。そうすると、今度は逆方向のダイオード達が活躍し、違うスイッチの判定に使えます。こうすることで、キーマトリクスのピン数とは変わらずとも2倍のキー数に対応出来るようになります。ダイオードで逆流防止してるので、誤作動することもありません。そしてこのDuplexMatrixを用いれば、キー数n個について2√(n/2) 個以上のピン数で済みます。

画像12

これならProMicroのピン数(15)で、112キーまで対応可能で、フルサイズキーボードも、はたまたキー数は40キー程度でもボリュームをつけたいといった要望にも応えることが出来ます。

動作時間

ゲーマーだったり、めちゃくちゃタイピングが速い人はもしかしたらこう思うかもしれません。

「え、こんなにややこしいことして、俺のタイピング速度についていけるの?」

では次回は、実際にこのキーマトリクスや、DuplexMatrixに対応したプログラムを書いてみて、スキャン速度を測定してみましょう。

この記事が気に入ったらサポートをしてみませんか?