myThingsを使ってESP-WROOM-02経由でロボを動かす(成功編)

  • 4
    Like
  • 0
    Comment
More than 1 year has passed since last update.

前回、myThingsのIDCFチャネルの環境で、ESP-WROOM-02をMQTT subscriberとして設定したところ、メッセージの受信ができなかったので、再挑戦です。

今回は、前回とは違うMQTTライブラリを利用します。
理由は不明ですが、myThingsでの動作実績のあるものにしました。下記ブログを参考にさせていただきました。

ESP8266でIDCF Cloudにつなぐ

今回、使用したMQTTライブラリはImroy/pubsubclientです。ZIPをDownloadして、Arduino IDEの[スケッチ]-[Include Library]-[Add ZIP Library]にて追加します。
(ちなみに、前回まで使用していたのはknolleary/pubsubclientです。こちらも、別のMQTT環境だと使えています)

JsonのParseには、ArduinoJsonParserを使用しました。これも、ZIPを追加します。
(Arduibo IDEに登録されているArduinoJsonを利用したかったのですが、うまく動作できなかったので、あきらめました)

ESP-WROOM-02のスケッチは下記の通りです。
MQTTメッセージを、ESP-WROOM-02で受けて、シリアル(UART)でFreaduino Uno(Arduino互換)に渡して、ロボを動かします。

robo_mythings.ino
#include <MQTT.h>
#include <PubSubClient.h>
#include <ESP8266WiFi.h>
#include <JsonArray.h>
#include <JsonHashTable.h>
#include <JsonObjectBase.h>
#include <JsonParser.h>

JsonParser<32> parser;
#define BUFFER_SIZE 100

// MQTTのクライアントID(ユニークにするためにスケッチをコンパイルした日付と時刻を使用)
const char *mqtt_client_id = "arduinoClient" __DATE__ __TIME__;

// Wi-FiアクセスポイントのSSIDとパスワード
const char *ssid =  "<ssid>";
const char *pass =  "<password>";

// IDCF Cloudに関する設定
const char* action_1_uuid = "<uuid>";
const char* action_1_token = "<token>";
IPAddress server(210, 140, *, *); //  使用するIPアドレス

void callback(const MQTT::Publish& pub) {
//  Serial.print(pub.topic());
//  Serial.print(" => ");
  if (pub.has_stream()) {
    // ペイロードのサイズが大きい場合にはローカルに用意したバッファに分割して読み取り
    // 読み取った単位ごとにシリアルにプリント
    uint8_t buf[BUFFER_SIZE];
    int read;
    while (read = pub.payload_stream()->read(buf, BUFFER_SIZE)) {
      Serial.write(buf, read);
    }
    pub.payload_stream()->stop();
    Serial.println();
  } else {
    // ペイロードのサイズが小さい場合にはそのままシリアルにプリント
    char buffer[pub.payload_string().length()+1];
    pub.payload_string().toCharArray(buffer,pub.payload_string().length()+1);
    JsonHashTable hashTable = parser.parseHashTable(buffer);
    parseCheck(hashTable);

    char* data = hashTable.getString("data");
    JsonHashTable hashTable_data = parser.parseHashTable(data);
    parseCheck(hashTable_data);

    char* payload = hashTable_data.getString("payload");
    Serial.println(payload);  
  }
}

void parseCheck(JsonHashTable hashTable){
  if (!hashTable.success()){
    Serial.println("JsonParser.parseHashTable() failed");
    return;
  }
}

WiFiClient wclient;
PubSubClient client(wclient, server);

void setup() {
  Serial.begin(115200);
  delay(10);
  Serial.println();
  Serial.println();
}

void loop() {
  if (WiFi.status() != WL_CONNECTED) {
    Serial.print("Connecting to ");
    Serial.print(ssid);
    Serial.println("...");
    WiFi.begin(ssid, pass);

    if (WiFi.waitForConnectResult() != WL_CONNECTED) {
      return;
    }
    Serial.println("WiFi connected");
  }

  if (!client.connected()) {
    // アクション1のUUIDとトークンをユーザ名およびパスワードとしてサーバに接続
    MQTT::Connect mqttConnect(mqtt_client_id);
    mqttConnect.set_auth(action_1_uuid, action_1_token);

    if (client.connect(mqttConnect)) {
      client.set_callback(callback);
      client.subscribe(action_1_uuid);
      Serial.println("completed");
    }
  }

  if (client.connected()) {
    client.loop();
  }
}

参考

Meshbluを使いMQTTとHTTPをブリッジしてRaspberry Piでメッセージを送受信する
Arduino blink LED with MQTT