使って適当に工作したメモを残していきます。API前回までで、Alexaからテレビを操作できるようになりました。同じ方法でルンバも操作しようとしたところ、lircでルンバのリモコンコードを読み取る際にエラーになってしまいました。理由がまるで分からず。PiではなくArduinoからルンバを操作することにしました。PiとArduinoのどちらでも赤外線が使える、というだけの話ですが。Arduinoを使う場合、まずは母艦のNode-REDからの通信を受け取らないとどうにもなりません。言え、数ビットの無線信号を受け取れれば良いだけなので、ESP-WROOM-02やBluetoothなど手段はいくらでもあります。今回は、余っていた古いFlashAir(W-02)を使いました。API経由で制御する【今回】(おまけ)ArduinoからROI経由でルンバを動かすArduinoから赤外線経由でルンバを動かすNode-REDからFlashAir/Arduino経由でルンバを動かすFlashAirのGPIO機能FlashAirのGPIO機能を使うと、SDカードの端子のうちの5つをHTTP経由でGPIOピンとして使用できます。Developersに詳しく説明されています。FlashAirの端子とArduinoのピンを接続すると、ArduinoのピンのHigh/LowをHTTPから切り替えられます。そのかわり、FlashAirのストレージとしての機能は使えなくなります。ファイルを編集します。通常は不可視フォルダになっていますが、LinuxやMacでマウントするとShell経由で普通に編集できます。Windowsの場合は不可視フォルダを表示すれば良いと思います。このファイルを開いて末尾にIFMODE=1を追加すればGPIO機能が有効になります。FlashAirをWiFi子機にする通常、FlashAirはWiFiの親機として動作します。そのため、自宅のLANの中にあるNode-REDからのHTTPリクエストを受け取れません。そこで、FlashAirを無線子機としてWiFiルータに接続させます。Developersに詳しく書かれています。「ステーションモードの利用」そんなこんなで、出来上がったCONFIGファイルは次のようになります。APPMODE=5APPNAME={FlashAirの名前}APPSSID={WiFiのSSID}APPNETWORKKEY={WiFiのパスワード}CIPATH=/DCIM/100__TSB/FA000001.JPGVERSION=F19BAW3AW2.00.00CID=02544d535730384708c00b7d7800d201PRODUCT=FlashAirVENDOR=TOSHIBAMASTERCODE=18002d4ff0a2IFMODE=1FlashAirとArduinoを接続こんな感じのSDカードスロットを使ってArduinoと接続します。今回はルンバの起動ができれば良いだけなので1ビット送れれば十分です。そのため、信号ピン1つと3.3V、GNDの3ピンだけ接続します。FlashAirのSDIをArduinoの11ピンに繋ぎました。3.3VとGNDは適宜。Developersの「SDインターフェース端子のI/O利用(op=190)」に書かれています。今回はSDOピン(CMD)をGPIOとして使うので、0x01のHIGH/LOWを切り替えられれば良いです。URLパラメータとGPIOの組み合わせは次の通りです。op=190&CTRL=0x1f&DATA=0x00ArduinoでFlashAirのGPIOを読むArduinoからピンの状態を読むのは普通に「digitalRead」で良いです。ライブラリも何も必要ありません。注意点としては、FlashAir起動時は全てのピンがHIGHになっていることでしょうか。SDOピンがHIGHの状態を検知してルンバを起動させようと考えた場合、FlashAirの電源投入時にHIGHなのでいきなりルンバが起動してしまいます。電子回路的にHIGH/LOWを反転させても良いのですが、部品点数が増えて面倒なので、Node-RED側で一旦LOWに落としてからHIGHにするようなリクエストを投げることで回避しました。したら、Arduinoで一旦pinModeをOUTPUTにしてLOWに落とせるのかもしれませんが試していません。Arduinoのコードはこんな感じです。delay(1000);}Node-REDからArduinoにHTTPリクエスト少々ブサイクですが、次のようにしました。Alexaに「ルンバで掃除して」と言うと左端の「ルンバ」ノードが呼ばれます。reset」が呼ばれます。reset」はHTTPリクエストのノードです。FlashAirに「op=190&CTRL=0x1f&DATA=0x00」を投げて全てのピンをゼロリセットしています。FlashAirの起動後、2回目以降の「ルンバ掃除して」の場合は前回呼び出し時にゼロリセットされているので、この処理は無意味になります。resetが先に実行されるように、上部のフローでは2秒delayが入っています。resetの実行後にフラグを書き換えるなどしてロックした方が良さそうに思いますが手抜きです。この手抜きのせいで、「ルンバ掃除して」と言ってから実行されるまでに2秒掛かってしまうので微妙に違和感があります。clean」が呼ばれます。これは「op=190&CTRL=0x1f&DATA=0x01」でSDOピンをHIGHにしています。この時点でArduino側ではルンバの制御に入ります。その後、5秒delayを掛けて再度ゼロリセットしておきます。5秒というのは、Arduino側がHIGHを確実に検知できるよう、長めに取っています。最初のdelayについては、もし検知し損ねても処理に失敗するのは起動後最初の1回だけなのでイライラが少ないです。長すぎると「ルンバ掃除して」からのタイムラグが長くなってしまうため、できるだけ短く。2回目のdelayは短かすぎると毎回失敗し、長くてもユーザビリティに影響ないので長めに。ここまででNode-REDからHTTP経由でArduinoに1ビット信号を送ることができるようになりました。次回はArduinoからルンバを操作します。