DevRel

電子工作界隈で話題のWi-Fiモジュール「ESP8266」でMQTTを使う方法

電子工作界隈で話題のWi-Fiモジュール「ESP8266」でMQTTを使う方法

はじめまして、Technical Rockstarsの平間と申します。

最近、技適を取得した「ESP8266」という格安Wi-Fiモジュールが、電子工作界隈(IoT界隈?)で話題になっています。このモジュールのおかげで安価でIoTが始められるようになり、より国内IoTが加速すると期待できます。

ESP8266でHTTPを使う(IFTTTに投げて通知等)記事は既にちらほらあるので、今回はこちらのライブラリを使ってESP8266でMQTTを使う(リアルタイム制御等)方法を説明します。

※先日、MilkcocoaでArduinoやESP8266用のSDKを公開しました。こちらの記事に具体的な使用方法が書いてあるので、是非こちらもご覧下さい。

Milkcocoaとは
Milkcocoaとは、IoTデバイス・スマートフォン・PC間で簡単にリアルタイムなデータのやり取りができるようになるプラットフォームです。
Milkcocoa公式サイト

▼目次

  • 環境
  • MQTTブローカーを立てる
  • Arduino IDE環境の準備
  • Adafruit MQTT Libraryのインストール
  • 動作確認
  • ざっくりコードの説明
  • 照度センサーのデータを送受信してみた

環境

  • ESP8266
  • 作業用パソコン
  • パソコンとESP8266間でシリアル通信ができるまでに必要な機器

パソコンとESP8266でシリアル通信ができるようになっていることが前提です。こちらの方法等は、下記の記事を参照下さい。

参考:技適済みWi-Fiモジュール「ESP8266」で始めるIoT入門(ブレイクアウトボード実装編)

※なお、私は@wamisnetさんが作った、「USBでPCに差すだけで即シリアル通信から始められるESP8266互換ボード」の試作品を頂いて、使いました(@wamisnetさん、ありがとうございます!)。このボードは、近日発売予定とのことです。

wami-board1.jpg

MQTTブローカーを立てる

まずMQTTを利用するために、 クライアント間の仲介役サーバーである「MQTTブローカー」を自前で立てましょう(既に使っているMQTTブローカーのサービスがあればそちらを使っても構いません)。
今回は、おそらく最も有名なMQTTライブラリである「Mosquitto」を使います。

mosquitto.png

Mosquittoのインストール

