ESP32[13] Wi-Fi 通信 (softAP)
ES32はWi-Fiモジュールが標準でついているので簡単にWi-Fi通信が行えます。ここでは、ESP32をルーターとして機能させてみます。
ルーターとは複数のクライアントが接続できるサーバーです。具体的には1つのESP32をルーターにしてWi-Fiで複数のクライアントを接続させてクライアントとルーター間でデータのやり取りをします。通信にはUDPを用いています。TCP/IPでもできるとは思いますが、小さいデータのやり取りならUDPのほうが楽だからです。
// AP側(サーバー側)
#include <WiFi.h>
#include <WiFiUdp.h>
const char pass[] = "password";  // password
const char ssid[] = "SSID"; // SSID
const IPAddress ip(192, 168, 4, 1);       // IPアドレス
const IPAddress subnet(255, 255, 255, 0); // サブネットマスク
static const char *kRemoteIpadr = "192.168.4.255";  //送信先のIPアドレス (BC)
char data[256];
static WiFiUDP wifiUdp;
static WiFiUDP udp;
const int localPort = 10000;      // ポート番号
IPAddress myIP;
static void Serial_setup()
{
  Serial.begin(115200);
  Serial.println(""); // to separate line
}
void ip_port_set() {
  WiFi.softAPConfig(ip, ip, subnet); // IPアドレス、ゲートウェイ、サブネットマスクの設定
  wifiUdp.begin(localPort);
}
void setup() {
  ip_port_set();
  Serial_setup();
  ssid0_set();
  sprintf(data, "123456789\0");
  Serial.printf("Router Starts\n");
}
void ssid0_set() {
  WiFi.softAP(ssid, pass);           // SSIDとパスの設定
  delay(200);                        // 追記:このdelayを入れないと失敗する場合がある
  WiFi.softAPConfig(ip, ip, subnet); // IPアドレス、ゲートウェイ、サブネットマスクの設定
  delay(100);
  myIP = WiFi.softAPIP();
  udp.begin(localPort);  // UDP通信の開始(引数はポート番号)
}
void loop()
{
  char rv_data[255];
  int i;
  int rec_size;
  // データ送信
  wifiUdp.beginPacket(kRemoteIpadr, localPort);
  for (i = 0; i < 10; i++) {
    wifiUdp.write(data[i]);
  }
  wifiUdp.endPacket();
  //データ受信
  if (rec_size = wifiUdp.parsePacket()) {
    wifiUdp.read(rv_data, 255);
    Serial.printf("%s\n", rv_data);
  }
  delay(500);
}
// クライアント側
#include <WiFi.h>
#include <WiFiUdp.h>
#define TRUE 1
#define FALSE 0
const char pass[] = "password";  // password
const char ssid[] = "SSID"; // SSID
const IPAddress ip(192, 168, 4, 3);       // IPアドレス(ゲートウェイも兼ねる)
const IPAddress subnet(255, 255, 255, 0); // サブネットマスク
static WiFiUDP udp;
static const char *kRemoteIpadr = "192.168.4.255";  //送信先のIPアドレス ブロードキャスト
static const int localPort = 10000; //送信先のポート
hw_timer_t * timer = NULL; //timer 初期化
int msec; //msec カウンター用グローバル変数
int msec_100; // 100msec カウンター
int counter_100msec;
int rec_size;
int reconnect;
char data[256];
void IRAM_ATTR msecond_100() {
  msec_100++;
  if (msec_100 < 0) msec_100 = 0;
  counter_100msec = counter_100msec - 1;
  if (counter_100msec < 0) counter_100msec = 0;
}
#define RE_CONNECT 50 // 5 sec //切断したときに、再接続を開始するまでの時間
void setup() {
  Serial.begin(115200);
  Serial.println(""); // to separate line
  // msec timer start
  timer = timerBegin(0, 80, true); //timer=1us
  timerAttachInterrupt(timer, &msecond_100, true);
  timerAlarmWrite(timer, 100000, true); // 100ms
  timerAlarmEnable(timer);
  sprintf(data, "0123456789");
  Serial.printf("Client Starts\n");
  WiFi.begin(ssid, pass);
  delay(100);
  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(100);
  }
  Serial.println("connected");
  udp.begin(localPort);  // UDP通信の開始(引数はポート番号)
  counter_100msec = RE_CONNECT;
}
void loop() {
  char rv_data[255];
  int i;
  if (counter_100msec == 0) {
    reconnect = TRUE;
  }
  // データ受信
  if (rec_size = udp.parsePacket()) {
    counter_100msec = RE_CONNECT; // re connect counter resets.
    udp.read(rv_data, 255);
    Serial.printf("%s\n", rv_data);
    //データ送信
    Serial.printf("%s\n", data);
    udp.beginPacket(kRemoteIpadr, localPort);
    for (i = 0; i < sizeof(data); i++) {
      udp.write(data[i]);
    }
    udp.write('\0');
    udp.endPacket();
    delay(100);
    //再接続が必用なら再接続する。
    if (reconnect == TRUE) {
      WiFi.disconnect();
      delay(100);
      WiFi.begin(ssid, pass);
      while (WiFi.status() != WL_CONNECTED) {
        Serial.print(".");
        delay(100);
      }
      Serial.println(" connected");
      //   udp.begin(localPort);   UDP通信の開始(引数はポート番号)
      counter_100msec = RE_CONNECT;
      reconnect = FALSE;
    }
  }
}

