カシオの名作ミニキーボードSA-46(UK-01)をハックする話—その2:途中経過&ESP32でMCP23S17を使うメモ—

前の記事はこちら

www.creativity-ape.com

さて、前回鍵盤の読み取りまではうまく行ったものの、コントローラーに打鍵情報を送信するところで、かなりハマりました。

その後も、いろいろと紆余曲折があったので、ここでいったん途中経過をまとめます。

f:id:at_you_key:20200823171056j:plain

プランB〜Dの概要

前回プランAがボツになり、いまのところ実現可能性があるのが、このプランB~Dの3案です。

プランB

SPI接続のI/Oエキスパンダー「MCP23S17」を使い 、ソフトでキースキャンを乗っ取る → 保留

f:id:at_you_key:20200819203844j:plain

前回から引き続いて苦戦中の、スキャンラインの信号を読み取って、加工した打鍵信号をデータラインに流す案です。

  • I2Cでは通信が遅すぎたため、SPI版に切り替えた
  • なかなか動かずハマりまくった末、なんとか動かすことができたが、スキャンに追い付くのに十分な速度を出せなかった
  • もう少しソフトウェアスキルが身につけばいけるかも、今は深追いしない

プランC

I2C接続のI/Oエキスパンダー「MCP23017」を2つ使い、32個のフォトカプラーで鍵盤をエミュレートする → ボツ

f:id:at_you_key:20200819203900j:plain

これはフォトカプラーをキーの数使って、まるごとキーマトリクスを作ってしまうという、力技な案です。

  • こっちは人間の打鍵に追いつくスピードで良いので、I2Cで大丈夫なはず
  • キースキャンのタイミング管理とか不要なので、ソフトを書くのは楽
  • エレガントさ皆無、部品数がすごいことになる。消費電力も大きめ
  • 最近思いついたC案が良さそうなので、一旦ボツ

プランD

ロジックICを12個使って鍵盤をエミュレートする → 最新

f:id:at_you_key:20200821064807j:plain

思想はフォトカプラー案と同じです。いまのところ、これが最有力候補。

  • フォトカプラーをORゲート「74HC32」に置き換えたもの
  • フォトカプラ ー案に比べればコンパクト

プランDの予備実験

まずはチップ単体で実験しておきましょう。

よし、この案で進めることにしましょう。

(おまけ)ESP32でMCP23S17を使うメモ

さて、プランBでMCP23S17を使おうとしたときに、しばらく、というかだいぶハマったので、ハマりどころと対策をメモしておきます。

使うライブラリはこちら。

github.com

① 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);

これが罠でした。

ESP32で実行すると、OUTPUTになってしまうわけですね。当然プルアップも効きません。

プルアップ入力にしたいときは、こう書く必要があります。

Mcp23s17_0.pinMode(i, false);
Mcp23s17_0.pullupMode(i, true);

まあ、このライブラリはそもそもESP32をサポートしていないので、仕方ないんですが。

ライブラリもESP32も、サードパーティのものはArduinoの皮を被った別物と覚悟して、迷ったら面倒がらずにソースを読むべし、という教訓を得ました。

そんなわけで、無事動かせるようになったものの、プランBがボツになったので今回はお蔵入りです、残念。

つづく

この記事を書いているうちに、実作業のほうがけっこう進んでいるので、続きは近々!