有線LANを使ってArduinoからパソコンにUDPでデータを送る。

#目次
・はじめに
・結果
・準備
・スケッチ例を使ったUDPによる送受信
・UDPによる連続送信
#はじめに
前回の記事に引き続きPCとArduino間で通信する。
https://qiita.com/get_itchy_feet/items/36a8f9fa5983fb11ac6a
今度はUDPを使用してみた。いろいろ便利が良いらしい。
「UDPSendReceiveString」を参考にしてトライする。データを送るだけのプログラムにも改造してみた。
#結果
　UDPでのデータ送信に成功した。
　結果は以下のツイート
<blockquote class="twitter-tweet" data-lang="ja"><p lang="ja" dir="ltr">有線LANでArduinoからPCにデータを送ってみる。<br>TCPに続きUDPでもデータの送付に成功。 <a href="https://t.co/E61lnZoVJu">pic.twitter.com/E61lnZoVJu</a></p>&mdash; いっちー (@get_itchy_feet) <a href="https://twitter.com/get_itchy_feet/status/1119275357553561601?ref_src=twsrc%5Etfw">2019年4月19日</a></blockquote>
<script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>
#準備
　必要なもの　①PC　②ArduinoUNO　③LANケーブル　④EthernetShield　⑤USBケーブル（書込み用）　⑥MACアドレス　⑦udp/ipテストツール
<img width=40% src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184089/7bf8d711-d766-94e3-7067-c29b8b441dba.png>
　③・・・PCとArduinoは直接ケーブルでつなげている。
　④・・・秋月電子で購入。DFROBOTのEthernet Shield V2.2。チップはW5100が搭載されている。
http://akizukidenshi.com/catalog/g/gM-13165/
　⑥・・・④にはMACアドレスがついていない。別機器（使っていないAmazonEcho）から拝借
　⑦・・・パソコン側でUDPの送受信を試すためのアプリをインストール。以下のHPからお借りした。
http://nonsoft.la.coocan.jp/Download/UdpTool/index.html
#UDPによる送受信
　Arduinoを起動し、「ファイル」→「スケッチ例」→「Ethernet」からUDPSendReceiveStringを開く。
　MACアドレスを書き換える。アドレスはさすがに公開できないので？を入れてある。下記の「0x??,0x??,0x??,0x??,0x??,0x??」の?に使用するアドレスの数値を記入。
　IPアドレスを書き換える。「IPAddress ip(192,168,2,101);」としている。
　改造した以下のプログラムをArduinoに書き込む。

