Wi-Fi をつないだ Arduino UNO WiFi Rev.2 で Beebotte MQTT ブローカーにデータを送るメモです。
Wi-Fi をまずつなぐ
こちらの記事でWi-Fi をまずつないだところ、ESP32でやったことあるような Wi-Fi 接続のお作法とライブラリの呼び出しが変わらない感じなので、このまま、 Beebotte の MQTT ブローカーにつないでみます。
Beebotte の MQTT ブローカーにつなぐ設定の確認
Beebotte の MQTT ブローカーにつなぐ設定については、Node-RED で一旦つないでみたこちらを参考にしてみてください。
test チャンネルで res リソースグループを利用しています。
- MQTTブローカー先
- mqtt.beebotte.com
- ポート
- 1883
- 接続するユーザー名
- Channel Token を使う
- 接続するパスワード
- (なにも書かない)
- 接続トピック
チャンネル名
/リソースグループ名
を設定- test チャンネルで res リソースグループの場合は
test/res
この記事でつないだ設定をそのまま使っていきます。まず、つながるということが分かっていると気が楽ですね!
プログラム
Arduino UNO WiFi Rev.2 に書き込んだプログラムはこちらです。
起動後すぐに Wi-Fi をつなぎに行き、Beebotte MQTT ブローカーにつながった瞬間に {"message":"Connected"}
というメッセージを送っています。
// WiFiNINA ライブラリ #include <SPI.h> #include <WiFiNINA.h> // MQTT をつなぐためのライブラリ // 今回追加インストールする #include <PubSubClient.h> // インストールすれば色がつく // JSON を扱いやすくするライブラリ #include <ArduinoJson.h> // こちらは色がついてなくてOK // Wi-FiのSSID char *ssid = "<Wi-Fi SSID>"; // Wi-Fiのパスワード char *password = "<Wi-Fi PASSWORD>"; // 今回使いたい Beebotte のブローカーのアドレス const char *mqttEndpoint = "mqtt.beebotte.com"; // 今回使いたい Beebotte のポート const int mqttPort = 1883; // 今回使いたい Beebotte のユーザー名 const char *mqttUsername = "<Channel Token>"; // 今回使いたい Beebotte のパスワード const char *mqttPassword = ""; // デバイスID // デバイスIDは機器ごとにユニークにします // YOURNAME を自分の名前の英数字に変更します // デバイスIDは同じMQTTブローカー内で重複すると大変なので、後の処理でさらにランダム値を付与してますが、名前を変えるのが確実なので、ちゃんと変更しましょう。 char *deviceID = "UNO-Rev2-WiFi"; // MQTT メッセージをに知らせるトピック char *pubTopic = "test/res"; // MQTT メッセージを受け取るトピック char *subTopic = "test/res"; // JSON 送信時に使う buffer char pubJson[255]; // PubSubClient まわりの準備 WiFiClient httpClient; PubSubClient mqttClient(httpClient); void setup() { Serial.begin(9600); // WiFi 接続開始 Serial.print("WiFi Connecting WPA SSID: "); Serial.println(ssid); while (WiFi.status() != WL_CONNECTED) { delay(500); // Connect to WPA/WPA2 network: WiFi.begin(ssid, password); Serial.print("."); } // 接続完了メッセージ Serial.print("WiFi Connected"); printCurrentNet(); printWifiData(); delay(2000); // MQTT の接続先設定 mqttClient.setServer(mqttEndpoint, mqttPort); // MQTT のデータを受け取った時(購読時)の動作を設定 mqttClient.setCallback(mqttCallback); // MQTT の接続 mqttConnect(); } void mqttConnect() { // MQTT clientID のランダム化(名称重複対策) char clientID[40] = "clientID"; String rndNum = String(random(0xffffff), HEX); String deviceIDRandStr = String(deviceID); deviceIDRandStr.concat("-"); deviceIDRandStr.concat(rndNum); deviceIDRandStr.toCharArray(clientID, 40); Serial.println("[MQTT]"); Serial.println(""); Serial.println("- clientID "); Serial.println(clientID); // 接続されるまで待ちます while (!mqttClient.connected()) { if (mqttClient.connect(clientID,mqttUsername,mqttPassword)) { Serial.println("- MQTT Connected."); // subTopic 変数で指定されたトピックに向けてデータを送ります int qos = 0; mqttClient.subscribe(subTopic, qos); Serial.println("- MQTT Subscribe start."); Serial.println(subTopic); // 初回データ送信 publish /////////// // データ送信のための JSON をつくる DynamicJsonDocument doc(1024); doc["message"] = "Connected"; // pubJson という変数に JSON 文字列化されたものが入る serializeJson(doc, pubJson); // pubTopic 変数で指定されたトピックに向けてデータを送ります mqttClient.publish(pubTopic, pubJson); } else { // MQTT 接続エラーの場合はつながるまで 5 秒ごとに繰り返します Serial.print("Failed. Error state="); Serial.println(mqttClient.state()); // Wait 5 seconds before retrying delay(5000); } } } // JSON を格納する StaticJsonDocument を準備 StaticJsonDocument<2048> jsonData; // MQTT のデータを受け取った時(購読時)の動作を設定 void mqttCallback (char* topic, byte* payload, unsigned int length) { // データ取得 String str = ""; Serial.print("Received. topic="); Serial.println(topic); for (int i = 0; i < length; i++) { Serial.print((char)payload[i]); str += (char)payload[i]; } Serial.print("\n"); // 来た文字列を JSON 化して扱いやすくする // 変換する対象は jsonData という変数 DeserializationError error = deserializeJson(jsonData, str); // JSON パースのテスト if (error) { Serial.print(F("deserializeJson() failed: ")); Serial.println(error.f_str()); return; } // 以下 jsonData 内が JSON として呼び出せる Serial.println("MQTT Subscribed data"); // データの取り出し // https://arduinojson.org/v6/example/parser/ const char* message = jsonData["message"]; // データの表示 Serial.println(message); } // 常にチェックして切断されたら復帰できるようにする対応 void mqttLoop() { if (!mqttClient.connected()) { mqttConnect(); } mqttClient.loop(); } void loop() { // 常にチェックして切断されたら復帰できるようにする対応 mqttLoop(); } void printWifiData() { // print your board's IP address: IPAddress ip = WiFi.localIP(); Serial.print("IP Address: "); Serial.println(ip); Serial.println(ip); // print your MAC address: byte mac[6]; WiFi.macAddress(mac); Serial.print("MAC address: "); printMacAddress(mac); } void printCurrentNet() { // print the SSID of the network you're attached to: Serial.print("SSID: "); Serial.println(WiFi.SSID()); // print the MAC address of the router you're attached to: byte bssid[6]; WiFi.BSSID(bssid); Serial.print("BSSID: "); printMacAddress(bssid); // print the received signal strength: long rssi = WiFi.RSSI(); Serial.print("signal strength (RSSI):"); Serial.println(rssi); // print the encryption type: byte encryption = WiFi.encryptionType(); Serial.print("Encryption Type:"); Serial.println(encryption, HEX); Serial.println(); } void printMacAddress(byte mac[]) { for (int i = 5; i >= 0; i--) { if (mac[i] < 16) { Serial.print("0"); } Serial.print(mac[i], HEX); if (i > 0) { Serial.print(":"); } } Serial.println(); }
設定を書き換える
以下を変更します。
// Wi-FiのSSID char *ssid = "<Wi-Fi SSID>"; // Wi-Fiのパスワード char *password = "<Wi-Fi PASSWORD>"; // 今回使いたい Beebotte のブローカーのアドレス const char *mqttEndpoint = "mqtt.beebotte.com"; // 今回使いたい Beebotte のポート const int mqttPort = 1883; // 今回使いたい Beebotte のユーザー名 const char *mqttUsername = "<Channel Token>"; // 今回使いたい Beebotte のパスワード const char *mqttPassword = ""; // デバイスID // デバイスIDは機器ごとにユニークにします // YOURNAME を自分の名前の英数字に変更します // デバイスIDは同じMQTTブローカー内で重複すると大変なので、後の処理でさらにランダム値を付与してますが、名前を変えるのが確実なので、ちゃんと変更しましょう。 char *deviceID = "UNO-Rev2-WiFi"; // MQTT メッセージをに知らせるトピック char *pubTopic = "test/res"; // MQTT メッセージを受け取るトピック char *subTopic = "test/res";
<Wi-Fi SSID>
- つなぎたい Wi-Fi の SSID
<Wi-Fi PASSWORD>
- つなぎたい Wi-Fi の パスワード
<Channel Token>
- 今回使いたい Beebotte のユーザー名 → Channel Token を入れる
Wi-Fi まわりは、Arduino UNO WiFi Rev.2 で Wi-Fi をつないでみるメモ、Beebotte の Channel Token まわりは Beebotte の MQTT ブローカーと Node-RED の MQTT ノードでやり取りをするメモ を事前に試しておくと成功しやすいと思います。
PubSubClient と ArduinoJson ライブラリのインストール
// MQTT をつなぐためのライブラリ // 今回追加インストールする #include <PubSubClient.h> // インストールすれば色がつく // JSON を扱いやすくするライブラリ #include <ArduinoJson.h> // こちらは色がついてなくてOK
PubSubClient と ArduinoJson については、ライブラリマネージャから検索してインストールしておき、事前に使えるようにしましょう。
動かしてみる
出来上がったら Arduino IDE から Arduino UNO WiFi Rev.2 に書き込みます。
シリアルモニタで見ていくと、Wi-Fi がつながった後、設定が合っていれば Beebotte にもつながります。つながった瞬間に {"message":"Connected"}
というメッセージを送っています。
Node-RED で、Beebotte につながったこのような MQTT のフローで事前に立ち上げて待ち受けていると、
このように、Arduino UNO WiFi Rev.2 から先ほど発行されたデータが Beebotte の MQTT ブローカー経由で Node-RED でデータが確認することができました。