前回は、ESP32同士でUDP通信を行いました。一方がサーバーで他方がクライアントでした。今回はルータを通した通信を行いたいと思います。
ルータを通すので、前回の様にサーバを上げる必要は有りません。2つのESP32をSTAモードでWiFiにつなげば良いはずです。前回のクライアント側スケッチを元に書き換えました。先ずは送信側
#include "WiFi.h"
#include <WiFiUdp.h>
const char * ssid = "XXXXXX";
const char * password = "YYYYYY";
IPAddress ip(192, 168, 3, 30); // IP Address
IPAddress gateway(192,168, 3, 1); // Gateway Address
IPAddress subnet(255, 255, 255, 0); // Subnet Address
IPAddress cl01_ip(192, 168, 3, 31); // Client01 IP Address
static const int Remote_Port = 9000; // Destination port
static const int Org_Port = 9000; // Source port
WiFiUDP UDP;
void setup()
{
Serial.begin(115200);
WiFi.mode(WIFI_STA);
WiFi.config(ip, gateway, subnet);
WiFi.begin(ssid, password);
// Try forever
while (WiFi.status() != WL_CONNECTED) {
Serial.println("...Connecting to WiFi");
delay(1000);
}
Serial.println("Connected");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
UDP.begin(Org_Port);
Serial.println("Client OK");
}
char a = 'A';
void loop()
{
Serial.println("Send : " + String(a));
UDP.beginPacket(cl01_ip, Remote_Port);
UDP.write(a);
UDP.endPacket();
a ++;
if(a > 'F') a = 'A';
delay(3000);
}
- 4,5行 ルータデータ
- 今回は自宅ルータのSSIDとPASSWORDを入力して下さい。
- 7行 IPAddress ip(192, 168, 3, 31);
- IPアドレスの指定。ルータの都合で”192. 168. 3. 30″としました。
- 8,9行 GatewayとSubnetの指定。
- 11行 IPAddress cl01_ip(192, 168, 3, 31);
- 相手側のIPアドレスです。
- 22行 WiFi.mode(WIFI_STA);
- STAモード設定
- 23行 WiFi.config(ip, gateway, subnet);
- IPアドレス等設定。
- 24行 WiFiに接続。
- 後は前回の送信側と同じです。
次は受信側
#include <WiFiUdp.h>
#include "WiFi.h"
const char * ssid = "XXXXXX";
const char * password = "YYYYYY";
IPAddress ip(192, 168, 3, 31); // IP Address
IPAddress gateway(192,168, 3, 1); // Gateway Address
IPAddress subnet(255, 255, 255, 0); // Subnet Address
IPAddress cl00_ip(192, 168, 3, 30); // Client00 IP Address
static const int Remote_Port = 9000; // Destination port
static const int Org_Port = 9000; // Source port
WiFiUDP UDP;
void setup()
{
Serial.begin(115200);
WiFi.mode(WIFI_STA);
WiFi.config(ip, gateway, subnet);
WiFi.begin(ssid, password);
// Try forever
while (WiFi.status() != WL_CONNECTED) {
Serial.println("...Connecting to WiFi");
delay(1000);
}
Serial.println("Connected");
Serial.println(ssid);
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
UDP.begin(Org_Port);
Serial.println("Server OK");
}
void loop()
{
char rv_data[2] = {0,0};
if (UDP.parsePacket() > 0)
{
UDP.read(rv_data , 1);
Serial.print("Recieve : ");
Serial.println(rv_data);
UDP.flush();
}
}
- 7,11行 送信側とIPアドレスが逆。
- 22,23,24行 WiFiにSTAモードで接続。
- 後は前回の送信プログラムと同じ。
コンパイル、実行して下さい。下記は左が送信側、右が受信側のモニタです。
送信側、受信側共にIPアドレスが正しく設定されています。これでルータを通してESP32同士UDPで繋ぎました。
DNSサーバーを使えば
UDPでデータを送る場合、UDP.beginPacket()で先ず通信の準備を行いますが、この関数の最初の引数は送信先のIPアドレスです。だとすれば、DNSを使ってWiFiに繋ぎ、ドメイン名からIPアドレスを引っ張って来ればIPアドレスを固定する必要が無いのでは。試して見ます。
先ずは送信側
#include "WiFi.h"
#include <WiFiUdp.h>
#include <ESPmDNS.h>
const char * ssid = "XXXXXX";
const char * password = "YYYYYY";
static const int Remote_Port = 9000; // Destination port
static const int Org_Port = 9000; // Source port
WiFiUDP UDP;
void setup()
{
Serial.begin(115200);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
// Try forever
while (WiFi.status() != WL_CONNECTED) {
Serial.println("...Connecting to WiFi");
delay(1000);
}
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
if (MDNS.begin("UDP_Client01"))
Serial.println("MDNS responder started");
UDP.begin(Org_Port);
Serial.println("Client01 OK");
}
char a = 'A';
void loop()
{
char buf[7];
Serial.println("Send : " + String(a));
UDP.beginPacket(MDNS.queryHost("UDP_Client00"), Remote_Port);
UDP.write(a);
UDP.endPacket();
a ++;
if(a > 'F') a = 'A';
delay(3000);
}
- 3行 #include
- DNSヘッダーファイルのインクルード
- 29行 if (MDNS.begin(“UDP_Client01”))
- ドメイン名を”UDP_Client01″に設定
- 44行 UDP.beginPacket(MDNS.queryHost(“UDP_Client00”), Remote_Port);
- MDNS.queryHost(“UDP_Client00”)がドメイン名”UDP_Client00″のIPアドレスを返す。
- “UDP_Client00″は送信先のドメイン名
受信側
#include <WiFiUdp.h>
#include "WiFi.h"
#include <ESPmDNS.h>
const char * ssid = "XXXXXX";
const char * password = "YYYYYY";
static const int Remote_Port = 9000; // Destination port
static const int Org_Port = 9000; // Source port
WiFiUDP UDP;
void setup()
{
Serial.begin(115200);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
// Try forever
while (WiFi.status() != WL_CONNECTED) {
Serial.println("...Connecting to WiFi");
delay(1000);
}
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
if (MDNS.begin("UDP_Client00"))
Serial.println("MDNS responder started");
UDP.begin(Org_Port);
Serial.println("Client00 OK");
}
void loop()
{
char rv_data[2] = {0,0};
if (UDP.parsePacket() > 0)
{
UDP.read(rv_data , 1);
Serial.print("Recieve : ");
Serial.println(rv_data);
UDP.flush();
}
}
- 29行 if (MDNS.begin(“UDP_Client00”))
- ここでドメイン名を”UDP_Client00″に設定
- 後は変更なし
コンパイル、実行して下さい。左が送信側、右が受信側です。送信、受信共にIPアドレスは指定していませんが、ルータが、”192.168.3.13”と”192.168.3.12”を振ってくれた様です。かつそのIPアドレスを指定する事無くドメイン名で送信先にデータを送る事が出来ました。かなり便利な気がします。
このDNA、softAPモードでも使用出来ました。ルータに繋いだ方が通信範囲が広いと思うので取り敢えずルータを通す事にします。
一回に送るデータが1バイトでは困る
送信用のプログラムでデータを送信する関数は、UDP.write(a); 一回の通信で1バイトの送信です。流石にこれでは通信量が少ないと思っていたら、バッファーデータを送る関数が有りました。
UDP.write(Buffer,Buffer_size);
関数名は同じですが、引数が違います。最初の引数が、データを格納したバッファーのアドレス。次はそのバッファーのサイズです。また、バッファーは符号無し8ビットで宣言する様です。
受け側もこれに対応して、
UDP.read(Buffer , Buffer_size);
が有りました。最初の引数は、データを格納するバッファーのアドレス。次は読み込むデータの数です。
送れる最大数は
次の興味はバッファーを使用した場合1回で送れる最大数は幾つかです。バッファーサイズを変えて送信して見ましたが、どうも1280以上は1回では送れない様です。つまり、1回で送れる最大数は1280バイトとなります。
だいぶ進んで来ました。UDPに関しては取り敢えずここまで。次回は音声の入力と出力について考えます。