前回、myThingsのIDCFチャネルの環境で、ESP-WROOM-02をMQTT subscriberとして設定したところ、メッセージの受信ができなかったので、再挑戦です。
今回は、前回とは違うMQTTライブラリを利用します。
理由は不明ですが、myThingsでの動作実績のあるものにしました。下記ブログを参考にさせていただきました。
今回、使用した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互換)に渡して、ロボを動かします。
# 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