私のパソコンがMacなので、HomebrewでMosquittoをインストールする方法をご紹介します。(参考記事
※Windowsやその他OSの場合はこちら

Homebrewがパソコンにインストールされていない方は、まずHomebrewをインストールします。

$ ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

続いてMosquittoのインストール。

$ brew install mosquitto

これでインストールは完了です。

Mosquittoの実行

ブローカーを実行するには、 mosquitto というコマンドを叩けば起動できます。
いきなりうまくいく人もいれば、うまくいかない人もいるかと思います。しかし、大抵は以下の問題を解決すれば大丈夫です。

1. brew link ~ ができない

作業ユーザーが /usr/local/ に書き込み権限がないと、 brew install mosquitto の際のメッセージに下記のような「 brew link ができないよ」といったエラーが出ると思います。

...
Error: The `brew link` step did not complete successfully
The formula built, but is not symlinked into /usr/local
Could not symlink share/man/man3/libmosquitto.3
/usr/local/share/man/man3 is not writable.
You can try again using:
  brew link mosquitto
...

そのため、下記のコマンドのように権限を与えた後に手動で brew link mosquitto をしてあげましょう。

$ sudo chown -R $(whoami) /usr/local
$ brew link mosquitto

2. brew link しても command not found になる

brew link しても command not found であれば、 /etc/paths//usr/local/sbin がない可能性が高いです。
mosquitto/usr/local/bin ではなく /usr/local/sbin に入っているので、 /etc/paths//usr/local/sbin がないと command not found になります。
解決方法は簡単で、 /etc/paths//usr/local/sbin を追加すれば大丈夫です。追加したら念のためターミナルの再起動もしてください。

$ sudo vim /etc/paths
...
/usr/local/sbin ←これを追加
...

これで、 mosquitto というコマンドを打つだけで、下記のようにブローカーが立ち上がるかと思います。

$ mosquitto
1445063239: mosquitto version 1.4.2 (build date 2015-05-08 13:59:14-0700) starting
1445063239: Using default config.
1445063239: Opening ipv4 listen socket on port 1883.
1445063239: Opening ipv6 listen socket on port 1883.

port 1883 と書いてあるように、デバイス(ESP8266)からは、作業用PCと同じネットワーク内にいる状態で (作業用PCのIP):1883 でブローカーにアクセスできます。

Arduino IDE環境の準備

ブローカーを立てられるようになったら、Arduino IDEでプログラミングを書いていきましょう。まずは環境を整えます。

Arduino IDEのインストール

Arduino公式サイトのダウンロードページから、Arduino IDEをダウンロードします。バージョンは、1.64以降のものをダウンロードしてください。

arduino-ide.png

ダウンロードが終わったら、インストーラーを立ち上げてインストールして下さい。

Arduino IDEでESP8266を使えるようにする

Arduino IDEを立ち上げて、以下の手順でArduino IDEでESP8266を使えるようにしましょう。Arduino IDEの「Preferences」を開いて、「Additional Board Manager URLs」フィールドに http://arduino.esp8266.com/stable/package_esp8266com_index.json を貼付けて、OKで保存します。

ide-preference.png

保存したら「ツール」 > 「ボード」 > 「Boards Manager…」から、「esp8266 platform」をインストールします。

ide-board-manager.png

インストール後、「ツール」 > 「ボード」から「Generic ESP8266 Module」を選びましょう。

ide-generic-board.png
※参考記事:Arduino IDE+ESP-WROOM-02でLチカ

これで、Arduino IDEからESP8266のプログラムを開発できるようになりました。

Adafruit MQTT Libraryのインストール

今回、ESP8266上でMQTTを使うために、Adafruit MQTT Libraryを使用します。

Adafruit MQTT Libraryのインストール方法

ライブラリのインストールはArduino IDE上からできます。
「スケッチ」 > 「Include Library」 > 「Manage Libraries…」をクリックして、検索窓(Filter your search…)にて Adafruit MQTT と打つと「Adafruit MQTT Library」が出てくるので、最新版をインストールしましょう(たまに出てこないときがありますが、Manage Librariesを開き直せば出てきます)。

ide-manage-library.png

「スケッチ」 > 「Include Library」の中に「Adafruit MQTT Library」が追加されていれば、インストール成功です。

ide-library-installed.png

動作確認

ライブラリのインストールが終わったら、早速動作確認してみましょう。
下記に公開しているコードをコピーして丸々貼付けます。

参考:esp8266-mqtt-quicktest/mqtt_esp8266_test.ino at master · kiyopikko/esp8266-mqtt-quicktest

貼付けたら、必要な情報を書き換えていきます。
下記を参照に、作業用PCが接続しているアクセスポイントのSSIDとパスワードを入力します。

#define WLAN_SSID       "...your_SSID..."
#define WLAN_PASS       "...your_password..."

次に、ブローカーのホスト、Username、Passwordを入力します(MQTTブローカーサービスを使っている場合は、サービスで指定されているものをそのまま使用して下さい)。

#define YOUR_SERVER      "...your_mqtt_broker_host..."
#define YOUR_SERVERPORT  1883
#define YOUR_USERNAME    "...your username..."
#define YOUR_PASSWORD    "...your password..."

Mosquittoで立てたブローカーのホストは、作業用PCで ifconfig コマンドを使って調べます。

$ ifconfig
...
en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST>...
    ...
    inet 192.168.0.4 ←これ netmask 0xffffff00 broadcast 192.168.0.255
    ...

Username・Passwordは、Mosquittoで立ち上げた場合は下記のように任意の文字列で大丈夫です。

#define YOUR_SERVER      "192.168.0.4"
#define YOUR_SERVERPORT  1883
#define YOUR_USERNAME    "test"
#define YOUR_PASSWORD    "test"

これらを書き換えて、 mosquitto コマンドでブローカーを立ち上げて、「マイコンボードに書き込む」を押して書き込みます。書き込みが終わったらシリアルモニタを開きます。
うまくいけば、下記の画像のように Got: 1 というのが1秒ごとに表示されるかと思います。

ざっくりコードの説明

動作確認ができたので、簡潔にコードの説明をします。
下記は、トピックからpublish用のオブジェクトとsubscribe用のオブジェクトを作成しています。

// Setup a pubulisher & subscriber.
const char TEST_TOPIC[] PROGMEM = "test";
Adafruit_MQTT_Publish testPublisher = Adafruit_MQTT_Publish(&mqtt, TEST_TOPIC);
Adafruit_MQTT_Subscribe testSubscriber = Adafruit_MQTT_Subscribe(&mqtt, TEST_TOPIC);

setup() の中で、subscribeします。

// Setup MQTT subscription.
mqtt.subscribe(&testSubscriber);

以下が、購読中のトピックにデータがきたときに実行する処理です。1回の loop() の中で、publishされた回数だけwhileの中身が(リアルタイムに)実行されるようになっているようです。来たデータは testSubscriber.lastread で取得します。

// this is our 'wait for incoming subscription packets' busy subloop
Adafruit_MQTT_Subscribe *subscription;
while ((subscription = mqtt.readSubscription(1000))) {
 if (subscription == &testSubscriber) {
   Serial.print(F("Got: "));
   Serial.println((char *)testSubscriber.lastread);
 }
}

publishは、上で作成したオブジェクトから、そのまま publish(payload) でできます。

testPublisher.publish(1);

コードの説明は以上です。これらのコードを自分用にカスタマイズしていけば良いかと思います。

照度センサーのデータを送受信してみた

試しに、下記の記事を参考に照度センサーのデータを送受信してみました。

参照:ちょと裏技っぽいけど、ESP8266 でAD変換やる方法

簡単ではありますが、ありものを使って下記のような回路にしました。
抵抗がこのように(2:1)なってるのは、TOUTが0V〜1Vまでしか測れないからです。GND・3.3V・TOUTはそれぞれESP8266の該当する場所につなげて下さい。

wami-board2-sketch.jpg

この回路で、下記のプログラムを走らせると「何もしてない状態で900〜1000くらい」「手で光を遮ると600〜700くらい」の値が見られました。

参照:esp8266-mqtt-quicktest/mqtt_esp8266_light.ino at master · kiyopikko/esp8266-mqtt-quicktest

おわりに

ESP8266でMQTTを利用する方法を説明しました。
MQTTを使うと、HTTPでは実現できないようなリアルタイムな処理や柔軟なメッセージングが可能になり、IoT開発の幅がさらに広がります。
冒頭でも紹介しましたが、先日、MilkcocoaでもArduinoやESP8266用のSDKを公開しました。下記の記事で使用方法を書いているので、是非こちらもご覧下さい。

参照:ESP8266やArduinoでMilkcocoaを使う方法(Milkcocoa Arduino SDK)

それでは、また!

この記事を書いた人