Let's Splitで自作キーボード入門したので、I2Cで遊んでみた
この記事は自作キーボード Advent Calendar 2017 12/20 分の記事です。
はじめまして、ひでん (@klNth) です。
今回は友人に誘われ、まんまとキーボードを作ってしまったのでその話と、 せっかくマイコンが載っていてI2Cで通信できるということなので、それで遊んでみた話になります。
あらすじ
今年8月頃、Twitterで散々「Ergodox作りたい。Let's Split作りたい」と言っていたのがきっかけで、出来心で検索してしまい 挙げ句の果てにはその友人とLet's Splitの部品を共同購入し作ってしまいました。
手前のが自分ので、奥のが友人のです。
スイッチやアクリルボードなどの手配、加工は友人が。自分はダイオードとケーブル類の調達などをやりました。 主に友人が調達で大変な部分をやってくれて、本当に助かりました。
キーキャップは袋詰めでいろいろな色が入っているものを購入し山分けしました。スイッチはGateronの黒をチョイス。 一通り組み立てた後に、I2C接続のためにはちょっとしたジャンパーを接続しないといけないことを知り、苦し紛れで接続しました。
初めて分離型&格子状配列なキーボードを使ってますが、肩を開いてタイピングできることに惚れて仕事先へ投入しました。 コレなしだとどうも捗らなくなってしまいました。
I2Cで遊ぶ話
さて、本題です。
このLet's Splitは4極ケーブルを使用し追加の部品をいくつか付ける事でI2Cで分離させているキーボード同士を通信させることができます。
I2Cというのは低速の通信バス規格ですが、これはマスターに対して複数のスレーブをぶら下げることができるので、いろんな機器の中でセンサーだったりちょっとしたICだったりを接続するためによく使用されています。
つまり、I2Cで接続しているLet's Split同士の間に全く異なるICを接続し利用することができます。QMK Firmwareのキーマップの中にもOLEDディスプレイを使用するサンプルがあるようです。
今回はこのI2CにRTC(Real Time Clock)ICであるPCF2127 をぶら下げて、キーボード側からいじれるか試してみました。
まずは信号を見る
ぶら下げる前に、通常状態でのI2C信号を見てみました。ディジタルオシロスコープを使用してやっていきましょう。
オシロスコープをLet's Splitのこの位置に接続し、波形を見てみます。
長めのケーブルを使用しているからか、I2Cの信号がかなり鈍っていて、良くないです。 ケーブルを短くするのは実用上避けたいので、とりあえずは5.1kOhmと大きめだったI2Cのプルアップ抵抗を1.4kOhm程度に小さくしました。
まあこんなものでしょう。面倒くさくなって片方の基板にしかプルアップ抵抗を着けてないのも原因の一つでしょうが、とりあえずはこれでいきます。
ソースコードをいじる
ここからはQMK Firmwareをいじっていきます。
Let's SplitではI2C通信用にi2c.hを自前で持っていて、lets_splitディレクトリ下のmatrix.cにそれを使用した通信用の関数i2c_transaction()があります。
これを参考にすれば、I2C通信用のコードを仕込めそうです。
今回使用するPCF2127のデータシートを読んで、初期設定値をいくつか設定したいと思います。 キーボードの起動時に一度だけ呼ばれる関数は、lets_splitディレクトリ下のsplit_util.c にあります。
なのでこの中でこんな感じの関数を書いてあげると、起動時に一度だけ走る、初期化用の関数ができあがります。
次はキーが押されたときにI2C通信が行われるようにします。こちらはkeymap.cにいくつか追加すればいけそうだったので、こんな感じに追加しました。
qmk_firmware/keymap.c at master · klaNath/qmk_firmware · GitHub
基本的にはキーが押されたときに分岐してI2C通信用の関数を呼ぶようにすればOKみたいです。 このテスト用のコードでは、I2CTESTを割り当てたキーが押された場合に、RTCの秒数をカウントしているレジスタを読みにいっています。 戻り値は捨てているので、まだLet's Splitのほうではなにもできません。ので、オシロスコープで読んで見ておきます。
ICをブレッドボードに乗っけて、それをICクリップを使って半ば無理矢理に電源と信号を接続しています。このLet's Splitに使用しているPro Microは5V版なので電源電圧も5Vが出ていますが、PCF2127は3.3Vを要求していますので手頃なシリーズレギュレーターで電圧を合わせておきます。
それではファームウェアをビルドし直して書き込み、試してみます。
これは初期化関数で送信された通信の様子です。問題無く送信されているようです。
これはキーを押したときに、秒レジスタを読んでいる時の様子です。うまく読めているみたいです。 波形下のI2Cと引かれたラインにあるDATA=B9H~Aがデータの内容です。MSBは秒数データに関係なく1になっていて、あとは4bitごとのBCDフォーマットとすれば良いらしいので39秒を表しているようです。
このデータを読んだ後も、一秒間隔くらいでキーを押すことでデータがカウントアップしていくのが確認できたので、正しくデータは読めているようです。
今後
今回は仕事であまり時間が取れず、ここまでとなってしまいました。
本来ならば、ここからRTCの時刻設定と液晶制御を追加して、Let's Splitに時計機能を追加する予定でした。いつかきっと・・・
思ったよりもQMK Firmwareはいじって遊べるようです。なにか新しいネタを思いついたら試してみたいと思いますし、正直言ってファームウェアの全体像がまだつかめていないので、コードを読んでいこうとも思います。
次の記事は IKeJI さんです。
この記事はSun Type 7 USB Keyboardで書きました。レツプリは真改造されていていますので、もう一台作りたいなあ…