Wi-Fi(wifi)モジュールESP8266の内、NodeMCU開発ボードを使ってWiFi越しに動く電動ロールスクリーンを作ってみるページ。
以前、作ったArduino+ステッピングモータ28BYJ-48製電動ロールカーテンを無線化したもの。
WebSocket版ロールスクリーンと併行して、今回は、操作にあたり、MQTTを介すことにしました。
完成後は不要かもしれませんが、モノがモノ、場所が場所だけにAruduinoOTAを使ってOTA(Over The Air/無線)アップデートできるようにしました。
そうそう要らないでしょ...と思っていたのですが、今回のケースでは、超絶便利でした。
これに伴い、3通りほどあるらしき、実装方法の内、Arduino IDEを使う前提のmDNS機能を必要とするものを選びました。
ほとんどは、Arduino版に書いた通りですが、材料については、個々の環境に合わせて適宜用意していただければ。
mDNS機能を持つパッケージアプリケーションとしてLinuxならAvahi、Mac/WindowsならBonjourがインストール済みであること(macOSはBonjourはプリインストール済みのはず)。
Arduino IDEが利用できることは、もちろん、ESP8266やESP32をArduino IDEで使えるようにしておくこと。
ESP-01やESP-02〜ESP14などのESP8266チップなら、Arduino IDEの[ツール] => [ボード]から[Generic ESP8266 Module]を選択、ESPモジュールにスケッチをアップロードできる状態であること。
ESP32なら、[espressif/arduino-esp32]の要領でESPモジュールにスケッチをアップロードできる状態であること。
ちなみにこれらArduino IDEの環境設定で追加する方法の場合、カンマ区切りで複数指定可能。
操作仲介役のMQTTブローカーと操作・実行用のMQTTクライアントを準備すること。
今回、MQTTブローカーは、PCにインストール、操作もPCから行うものとしました。
自身のメインOSは、Debian GNU/Linuxで、ブローカーとクライアントとして有名なmosquittoとmosquitto-clientsをaptでインストールしました。
が、この手法で常用するとしたら、必要都度起動しているRaspberry Pi 2 Model B/Raspbianサーバがあるので常時起動させるのもありですし、決まった操作なら、別途、物理ボタン回路のあるESP8266/ESP32を併用してESPモジュールからパブリッシュすればよいかなとも思っています。
というか、どうやら、 martin-ger / esp_mqttと併せ、そこにある通り、ブローカー martin-ger / uMQTTBrokerライブラリを使わせて頂くとESP8266/ESP32をもMQTTブローカーやMQTTクライアントとして使えるとのことなのでOpenHABなどを併用すれば尚のこと、遠隔など外部から通信したい場合もクラウドにどっぷり依存することなく、ローカル側である程度コントロールできるでしょうし、また、Zero含めラズパイを使うよりも低コストでMQTT環境を整えることができそうです。
回路については、ほぼ、Arduino版のArduinoが、ESPボードに変わっただけです。
実のところ、今回は、逆流防止のダイオードは入れなかったのですが、少なくともスクリーンの上限下限の位置決めが終わるまでは、シャフトを手動で回すことがあったりし、発電機のような状態になるので各モーターピン用にいるかもなと思った次第です。
また、操作は、物理スイッチではなく、後述の通り、MQTTを介し、遠隔操作するだけです。
電源は、十分な電流を供給できるACアダプタなどを降圧して使えば、5V程度(今回は、ブレッドボード用電源やDC/DC降圧コンバータ+DCジャック端子台アダプタ)でもESPボードのVIN/GNDとモーター用5V/GNDを共用しても、もちろん、モーター用と分けても十分機能します。
尚、共有する場合の電源が、モバイルバッテリーだと(機能時、電流を要するため、自動OFFはしないものの、)特に巻き上げ時、トルク不足と勘違いするような状況で稀にしかうまくいきません。
また、モーターを別電源とし、ESPボードへの電源供給専用としてならモバイルバッテリーでも十分ですが、別電源によってスクリーン動作中であってもESPボードには供給(充電)不要と判断され、自動OFFしてしまいます。
よって強力な電源で共用するか、ESPボードは、電源タップに挿したAC充電アダプタから供給するかの何れかになるでしょう。
いろいろやってみた中で、これをしなくてもできたのですが...。
一からやってみたら、これをしないとできなかったので基本に忠実にWiFi SSIDとパスフレーズのみ環境に合わせたBasicOTAをNodeMCUボードにアップロード。
その上でBasicOTAの内容を網羅したオリジナルスケッチをNodeMCUボードにアップロード。
これでOTAアップデートできるようになります。
今回のスケッチは、こんな感じ。
Step_motor_MQTT.inoと以前のArduino版ロールスクリーンで使ったスケッチ、Stepper、ArduinoOTA、ESP8266mDNS各ライブラリの合作です。
便利なもので後述のようにMQTTクライアントからメッセージが送信されるとESP8266/ESP32にアップロードしたスケッチのcallback関数がコールされ、payload引数にその値が入ってきます。
ブローカーmosquittoとクライアントmosquitto-clientsを入れたDebian PCにおいては、端末(≒ターミナル)を開き、このようにメッセージを送信(パブリッシュ)します。
ここでは、スケッチ内容に合わせてメッセージを1としていますが、文字列も送信できます。
[-d]オプションでデーモンを起動、[-t]はトピック名、-mは、メッセージ(受け取る側・ブローカーから見るとペイロード)です。
ちなみに毎回[-d]オプションを付けてもエラーにはなりません。
今回の自作ロールスクリーンにおいては、1でスクリーン上昇、2で下降し、予め検証し、(脱調しない限りは、)良き位置で止まる値FullOpenCloseNumを設定してあるのでそれぞれリミットスイッチ不要で自動的に止まります。
MQTTは、ブローカーをサーバとして介し、トピックを目印にやり取りするパブリッシュ・サブスクライブ(Publish・Subscribe/出版・購読/パブ・サブ)方式で非同期・同期通信を行うことができるIBM起源のプロトコルです。
非同期通信できるHTML5実装のWebSocketやMQTTなら任意の時点でモータの停止もできる...と思ったら、割り込み方法を思いつかず、全開・全閉のみで停止については実装できていません。
ただ、非同期なのでスクリーン稼働中に他のメッセージを送信(操作)することはでき、HTTP TCP/IPのようにフリーズすることはありません(が、今のところ、途中で逆転させたり、停止させたりはできません)。