Re: note

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

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

f:id:hik0leaf:20190615175934j:plain

MICROCHIPのENC28J60を使ってArduinoUDP通信を行ってみます。

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以上の供給能力がある外部電源を用意してください。

https://www.microchip.com/wwwproducts/en/en022889

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

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

3. コード

W5500であれば標準ライブラリのEthernet.hが使用できますが、ENC28J60は対応していないようなので、今回は別ライブラリのEtherCardを使用します。Arduino Library Managerに対応しているので、Arduino IDEのライブラリマネージャからインストールすることができます。(「ethercard」で検索すると出てきます)

github.com

他にもENC28J60に対応しているライブラリとしてはUIPEthernetもあります。

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

#include <EtherCard.h>

const byte ip[] = { 10, 0, 1, 10 };
const byte gw[] = { 10, 0, 1, 1 };
const byte dns[] = { 10, 0, 1, 1 };
const byte mac[] = { 0x1A, 0x2B, 0x3C, 0x4D, 0x5E, 0x6F };
byte Ethernet::buffer[700];


void udpSerialPrint(uint16_t dest_port, uint8_t src_ip[IP_LEN], uint16_t src_port, const char *data, uint16_t len){
  Serial.print("dest_port: ");
  Serial.println(dest_port);
  
  Serial.print("src_port: ");
  Serial.println(src_port);
  
  Serial.print("src_ip: ");
  ether.printIp(src_ip);
  
  Serial.print("\ndata: ");
  Serial.println(data);

  ether.sendUdp(data, len, dest_port, src_ip, src_port);// send echo back
}


void setup () {
  Serial.begin(9600);
  Serial.println("starting...");
  
  if (ether.begin(sizeof Ethernet::buffer, mac, SS) == 0) {
    Serial.println( "Failed to access Ethernet controller");
  }
  
  ether.staticSetup(ip, gw, dns);
  ether.printIp("IP:  ", ether.myip);
  ether.printIp("GW:  ", ether.gwip);
  ether.printIp("DNS: ", ether.dnsip);

  ether.udpServerListenOnPort(&udpSerialPrint, 1337);
}


void loop () {
  ether.packetLoop(ether.packetReceive());
}

MACアドレスIPアドレスは環境に合わせて変更してください。 EtherCardの詳細なリファレンスも用意されています。

EtherCard: EtherCard

4. 実行

シリアルモニタでログを確認します。通信相手はNode.jsを使うと簡単に用意することができます。正常に動作していれば、ログに受信したメッセージと相手先に同じメッセージをエコーバックしていることが確認できます。

f:id:hik0leaf:20190615184136j:plain
シリアルモニタの動作ログ (例:カウントアップデータをエコーバック)

5. 参考リンク