LoginSignup
12
14

More than 5 years have passed since last update.

ESP-WROOM-02をBluemixにつなぎSubscribeする。

Last updated at Posted at 2016-05-08

はじめに

ESP-WROOM-02というWiFi付センサーハブは激安だ。通販や秋葉原の店頭で500円位で手に入る。使いやすいブレークアウトボードに搭載されたものでも1000円以内で手に入る。
以下の写真は、ブレークアウトボードに搭載されているタイプで、秋月電子で650円で売っている。安い!
このセンサーハブを使えば、激安センサーシステムを作成することが可能なはず。安く手軽にIoTが出来るとなればこれはブレーク間違いない。
そこで、WROOM-02をIBM Bluemixにつなげてセンサーデータの送信とコマンドの受信(PublishとSubscribe)をしてみようと思った。
センサーデータの送信(Publish)は、Check! IoT ができるようになるまで ~ ESP-WROOM-02 を IoT Foundation で Bluemix につなぐ!を参考にトラブルに見舞われながらも数時間で何とかなったが、コマンドの受信(Subscribe)ははまって成功まで数日かかった。
本投稿ではコマンドの受信(Subscribe)をできるまでのポイントを解説します。

2016050816580900.jpg

前提

本投稿ではすでにWROOM-02がシリアル通信できるようになっており、ArduinoIDEでWROOM-02にプログラムを焼け、Bluemixに接続しPublishができている事を想定している。なので、以下(または各種サイト)を参考にしてその前提を整えてください。

いきなり完成品

まずは完成したものを出してしまおう。どこがポイントかというのはそのあとで。

コード

サンプルのコードは以下の感じ。Bluemixからコマンドを受信(Subscribe)するとシリアルモニタに「callback invoked」と表示する。

サンプル.ino
/** 
 * This source code refer to the recipe of IBM developerWorks, https://developer.ibm.com/recipes/tutorials/connect-an-esp8266-with-the-arduino-sdk-to-the-ibm-iot-foundation/ .
 */ 
#include <ESP8266WiFi.h>
#include <PubSubClient.h>

//-------- Customise these values -----------
const char* ssid = "<SSID>";
const char* password = "<暗号化キー>";

#define ORG "<組織ID>"      // 組織ID
#define DEVICE_TYPE "<デバイス・タイプ>"  // デバイス・タイプ
#define DEVICE_ID "<デバイスID>"      // デバイスID
#define TOKEN "<認証トークン>"              // 認証トークン
//-------- Customise the above values --------

char server[] = ORG ".messaging.internetofthings.ibmcloud.com";
char topic[] = "iot-2/evt/status/fmt/json";
char authMethod[] = "use-token-auth";
char token[] = TOKEN;
char clientId[] = "d:" ORG ":" DEVICE_TYPE ":" DEVICE_ID;

WiFiClient wifiClient;
PubSubClient client(wifiClient);

void callback(char* topic, byte* payload, unsigned int length) {
 Serial.println("callback invoked");
}

void setup() {
 Serial.begin(115200);
 Serial.println();

 Serial.print("Connecting to ");
 Serial.print(ssid);
 WiFi.begin(ssid, password);

 while (WiFi.status() != WL_CONNECTED) {
 delay(500);
 Serial.print(".");
 } 
 Serial.println("");

 Serial.print("WiFi connected, IP address: ");
 Serial.println(WiFi.localIP());

 client.setServer(server, 1883);
 client.setCallback(callback);
}

int counter = 0;

void loop() {

 if (!!!client.connected()) {
 Serial.print("Reconnecting client to ");
 Serial.println(server);
 while (!!!client.connect(clientId, authMethod, token)) {
 Serial.print(".");
 delay(500);
 }
 if (client.subscribe("iot-2/cmd/cid/fmt/json")) {
 Serial.println("Subscribe ok");
 } else {
 Serial.println("Subscribe failed");
 }
 Serial.println();
 }

 String payload = "{\"d\":{\"myName\":\"";
 payload += DEVICE_TYPE;
 payload += ".";
 payload += DEVICE_ID;
 payload += "\",\"count\":";
 payload += counter;
 payload += "}}";

 Serial.print("Sending payload: ");
 Serial.println(payload);

 if (client.publish(topic, (char*) payload.c_str())) {
 Serial.println("Publish ok");
 } else {
 Serial.println("Publish failed");
 }
 client.loop();
 if (1000 < counter) {
  counter = 0;
 }
 else {
  ++counter;
 }
 delay(10000);
}

Bluemix側の設定

Bluemix側のNode-REDのフローはこんな感じ。

IoTBluemix20160508_6_forESP8266.png

Functionの「test command」の中身の例。

IoTBluemix20160508_7_forESP8266.png

「IBM IoT App Out」の中身の例。

IoTBluemix20160508_4_forESP8266.png

ポイントの解説

コード側

client.loop()の実行を忘れてはならない。

loop関数の中で、client.loop();を実行するようにする。
私はこれがわからなくて2日間悩んだ。なので一番のポイントとして挙げておこう。
client.loop();は、Bluemixからの受信を処理する命令らしい。

抜粋.ino
void loop() {
<......>

 client.loop();

<......>
}

受信時に実行される関数の用意

Subscribeを受信したときの処理を関数として書いておく。

抜粋.ino
void callback(char* topic, byte* payload, unsigned int length) {
 Serial.println("callback invoked");
}

受信時に実行される関数の登録

Subscribeを受信したときに実行する関数の名前をclient.setCallback(callback);のように設定する。

抜粋.ino
void setup() {
 <......>
 client.setServer(server, 1883);
 client.setCallback(callback);
}

Subscribe開始の命令の実行

接続処理の直後で、client.subscribe("iot-2/cmd/cid/fmt/json")のようにsubscribeを行う。
Bluemixから受信する場合、iot-2/cmd/<任意の文字列>/fmt/jsonという形式のトピックを指定する。
任意の文字列は、Node-REDの「IBM IoT App Out」の中身の Command Typeと合わせる必要がある。

抜粋.ino
 <......>
 while (!!!client.connect(clientId, authMethod, token)) {
 Serial.print(".");
 delay(500);
 }
//接続成功後
 if (client.subscribe("iot-2/cmd/cid/fmt/json")) {
 Serial.println("Subscribe ok");
 } else {
 Serial.println("Subscribe failed");
 }
 Serial.println();
 }

Bluemix側

DeviceTypeの名前に気を付ける

Node-REDの「IBM IoT App Out」の中身のDevice Typeと、登録機器の「デバイス・タイプ」を合わせる。Bluemix側のポイントはこれだけ。

IoTBluemix20160508_9_forESP8266.png

IoTBluemix20160508_10_forESP8266.png

実行例

正しくできていれば、シリアルモニターに「callback invoked」と表示されるはず。
IoTBluemix20160508_5_forESP8266.png

他に参考にした投稿

以下も参考にするとよいと思う。Bluemix側の設定はここを参考にした。

12
14
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
14