1.実験の概要
下図のようにシンプルな構成で、双方向通信の実験を行います。デバイスの数を増やして多対多の通信を試すことも考えられますが、その場合はデバイスにさらにLEDやスイッチ類を追加することが必要になるので取りやめ、少々横着をしています。だた、実験してみると明らかになりますが、2つのデバイス間の双方向通信が理解できると、複数デバイスへの対応はとても簡単なことがわかると思います。
計測デバイスには温湿度センサーと赤色プッシュボタンがあり、一定の時間間隔で計測した温湿度情報をパブリッシュします。また赤色プッシュボタンを押すとシグナルをパブリッシュします。同時に、監視デバイスからのボタン押下シグナルをサブスクライブして、それが届くと黄色LEDを点灯/消灯します。
一方、監視デバイスは温湿度情報をサブスクライブしてOLEディスプレイの表示を更新、計測デバイスからのボタン押下シグナルもサブスクライブしていて、届くと赤色LEDを点灯/消灯します。そして黄色プッシュボタンが押されると、押下シグナルをパブリッシュします。
このようにして、2つのデバイスはそれぞれ独立してパブリッシュとサブスクライブを実行し、サブスクライブの結果をOLEDディスプレイやLEDの点滅に反映させます。なお、今回の実験ではセキュリティについては考慮していません。
2.トピックの設定
実験の概要が決まったところで、それぞれのパブリッシュ/サブスクライブで指定するトピックを決めておきましょう。
それぞれのデバイスのパブリッシュとサブスクライブのメッセージを整理すると次表のようになります。デバイス右の()は便宜上のデバイス名、メッセージの()はデータ名称です。
計測デバイス(device1) | 監視デバイス(device2) | ||
パブリッシュ | サブスクライブ | パブリッシュ | サブスクライブ |
温湿度計測情報 (measured_value) | 温湿度計測情報 (measured_value) | ||
赤色ボタン押下 (button_on) | 赤色ボタン押下 (button_on) | ||
黄色ボタン押下 (button_on) | 黄色ボタン押下 (button_on) |
トピックはパブリッシュ時に設定するメッセージの識別キーなので、デバイス名とパブリッシュのデータ名称を組み合わせて設定することにしましょう。
・device1/measured_value : 計測デバイスの温湿度情報
・device1/button_on : 計測デバイスの赤色ボタン押下情報
・device2/button_on : 監視デバイスの黄色ボタン押下情報
メッセージを受信したいデバイスは、これらのトピックから必要なものを指定してサブスクライブすることになります。
ここまで決めたのですから、ついでに、計測デバイス側と監視デバイス側のコードを分かりやすくするために、トピックを定数定義しておきましょう。
// 計測デバイス側トピックス
const char* publishMeasuredValue = "device1/measured_value";
const char* publishPushbutton = "device1/button_on";
const char* subscribePushbutton = "device2/button_on";
// 監視デバイス側トピックス
const char* publishPushbutton = "device2/button_on";
const char* subscribeMeasuredValue = "device1/measured_value";
const char* subscribePushbutton = "device1/button_on";
それぞれのトピックに対応したサブスクライブ時の処理は次の通りです。
・device2/button_on : 計測デバイスの黄色LEDを点灯または消灯する。
・device1/measured_value : 監視デバイスのOLEDディスプレイに受信計測値を表示する。
・device1/button_on : 監視デバイスの赤色LEDを点灯または消灯する。
3.MQTTライブラリーとプログラム構造
(1)MQTTライブラリーのインストール
ESP32でMQTT通信を使用するには、非同期TCPライブラリーと非同期MQTTクライアントライブラリーが必要になります。次のようにして、Arduino IDEにこれらのライブラリーをインストールします(PlatformIOとVSCodeを使う場合は、Ⅴ-1. ESP32によるIoTゲートウェイの開発①を参考にして、プロジェクト"MQTTDevice1"を作成後にインストールしてください)。
①非同期TCPライブラリーのインストール
・ここをクリックしてAsync TCPライブラリーをダウンロードしてください。
・zipフォルダを解凍すると、AsyncTCP-masterフォルダが表示されます。
・フォルダー名をAsyncTCPに変更して、Arduino IDEのインストールライブラリーフォルダーに移動します。
②非同期MQTTクライアントライブラリーのインストール
・ここをクリックしてAsync MQTTクライアントライブラリーをダウンロードしてください。
・zipフォルダを解凍すると、async-mqtt-client-masterフォルダが表示されます。
・フォルダー名をasync-mqtt-client に変更して、Arduino IDEのインストールライブラリーフォルダーに移動。
(参考)
Windows環境では、Arduino IDEインストールライブラリーフォルダーは次の位置にあります。
C:\Users\User-Name\AppData\Local\Arduino15\packages\esp32\hardware\esp32\1.0.?\libraries
(2)MQTTのドキュメントとサンプルコード
先に配置したasync-mqtt-clientフォルダーを開くと、docsフォルダーとexamplesフォルダーがあります。docsフォルダーには、MQTTクライアント用の多数のAPIについての解説や、onMessageコールバックの最大受信サイズが約1460バイトであること、ペイロード最大サイズは無制限であることなどの重要な情報が記載されているので、ぜひ一読をお勧めします。
examplesフォルダー配下にはFullyFeatured-ESP32、FullyFeatured-ESP8266、FullyFeaturedSSLの3つのフォルダーがあり、MQTT通信プログラムを作成するための骨格として利用できるスケッチが収納されています。今回のプロジェクトはFullyFeatured-ESP32.inoを下敷きにしています。コメントが少ないので少々わかりにくいですが、パブリッシュやサブスクライブに伴うデバイス固有の処理以外は、スケッチのほとんどの部分を流用することができます。
(3)コーディングスタイルなどについて
以降の開発はArduino IDEで行うことにして、PlatformIO+VSCode環境での内容は割愛します。ただし両方で開発するケースを考えて、冗長にはなりますがArduiuno IDEでは必要としない次のコードを記述しています。
・先頭でヘッダーファイル「Arduino.h」をインクルードしています。
・関数の記述順序に縛られないため、関数の前方宣言(関数プロトタイプ)を記述しています。
4.ブローカーの構築
Raspberry PiにオープンソースのMosquitto Brokerをインストールして、ブローカーを構築します。MosquittoはQoS0~3の全レベルとWillやRetainの機能も備えています。しかも、インストールはきわめて簡単です。
Raspberry PiはWi-Fiが動作すればどんなモデルでもかまいません。すでにOSをインストール済みのものがあれば、それで試してみてください。冒頭で述べたように、ここでは、以前開発したNASにMosquittoを追加インストールしています。ブローカーインストールの前提条件はただひとつ、固定IPアドレスを設定していることです。まだであれば、このサイトのRaspberry Pi関連記事のあちこちで解説しているので参考にしてください。
①Mosquitto Brokerをインストールする
$ sudo apt update $ sudo apt install -y mosquitto mosquitto-clients |
②起動時にMosquittoを自動起動させるように設定する
$ sudo systemctl enable mosquitto.service |
③確認:バージョンを表示してみる
$ mosquitto -v |
mosquitto version 1.4.10 (build date Wed, 17 Oct 2018 19:03:03 +0200) starting
以上でブローカーのインストールは完了です。
これでESP32によるMQTT通信システムの開発準備が完了しました。
次回は、計測用デバイスのパブリッシュ/サブスクライブ・プログラムを開発します。お楽しみに!