```arduino:UDPSendReceiveString.ino
/*
 UDPSendReceiveString:
 This sketch receives UDP message strings, prints them to the serial port
 and sends an "acknowledge" string back to the sender

 A Processing sketch is included at the end of file that can be used to send
 and received messages for testing with a computer.

 created 21 Aug 2010
 by Michael Margolis

 This code is in the public domain.
 */


#include <Ethernet.h>
#include <EthernetUdp.h>

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = {
  0x??,0x??,0x??,0x??,0x??,0x??
};
IPAddress ip(192,168,2,101);

unsigned int localPort = 8888;      // local port to listen on

// buffers for receiving and sending data
char packetBuffer[UDP_TX_PACKET_MAX_SIZE];  // buffer to hold incoming packet,
char ReplyBuffer[] = "acknowledged";        // a string to send back

// An EthernetUDP instance to let us send and receive packets over UDP
EthernetUDP Udp;

void setup() {
  // You can use Ethernet.init(pin) to configure the CS pin
  //Ethernet.init(10);  // Most Arduino shields
  //Ethernet.init(5);   // MKR ETH shield
  //Ethernet.init(0);   // Teensy 2.0
  //Ethernet.init(20);  // Teensy++ 2.0
  //Ethernet.init(15);  // ESP8266 with Adafruit Featherwing Ethernet
  //Ethernet.init(33);  // ESP32 with Adafruit Featherwing Ethernet

  // start the Ethernet
  Ethernet.begin(mac, ip);

  // Open serial communications and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  // 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.");
  }

  // start UDP
  Udp.begin(localPort);
}

void loop() {
  // if there's data available, read a packet
  int packetSize = Udp.parsePacket();
  if (packetSize) {
    Serial.print("Received packet of size ");
    Serial.println(packetSize);
    Serial.print("From ");
    IPAddress remote = Udp.remoteIP();
    for (int i=0; i < 4; i++) {
      Serial.print(remote[i], DEC);
      if (i < 3) {
        Serial.print(".");
      }
    }
    Serial.print(", port ");
    Serial.println(Udp.remotePort());

    // read the packet into packetBufffer
    Udp.read(packetBuffer, UDP_TX_PACKET_MAX_SIZE);
    Serial.println("Contents:");
    Serial.println(packetBuffer);

    // send a reply to the IP address and port that sent us the packet we received
    Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
    Udp.write(ReplyBuffer);
    Udp.endPacket();
  }
  delay(10);
}


/*
  Processing sketch to run with this example
 =====================================================

 // Processing UDP example to send and receive string data from Arduino
 // press any key to send the "Hello Arduino" message


 import hypermedia.net.*;

 UDP udp;  // define the UDP object


 void setup() {
 udp = new UDP( this, 6000 );  // create a new datagram connection on port 6000
 //udp.log( true ); 		// <-- printout the connection activity
 udp.listen( true );           // and wait for incoming message
 }

 void draw()
 {
 }

 void keyPressed() {
 String ip       = "192.168.1.177";	// the remote IP address
 int port        = 8888;		// the destination port

 udp.send("Hello World", ip, port );   // the message to send

 }

 void receive( byte[] data ) { 			// <-- default handler
 //void receive( byte[] data, String ip, int port ) {	// <-- extended handler

 for(int i=0; i < data.length; i++)
 print(char(data[i]));
 println();
 }
 */
```
　次にudp/ipテストツールを立ち上げる。ダウンロードしたファイルを解凍し、exeファイルをダブルクリック。
　送信先ポート番号に「8888」、送信先IPアドレスに「192.168.2.101」と記入し、接続ボタンをクリック。
　送信するテキストに文字を記入し、TEXT送信ボタンをクリックすると送受信に成功、以下のように出てきた。
<img width=60% src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184089/04d70076-11ee-101c-2856-ef27f4a13a14.png>
#UDPによる連続送信
　次にArduino側から連続してデータを送る。
　ちなみにパソコン側のIPアドレスは「192.168.2.100」にしてある。以下のように設定した。。PC左下のWindowsマークを右クリックし、「ネットワークの状態」を開く。下の方の「ネットワークと共有センター」を開き、「イーサネット」をクリック、「イーサネットの状態」が出てきたら、「プロパティ」をクリックし、「イーサネット　プロトコル　バージョン4」を選び「プロパティ」を開く。
（ちなみにWindow10です。）![無題.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184089/b20145e6-40c3-1267-7075-50ffc47e7e26.png)
　ここでPC側の設定ができるので、「次のIPアドレスを使う」にチェックを入れ、IPアドレスを「192.168.2.100」にした。
　デフォルトゲートウェイ・DNSサーバーには適当に「192.168.2.1」とし、サブネットマスクは勝手に出てきた。OKを押し設定を変更。
　つぎに以下のようなプログラムをArduinoに書き込んだ。PC側のIPアドレスは設定した通り「192.168.2.100」ポート番号ははudp/ipテストツールのLOCALポートに書き込んだ番号（ここでは「8889」）とした。

```arduino:UDPTest.ino
#include <Ethernet.h>
#include <EthernetUdp.h>

byte mac[] = {
  0x00,0x71,0x47,0xB7,0x5A,0x3A
};
IPAddress ip(192,168,2,101);
unsigned int localPort = 8888;

IPAddress remote(192,168,2,100);
int pClocalPort = 8889;

int i = 97;

EthernetUDP Udp;

void setup() {
  Ethernet.begin(mac, ip);

  if (Ethernet.hardwareStatus() == EthernetNoHardware) {
    while (true) {
      delay(1);
    }
  }
  if (Ethernet.linkStatus() == LinkOFF) {
  }
  Udp.begin(localPort);
}

void loop() {
  Udp.beginPacket(remote,pClocalPort);
  if(i < 116) i = i + 1;
  else i = 97;
  Udp.write(i);
  Udp.endPacket();
  delay(500);
}
```
udp/ipテストツールを立ち上げ、LOCALポートに「8889」と記入、接続するとa-zを繰り返し表示するようになった。
<img width=60% src=https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/184089/138ebc47-2ec0-6185-43ab-1899eb5f0902.png>

UDPでの送信のみのプログラムの作成にも成功した。
以上である。