Re: note

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

ENC28J60を使ってArduinoでMQTT通信する

f:id:hik0leaf:20190615210326j:plain

MICROCHIPのENC28J60を使ってArduinoでMQTT通信を行ってみます。

1. 準備

ENC28J60を入手します。aitendoやAmazonで1,000円程度で購入できます。入手に時間がかかってもよければAliexpressを使うと$2~$3で購入できます。

f:id:hik0leaf:20190615181042j:plain f:id:hik0leaf:20190615181059j:plain

ArduinoはUNO R3を使います。

2. 接続

ArduinoとはSPIで通信を行うため、ENC28J60を以下のように接続します。IOレベルは3.3Vですが5VトレラントでもあるのでArduinoへ直結することができます。その他の注意点としてはENC28J60の消費電流が大きいため3.3Vの供給をArduinoから行わずに外部から加えるようにしています。このあたりはWIZnetのW5500と同じですね。

f:id:hik0leaf:20190615181240j:plain
接続図

Arduino ENC28J60
D10 (SS) CS
D11 (MOSI) SI
D12 (MISO) SO
D13 (SCK) SCK
GND GND

ENC28J60のモジュールによってはピン配置が異なるため、実物の仕様やシルク等を確認して割り当てられたピンと適切に接続してください。今回購入したENC28J60のモジュールでは以下のようになっていました。

f:id:hik0leaf:20190615181903j:plain
ENC28J60モジュールのピン配置

また、ENC28J60のデータシートを見ると動作時の最大消費電流が180mAとあるので、少なくとも200mA以上の供給能力がある外部電源を用意してください。

ENC28J60 - Ethernet Controllers

f:id:hik0leaf:20190615181350j:plain
ENC28J60の消費電流 (データシートから抜粋)

(2019.06.15 追記)
ブレッドボードで接続する場合はワイヤーをなるべく短くしてください。ワイヤーが長いと通信が不安定になります。

3. ライブラリのインストール

以下の2つのライブラリを使用します。

github.com

github.com

UIPEthernetはENC28J60でEthernet通信するためのライブラリで、PubSubClientはMQTT通信するためのライブラリです。PubSubClientについてはENC28J60をサポートしていないようですが、動作確認することができたのでこのまま進めます。

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

f:id:hik0leaf:20190615212408j:plain f:id:hik0leaf:20190615212349j:plain

4. コード

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

#include <UIPEthernet.h>
#include <PubSubClient.h>

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte server[] = { 10, 0, 1, 9 };

EthernetClient ethClient;
void callback(char* topic, byte* palyload, unsigned int length);
PubSubClient client(server, 1883, callback, ethClient);

void setup() {
  Serial.begin(9600);
  Serial.println("starting...");
  
  Ethernet.begin(mac);
  Serial.print("IP Address: ");
  Serial.print(Ethernet.localIP());
  Serial.print("/");
  Serial.println(Ethernet.subnetMask());

  while (!client.connected()) {
    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 loop() {
  client.loop();
}

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

  Serial.println(msg);
}

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

Arduino Client for MQTT

MACアドレスやserverアドレスは環境に合わせて変更してください。 serverアドレスはMQTT Brokerのアドレスで、動作確認するためにはMQTT Brokerが必要になります。MQTT BrokerはRaspberry Pimosqittoをインストールして構築するのが一番簡単でおすすめです。

5. 実行

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

f:id:hik0leaf:20190615214540j:plain

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

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

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

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

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

6. まとめ

ENC28J60を使ってArduinoでMQTT通信できることが確認できました。しかしながら、PubSubClientがENC28J60のサポートを正式に謳っていないことや、スケッチを書き込んでみると分かりますがArduino UNOを使うとフラッシュメモリを70%以上消費してしまうため、使用にはやや不安が残ります。

これらの点に注意しながら使うか、別のイーサネットモジュール(W5500など)や別のライブラリの使用を検討するのも良いかと思います。

7. 参考リンク

ワンコインでIot入門 第二章