前の記事はこちら
さて、前回鍵盤の読み取りまではうまく行ったものの、コントローラーに打鍵情報を送信するところで、かなりハマりました。
その後も、いろいろと紆余曲折があったので、ここでいったん途中経過をまとめます。
プランB〜Dの概要
前回プランAがボツになり、いまのところ実現可能性があるのが、このプランB~Dの3案です。
プランB
SPI接続のI/Oエキスパンダー「MCP23S17」を使い 、ソフトでキースキャンを乗っ取る → 保留
前回から引き続いて苦戦中の、スキャンラインの信号を読み取って、加工した打鍵信号をデータラインに流す案です。
- I2Cでは通信が遅すぎたため、SPI版に切り替えた
- なかなか動かずハマりまくった末、なんとか動かすことができたが、スキャンに追い付くのに十分な速度を出せなかった
- もう少しソフトウェアスキルが身につけばいけるかも、今は深追いしない
プランC
I2C接続のI/Oエキスパンダー「MCP23017」を2つ使い、32個のフォトカプラーで鍵盤をエミュレートする → ボツ
これはフォトカプラーをキーの数使って、まるごとキーマトリクスを作ってしまうという、力技な案です。
- こっちは人間の打鍵に追いつくスピードで良いので、I2Cで大丈夫なはず
- キースキャンのタイミング管理とか不要なので、ソフトを書くのは楽
- エレガントさ皆無、部品数がすごいことになる。消費電力も大きめ
- 最近思いついたC案が良さそうなので、一旦ボツ
プランD
ロジックICを12個使って鍵盤をエミュレートする → 最新
思想はフォトカプラー案と同じです。いまのところ、これが最有力候補。
- フォトカプラーをORゲート「74HC32」に置き換えたもの
- フォトカプラ ー案に比べればコンパクト
プランDの予備実験
まずはチップ単体で実験しておきましょう。
2ビット分での予備実験は成功!これはいける! pic.twitter.com/EFWt2frAJx
— アツユキ (@aaa_tu) 2020年8月12日
よし、この案で進めることにしましょう。
(おまけ)ESP32でMCP23S17を使うメモ
さて、プランBでMCP23S17を使おうとしたときに、しばらく、というかだいぶハマったので、ハマりどころと対策をメモしておきます。
使うライブラリはこちら。
① exampleのコメントがフォーク元のまんまでハマる
MCP23S17は、A0~A2ピンでアドレス指定することで、SSひとつにつき8つまで扱うことができます。
デフォルトはアドレス0x0になっていて、アドレスを指定したい場合のやり方は、exampleのコメントにこう書かれています。
// MCP23S17 Mcp23s17_0 = MCP23S17(MCP23S17_SLAVE_SELECT_PIN,0x0);
第2引数に、ピンで指定した0x0〜0x7のアドレスを書き込めば良いわけですね。
これがひとつめの罠です。
このフォークの追加機能では
added optional cached mode to avoid reading when writing, added methods for deferred writing
というのが追加されていて、この機能のON/OFFを指定する第三引数が無いと動きません。
今回は、従来通りの挙動が欲しいので、こうです。
MCP23S17 Mcp23s17_0 = MCP23S17(MCP23S17_SLAVE_SELECT_PIN,0x0,false);
② ArduinoとArduino-ESP32の定数の違いでハマる
このライブラリ、Arduinoと同じインターフェースでI/Oをコントロールできるので、とても取っつきやすいです。 ピン設定も見慣れた関数が用意されているので、Arduinoに飼いならされた我々は、当然このように書きますね。
Mcp23s17_0.pinMode(i, INPUT); Mcp23s17_0.pullupMode(i, HIGH);
これが罠でした。
入力ピンがプルアップできない問題があって暫くハマった結果、INPUT/OUTPUTの定数がArduinoとArduino-esp32で違う罠だった。
— アツユキ (@aaa_tu) 2020年7月21日
MCP23S17のライブラリはピンモードを真偽で受けていたので、どうりでESP32だと必ず出力設定になるんだなぁ。 pic.twitter.com/1rgSmI4ZJA
ESP32で実行すると、OUTPUTになってしまうわけですね。当然プルアップも効きません。
プルアップ入力にしたいときは、こう書く必要があります。
Mcp23s17_0.pinMode(i, false); Mcp23s17_0.pullupMode(i, true);
まあ、このライブラリはそもそもESP32をサポートしていないので、仕方ないんですが。
ライブラリもESP32も、サードパーティのものはArduinoの皮を被った別物と覚悟して、迷ったら面倒がらずにソースを読むべし、という教訓を得ました。
そんなわけで、無事動かせるようになったものの、プランBがボツになったので今回はお蔵入りです、残念。
つづく
この記事を書いているうちに、実作業のほうがけっこう進んでいるので、続きは近々!
入出力組み合わせてのパススルーテスト
— アツユキ (@aaa_tu) 2020年8月17日
レイテンシーもほとんどなく、うまく動いてくれている!
次の目標は、サステイン、アルペジエーター、BLE-MIDI機能の実装かな pic.twitter.com/Osiobg6vPg