2017年3月9日木曜日

ESP-WROOM-02 で MQTT にメッセージを Publish してみた

概要

前回 WROOM を Arduino 化して実際に Wifi に接続するところまで試しました
今回のその応用としてネットワークにつながった WROOM からインターネット上の MQTT のブローカにメッセージを Publish してみました

環境

事前作業

前回の作業+今回は MQTT のブローカも必要になります
無料で使える MQTT as a Service は結構あります
今回は Sango を使ってみました (Sango を使う場合は Github のアカウントが必要になります)
ブローカに接続するための認証情報も Sango ベースの設定になっているので、そのあたりは適宜変更してください

Arduino Client for MQTT のインストール

まず Arduino IDE に MQTT ライブラリを追加します
https://github.com/knolleary/pubsubclient/releases/latest から最新の zip ファイルをダウンロードしましょう
wroom_try_mqtt_download_zip.png

本記事執筆時点でのバージョンは 2.6 でした
Arduino IDE にライブラリを追加するのに zip を解凍する必要はありません

ダウンロードが完了したら Arduino IDE を起動して

スケッチ -> ライブラリをインクルード -> .ZIP形式のライブラリをインクルード

と選択してダウンロードした zip ファイルを選択してください
特に IDE にエラーが出なければインクルード完了です

ライブラリをインクルードの選択肢に「PubSubClient」が追加されており、ファイル -> スケッチの例にも「PubSubClient」が追加されていれば OK です

スケッチの作成

今回はスケッチの例にある「mqtt_esp8266」をベースにスケッチを作成しました
スケッチの全体は以下の通りです

#include <ESP8266WiFi.h>
#include <PubSubClient.h>

const char* ssid = "ssid";
const char* password = "ssid-password";
const char* mqtt_server = "lite.mqtt.shiguredo.jp";
const int mqtt_port = 1883;
const char* mqtt_pub_topic = "yourGithubAccount@github/esp8266";
const char* mqtt_sub_topic = "yourGithubAccount@github/esp8266_sub";
const char* mqtt_username = "yourGithubAccount@github";
const char* mqtt_password = "yourBrokerPassword";

WiFiClient espClient;
PubSubClient client(espClient);
long lastMsg = 0;
char msg[50];
int value = 0;

void setup_wifi() {
  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

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

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

void callback(char* topic, byte* payload, unsigned int length) {
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
  Serial.println();

  // Switch on the LED if an 1 was received as first character
  if ((char)payload[0] == '1') {
    digitalWrite(BUILTIN_LED, LOW);   // Turn the LED on (Note that LOW is the voltage level
    // but actually the LED is on; this is because
    // it is acive low on the ESP-01)
  } else {
    digitalWrite(BUILTIN_LED, HIGH);  // Turn the LED off by making the voltage HIGH
  }
}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    if (client.connect("ESP8266Client", mqtt_username, mqtt_password)) {
      Serial.println("connected");
      // Once connected, publish an announcement...
      client.publish(mqtt_pub_topic, "hello world");
      // ... and resubscribe
      client.subscribe(mqtt_sub_topic);
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

void setup() {
  pinMode(BUILTIN_LED, OUTPUT);     // Initialize the BUILTIN_LED pin as an output
  Serial.begin(115200);
  setup_wifi();
  client.setServer(mqtt_server, mqtt_port);
  client.setCallback(callback);
}

void loop() {
  if (!client.connected()) {
    reconnect();
  }
  client.loop();

  long now = millis();
  if (now - lastMsg > 10000) {
    lastMsg = now;
    ++value;
    snprintf (msg, 75, "hello world #%ld", value);
    Serial.print("Publish message: ");
    Serial.println(msg);
    client.publish(mqtt_pub_topic, msg);
  }
}

ポイント説明

スケッチ冒頭にある Wifi とブローカの情報を各自の環境に合わせて設定してください

setup() で Wifi の接続と MQTT への接続の準備を行います
Wifi の接続に成功すると取得できた IP アドレスを表示します

loop() ではまず MQTT への接続を行います
接続状態になっていれば接続処理はスルーします
reconnect メソッドで接続処理を行っており、設定したブローカ情報がおかしい場合は再接続をし続けるので、再度スケッチの設定を見なおしてください

reconnect 内で接続が成功するとまず pub/sub を 1 回行います
Subscribe は callback メソッドを設定しており、メッセージが到着すると callback メソッドが呼ばれます

loop() 内で 10 秒おきに Publish を続けます
メッセージは固定で「hello world #N」を送信します
N は送信したメッセージのカウントになので、送信ごとにインクリメントされます

動作確認

スケッチをコンパイルし問題なければ書き込みを開始しましょう
開始する前にシリアルモニタを開いておきましょう
改行を CRおよびLF に設定し、ボーレートを 115200 にします

書き込みが成功すると Wifi に接続を試みます
Wifi への接続が成功すると次に MQTT への接続を試みます
MQTT への接続が成功するとメッセージの Publish が 10 秒おきに行われます
wroom_try_mqtt_debug_serial.png

シリアルモニタはこんな感じで表示され続けます

最後に

紹介は以上です
WROOM を Arduino 化したおかげで Arduino 用のライブラリも WROOM で簡単に使えるようになったで非常に簡単に MQTT も使えるようになりました

一応試してみた感じだと、長時間起動しっぱなしでも特に問題なく動作しており、電源も入れなおすと自動でスケッチが起動して MQTT への Publish も再開されました

参考サイト

0 件のコメント:

コメントを投稿