２台のArduinoでWi-Fi通信してみた

#はじめに
2台のArduinoを使ってWi-Fi通信をしました。
#目次
1.使ったもの
2.環境設定
3.コード
4.結果
#使ったもの
Arduino UNO
ESP-Wroom 02 （スイッチサイエンスでシンプル版を購入しました）
コンデンサ　0.1μF
コンバーター
3端子レギュレーター 3.3V
10KΩ抵抗3つ
これを次のように繋ぎます.

![arduino_setting.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/867001/797889a9-322a-958c-6e92-8b3b7f7ca441.png)


Wroomに供給する電源に直接3.3vの端子から引っ張らないのは、電力不足になるからだった気がします。
5Vから引っ張って電圧を変えて供給しましょう。
諸々の回路のつなげ方はWroomの説明書に記載があります。(抵抗を挟んでつなげるように...など）

#環境設定
wroom02の設定を行います。

```
#include <SoftwareSerial.h>
SoftwareSerial mySerial(2,3); // RX, TX
//この部分でArduinoのRXピンをWroomからのデータ受信に、3ピンをWroomへのデータ送信に定義
void setup()
{
  Serial.begin(115200);
　//PCとArduinoの通信を115200bpsに設定
  mySerial.begin(115200);
　//wroom-Arduinoの通信を115200bpsに設定（wroomの通信速度がデフォルトで115200bpsなので）
}
void loop()
{
  if(mySerial.available())
  Serial.write(mySerial.read());
  if (Serial.available())
  mySerial.write(Serial.read());
}
```

この状態でシリアルモニタを開きます。
ここで、Wroomの通信速度を変更します。

```
AT+UART_DEF=9600,8,1,0,0
```

これで wroom02の通信速度を9600bpsに変更しました。これ以上早いと動作が不安定になるらしいので今後はこの速度で通信を行います。

次に通信用ライブラリを用意します。
ESP8266とArduinoを通信するライブラリをダウンロードします。
https://github.com/itead/ITEADLIB_Arduino_WeeESP8266
このファイルのESP8266.h内の27行目を

```
 #define ESP8266_USE_SOFTWARE_SERIAL
```

とします。
これで設定は終わりです。
#コード
###ネットワーク、コードの説明
サーバーサイド、クライアントサイドで２つ用意します。
ネットワークは写真のものを想定します
![スクリーンショット 2020-11-24 18.07.20.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/867001/a40f7dcd-d88f-6c82-e87b-b5a62a2b2f18.png)
ここで、クライアント、サーバー通信を行うに当たって、サーバー側のIPアドレスを把握する必要があります。
必要に応じて、サーバー側に決めたデバイスのIPアドレスを固定で割り当ててください。
DHCPを使って動的に割り当てないように、クライアント側はIPアドレスを指定して、パケットを送信します。
そのため、DHCPを用いている場合、IPアドレスが毎回変わることになり、コードを書き換える必要が生じます。
IPアドレスは192.168.11.0などにアクセスして、設定してください。

###コードの注意

このプログラムの通信の順は
①クライアントがサーバーにデータを送信
②サーバーが受信したことを知らせるデータをクライアントに送信
という手順を踏んでいます
時々データを送信しても受信していない状態が発生します。そのため、連続で通信を行うと両方が受信待ちとなり、デットロックが発生することがあります。
syncという関数は同期をとっている部分です。なくてもいいです。
センサ値からデータを取得するようなものを考えている場合は、クライアントは送りっぱなしに、サーバーは受信しっぱなしにするといいと思います。

###コード

```server.ino
 #include "ESP8266.h"
 #define SSID "自分が使うアクセスポイント"
 #define PASSWORD "パスワード"
 #define BAUD_RATE   9600
 #define HOST_PORT (8090)

SoftwareSerial mySerial(2, 3); 
ESP8266 wifi(mySerial);

void setupESP8266()
{
  while (1) {
    Serial.print("restaring esp8266...");
    if (wifi.restart()) {
      Serial.print("ok\r\n");
      break;
    }
    else {
      Serial.print("not ok...\r\n");
      Serial.print("Trying to kick...");
      while (1) {
        if (wifi.kick()) {
          Serial.print("ok\r\n");
          break;
        }
        else {
          Serial.print("not ok... Wait 5 sec and retry...\r\n");
          delay(5000);
        }
      }
    }
  }

  Serial.print("setup begin\r\n");
  Serial.print("FW Version:");
  Serial.println(wifi.getVersion().c_str());

  while (1) {
    if (wifi.setOprToStation()) {
      Serial.print("to station ok\r\n");
      break;
    }
    else {
      Serial.print("to station err\r\n");
      Serial.println("Wait 5 seconds and try again...");
      delay(5000);
    }
  }

  while (1) {
    if (wifi.joinAP(SSID, PASSWORD)) {
      Serial.print("Join AP success\r\n");
      break;
    }
    else {
      Serial.print("Join AP failure\r\n");
      Serial.println("Wait 5 seconds and try again...");
      delay(5000);
    }
  }
  Serial.print("setup end\r\n");
}

void setup(void)
{
  Serial.begin(BAUD_RATE);
  setupESP8266();
  
  if (wifi.enableMUX()) {
    Serial.print("multiple ok\r\n");
  } else {
    Serial.print("multiple err\r\n");
  }

  if (wifi.startTCPServer(HOST_PORT)) {
    Serial.print("start tcp server ok\r\n");
  } else {
    Serial.print("start tcp server err\r\n");
  }

  if (wifi.setTCPServerTimeout(600)) {
    Serial.print("set tcp server timout 10 seconds\r\n");
  } else {
    Serial.print("set tcp server timout err\r\n");
  }

  Serial.print("setup end\r\n");
}

void loop(void)
{
  uint8_t buffer[128] = {0};//送りたい文字
  uint8_t mux_id;
  uint32_t len;
  int val;
  char val2[5];
  len = wifi.recv(&mux_id, buffer, sizeof(buffer), 100);
  val =wifi.recv(&mux_id,val2,sizeof(val2),100);
  //&mux_id is a TCP id(which TCP send the data),buffer is storing place.
  //return the length of received data
  if (len > 0) {
    Serial.print("Status:[");
    Serial.print(wifi.getIPStatus().c_str());
    Serial.println("]");

    Serial.print("Received from :");
    Serial.print(mux_id);
    Serial.print("[");
    for (uint32_t i = 0; i < len; i++) {
      Serial.print((char)buffer[i]);
    }
    for(uint32_t j=0;j<val;j++){
    Serial.print((char)val2[j]);
    }
    Serial.print("]\r\n");

    if (wifi.send(mux_id, buffer, len)) {
      delay(3000);
      Serial.print("send back ok\r\n");
    } else {
      delay(3000);
      Serial.print("send back err\r\n");
    }

    if (wifi.releaseTCP(mux_id)) {
      Serial.print("release tcp ");
      Serial.print(mux_id);
      Serial.println(" ok");
    } else {
      Serial.print("release tcp");
      Serial.print(mux_id);
      Serial.println(" err");
    }

    Serial.print("Status:[");
    Serial.print(wifi.getIPStatus().c_str());
    Serial.println("]");
  }
}
```

```client.ino
#include "ESP8266.h"
#include <SoftwareSerial.h>

#define SSID "自分のアクセスポイント"
#define PASSWORD "アクセスポイントのパスワード"
#define HOST_NAME   "サーバーに割り当てたIPアドレス"
#define HOST_PORT   (8090)
#define BAUD_RATE   9600

SoftwareSerial mySerial(2, 3); /* RX:D3, TX:D2 */
ESP8266 wifi(mySerial,BAUD_RATE);
void sync(ESP8266 wifi){
  static uint8_t thisid=0;
  char* synctime="s";
  char* synctimerec;
   if(wifi.send(thisid, synctime, sizeof(synctime))){
    Serial.println("send success");
   }
  Serial.println("sync strat");
   if(wifi.recv(thisid, synctimerec, sizeof(synctimerec), 100)){
    Serial.println((char)synctimerec);
    Serial.println("sync end");
   }
  
}
void setupESP8266()
{
  while (1) {
    Serial.print("restaring esp8266...");
    if (wifi.restart()) {
      Serial.print("ok\r\n");
      break;
    }
    else {
      Serial.print("not ok...\r\n");
      Serial.print("Trying to kick...");
      while (1) {
        if (wifi.kick()) {
          Serial.print("ok\r\n");
          break;
        }
        else {
          Serial.print("not ok... Wait 5 sec and retry...\r\n");
          delay(5000);
        }
      }
    }
  }

  Serial.print("setup begin\r\n");
  Serial.print("FW Version:");
  Serial.println(wifi.getVersion().c_str());

  while (1) {
    if (wifi.setOprToStation()) {
      Serial.print("to station ok\r\n");
      break;
    }
    else {
      Serial.print("to station err\r\n");
      Serial.println("Wait 5 seconds and try again...");
      delay(5000);
    }
  }

  while (1) {
    if (wifi.joinAP(SSID, PASSWORD)) {
      Serial.print("Join AP success\r\n");
      break;
    }
    else {
      Serial.print("Join AP failure\r\n");
      Serial.println("Wait 5 seconds and try again...");
      delay(5000);
    }
  }
  Serial.print("setup end\r\n");
}

void setup(void)
{

  Serial.begin(BAUD_RATE);
  setupESP8266();
  if (wifi.enableMUX()) {
    Serial.print("multiple ok\r\n");
  } else {
    Serial.print("multiple err\r\n");
  }

  Serial.print("setup end\r\n");
}

void loop(void)
{
  uint8_t buffer[128] = {0};
  static uint8_t mux_id = 0;
   uint8_t val=analogRead(0);
   uint8_t sensor[2];
   sensor[0]='d';
   sensor[1]=val;
  if (wifi.createTCP(mux_id, HOST_NAME, HOST_PORT)) {
    Serial.print("create tcp ");
    Serial.print(mux_id);
    Serial.println(" ok");
    sync(wifi);
  } else {
    Serial.print("create tcp ");
    Serial.print(mux_id);
    Serial.println(" err");
  }



  char *hello = "mHello, this is client!";
  if (wifi.send(mux_id, (const uint8_t*)hello, strlen(hello))) {
    delay(1000);
    Serial.println("send ok");
  } else {
    delay(1000);
    Serial.println("send err");
  }

  uint32_t len = wifi.recv(mux_id, buffer, sizeof(buffer), 10000);
  if (len > 0) {
    Serial.print("Received:[");
    for (uint32_t i = 0; i < len; i++) {
      Serial.print((char)buffer[i]);
    }
    Serial.print("]\r\n");
    wifi.send(mux_id, (const uint8_t*)sensor, strlen(sensor));
  }

  if (wifi.releaseTCP(mux_id)) {
    Serial.print("release tcp ");
    Serial.print(mux_id);
    Serial.println(" ok");
  } else {
    Serial.print("release tcp ");
    Serial.print(mux_id);
    Serial.println(" err");
  }

  delay(3000);
  mux_id++;
  if (mux_id >= 1) {
    mux_id = 0;
  }
}
```


#参考
https://ics.media/entry/10457/
http://discexuno.wp.xdomain.jp/arduino/esp-wroom-02_client/