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


[前回](http://qiita.com/snumano/items/0e96bb3b1ed9ffc90eb5)、myThingsのIDCFチャネルの環境で、ESP-WROOM-02をMQTT subscriberとして設定したところ、メッセージの受信ができなかったので、再挑戦です。

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

[ESP8266でIDCF Cloudにつなぐ](http://qiita.com/mayfair/items/bb09ad04942104be5578)


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

JsonのParseには、[ArduinoJsonParser](https://github.com/markert/ArduinoJsonParser)を使用しました。これも、ZIPを追加します。
(Arduibo IDEに登録されている[ArduinoJson](https://github.com/bblanchon/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でメッセージを送受信する](http://qiita.com/masato/items/90ca2ae56feaea37eaa8)
[Arduino blink LED with MQTT](http://docs.gadgetkeeper.com/plugins/servlet/mobile#content/view/11699658)