W5500を使ってArduinoでMQTT通信する
WIZnetのW5500を使ってArduinoでMQTT通信を行ってみます。
1. 準備
Aliexpress等でW5500を購入します。
1 個 USR ES1 W5500 チップ新 spi 蘭イーサネット変換 TCPIP Mod - Aliexpress.com | Alibaba グループ上の 電子部品&用品 からの 集積回路 の中
ArduinoはUNO R3を使います。
2. 接続
ArduinoとはSPIで通信を行うため、W5500を以下のように接続します。IOレベルは3.3Vですが5VトレラントでもあるのでArduinoへ直結することができます。その他の注意点としてはW5500の消費電流が大きいため3.3Vの供給をArduinoから行わずに外部から加えるようにしています。
Arduino | W5500 |
---|---|
D10 (SS) | CS |
D11 (MOSI) | MOSI |
D12 (MISO) | MISO |
D13 (SCK) | SCLK |
GND | GND |
データシートを見ると100M Trasmittingのときに132mA消費すると書いてあるので、外部電源は200mA以上供給できるものを用意すると良いでしょう。
products:w5500:datasheet [Document Wiki]
【注意】ブレッドボードで接続する場合はワイヤーをなるべく短くしてください。ワイヤーが長いと通信が不安定になります。
3. ライブラリのインストール
W5500を使用する場合はENC28J60とは異なり、標準のEthernetライブラリでモジュールを制御することができるため、MQTT部分を処理するPubSubClientのみをインストールします。
ライブラリはArduino IDEのライブラリマネージャから名前で検索してインストールすることができます。
4. コード
以下のコードをArduinoに書き込みます。
#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(9600); Serial.println("starting..."); Ethernet.init(10);// CS pin 10 Ethernet.begin(mac); // 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(); }
PubSubClientにはAPIドキュメントも用意されています。
MACアドレスやserverアドレスは環境に合わせて変更してください。 serverアドレスはMQTT Brokerのアドレスで、動作確認するためにはMQTT Brokerが必要になります。MQTT BrokerはRaspberry Piにmosqittoをインストールして構築するのが一番簡単でおすすめです。
5. 実行
MQTT Brokerが動作していることが確認できたら、Arduinoに繋がっているシリアルモニタでログを確認します。正常に動作していれば以下のようになります。
mosquittoをインストールすると、Brokerの他にPubSubクライアントもインストールされるのでPublish(Pub)用とSubscribe(Sub)用のターミナルを立ち上げて動作を確認してみます。
トピックはoutputをSubscribeしておきます。Arduinoが立ち上がるとreadyが送られてくるのを確認できます。見逃してしまったらArduinoをリセットするともう一度送られてきます。
inputトピックに対してメッセージ(payload)を送るとArduinoのシリアルモニタで受信を確認することができます。
6. まとめ
W5500やENC28J60を使うことで非力なマイコンでもTCPやUDP通信できることをこのブログで紹介してきました。最近ではWi-Fiを搭載したESP8266やESP32の登場により、単体で気軽にIoT機器を作ることができるようになりましたが、人が多い場所や電波干渉が顕著な環境では有線による安定動作が望まれる場面もあるかと思います。
マイコンで通信を行うときはコストや用途、使用環境などを考慮して有線や無線、プロトコルを選択できるようになると良いでしょう。