Re: note

技術的な知見やポエムなど役に立たない情報を書き連ねる場所

W5500を使ってESP32でEthernet MQTT通信する

f:id:hik0leaf:20190617230354j:plain

WIZnetのW5500を使ってESP32(Arduino core for the ESP32)でMQTT通信を行ってみます。

1. 準備

過去の記事を参考に3までを行います。

  • 1.準備
  • 2.接続
  • 3.ライブラリ修正

hikoleaf.hatenablog.jp

2. MQTTライブラリのインストール

MQTT通信するために以下のライブラリをインストールします。

github.com

ライブラリはArduino IDEのライブラリマネージャから名前で検索してインストールすることができます。

f:id:hik0leaf:20190615212349j:plain

PubSubClientについてはAPIドキュメントが用意されています。

Arduino Client for MQTT

3. コード

以下のコードをESP32に書き込みます。

#include <Ethernet.h>
#include <PubSubClient.h>


byte mac[] = { 0x70, 0x69, 0x69, 0x2D, 0x30, 0x31 };
byte server[] = { 10, 0, 1, 5 };

void callback(char* topic, byte* payload, unsigned int length) {
  payload[length] = '\0';
  String msg = String((char*) payload);
  Serial.println(msg);
}

EthernetClient ethClient;
PubSubClient client(server, 1883, callback, ethClient);

void reconnect() {
  while (!client.connected()) {
    Serial.println("Attempting MQTT connection...");
    
    if (client.connect("myClient")) {
      Serial.println("MQTT PubSub Ready");
      client.publish("output", "ready");
      client.subscribe("input");
      Serial.println("subscribe input");
    } else {
      Serial.println("MQTT PubSub failer");
      Serial.println("try again in 2 seconds");
      delay(2000);
    }
  }  
}


void setup() {
  Serial.begin(115200);
  Serial.println("starting...");
  
  Ethernet.init(33);// CS pin 33
  Ethernet.begin(mac);// use DHCP

  // Check for Ethernet hardware present
  if (Ethernet.hardwareStatus() == EthernetNoHardware) {
    Serial.println("Ethernet shield was not found.  Sorry, can't run without hardware. :(");
    while (true) {
      delay(1); // do nothing, no point running without Ethernet hardware
    }
  }
  if (Ethernet.linkStatus() == LinkOFF) {
    Serial.println("Ethernet cable is not connected.");
  }

  Serial.print("IP: ");
  Serial.println(Ethernet.localIP());
  
  delay(1500);
}


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

MACアドレスは環境に合わせて変更してください。IPアドレスの設定はDHCPを使っていますが、Ethernet.begin()の引数にIPアドレスgatewayを指定することで固定IPを設定することもできます。

固定IPで設定する際のdnsgateway・subnetはデフォルト値が設定されているため、MACアドレスIPアドレスだけで動作する場合がありますが、指定しないと動作しなかったり通信が不安定だったりするので面倒でも全て指定した方が良いでしょう。Ethernet.begin()の詳細は以下の公式リファレンスから確認できます。

Arduino - EthernetBegin

またserverアドレスはMQTT Brokerのアドレスで、動作確認するためにはMQTT Brokerが必要になります。MQTT BrokerはRaspberry Pimosqittoをインストールして構築するのが一番簡単でおすすめです。

4. 実行

MQTT Brokerが動作していることが確認できたら、ESP32に繋がっているシリアルモニタでログを確認します。正常に動作していれば以下のようになります。

f:id:hik0leaf:20190616110611j:plain

mosquittoをインストールすると、Brokerの他にPubSubクライアントもインストールされるのでPublish(Pub)用とSubscribe(Sub)用のターミナルを立ち上げて動作を確認してみます。

f:id:hik0leaf:20190615214945j:plain
Subscribe画面

トピックはoutputをSubscribeしておきます。ESP32が立ち上がるとreadyが送られてくるのを確認できます。見逃してしまったらESP32をリセットするともう一度送られてきます。

f:id:hik0leaf:20190615214907j:plain
Publish画面

inputトピックに対してメッセージ(payload)を送るとシリアルモニタで受信を確認することができます。

5. まとめ

ESP32でEthernetを使ったMQTT通信を行ってみました。ESP32にはWiFiが搭載されているため無線通信の方が気軽に試すことができますが、無線では得られない圧倒的な通信安定度がEthernetにはありますので用途によって使い分けられると良いかと思います。