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;
}
}
}