两个 ESP32 上的 AsyncUDP 示例不工作:"WL_NO_SSID_AVAIL"
AsyncUDP example on two ESP32s not working: "WL_NO_SSID_AVAIL"
我正在尝试在两个 ESP32 DEVKITV1s 之间创建一个直接的客户端-服务器 WiFi 网络,由我的两台计算机的 USB 端口供电。
我已经使用 Arduino IDE(使用额外的开发板管理器 URL https://dl.espressif.com/dl/package_esp32_index.json)加载了示例并且 WiFi 状态(在两个开发板上)是 WL_NO_SSID_AVAIL.
客户代码:
#include "WiFi.h"
#include "AsyncUDP.h"
const char * ssid = "my_ssid";
const char * password = "my_password";
AsyncUDP udp;
void setup()
{
Serial.begin(115200);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
if (WiFi.waitForConnectResult() != WL_CONNECTED) {
Serial.println("WiFi Failed");
while(1) {
delay(1000);
}
}
if(udp.connect(IPAddress(192,168,1,100), 1234)) {
Serial.println("UDP connected");
udp.onPacket([](AsyncUDPPacket packet) {
Serial.print("UDP Packet Type: ");
Serial.print(packet.isBroadcast()?"Broadcast":packet.isMulticast()?"Multicast":"Unicast");
Serial.print(", From: ");
Serial.print(packet.remoteIP());
Serial.print(":");
Serial.print(packet.remotePort());
Serial.print(", To: ");
Serial.print(packet.localIP());
Serial.print(":");
Serial.print(packet.localPort());
Serial.print(", Length: ");
Serial.print(packet.length());
Serial.print(", Data: ");
Serial.write(packet.data(), packet.length());
Serial.println();
//reply to the client
packet.printf("Got %u bytes of data", packet.length());
});
//Send unicast
udp.print("Hello Server!");
}
}
void loop()
{
delay(1000);
//Send broadcast on port 1234
udp.broadcastTo("Anyone here?", 1234);
}
服务器代码:
#include "WiFi.h"
#include "AsyncUDP.h"
const char * ssid = "my_ssid";
const char * password = "my_password";
AsyncUDP udp;
void setup()
{
Serial.begin(115200);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
if (WiFi.waitForConnectResult() != WL_CONNECTED) {
Serial.println("WiFi Failed");
while(1) {
delay(1000);
}
}
if(udp.listen(1234)) {
Serial.print("UDP Listening on IP: ");
Serial.println(WiFi.localIP());
udp.onPacket([](AsyncUDPPacket packet) {
Serial.print("UDP Packet Type: ");
Serial.print(packet.isBroadcast()?"Broadcast":packet.isMulticast()?"Multicast":"Unicast");
Serial.print(", From: ");
Serial.print(packet.remoteIP());
Serial.print(":");
Serial.print(packet.remotePort());
Serial.print(", To: ");
Serial.print(packet.localIP());
Serial.print(":");
Serial.print(packet.localPort());
Serial.print(", Length: ");
Serial.print(packet.length());
Serial.print(", Data: ");
Serial.write(packet.data(), packet.length());
Serial.println();
//reply to the client
packet.printf("Got %u bytes of data", packet.length());
});
}
}
void loop()
{
delay(1000);
//Send broadcast
udp.broadcast("Anyone here?");
}
其他人有没有遇到问题运行他们的 ESP32 上使用 Arduino IDE 的示例代码?
综上所述,我的误区是:
- AsyncUDP 示例不允许直接的客户端-服务器通信。它需要一个中间路由器,例如家用路由器。这是因为 WiFi.mode(WIFI_STA) 设置 - 服务器需要设置为 WiFi.mode(WIFI_AP) 才能连接到其他 ESP32。
- 客户端和服务端都需要使用udp.listen(端口)函数来接收消息(这里可以指定端口)。要发送消息,请对服务器使用 udp.broadcast(message),对客户端使用 udp.broadcastTo(message, port)。
以下代码是我可以使它仍然有效的最小示例。我确信有更好的示例可用,但这是我在没有 HTTP 请求的情况下使用中间路由器等在两个 ESP32 之间进行通信的示例的方式...
客户端:
#include "WiFi.h"
#include "AsyncUDP.h"
const char * ssid = "my_ssid";
const char * password = "my_password";
AsyncUDP udp;
int port = 1234;
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA); // Make this the client (the server is WIFI_AP)
WiFi.begin(ssid, password);
delay(100);
Serial.print("Connecting...");
// Display a period every 0.5 s to show the user something is happening.
while (WiFi.waitForConnectResult() != WL_CONNECTED) {
Serial.print(".");
delay(500);
}
Serial.println("");
if(udp.listen(port)) {
udp.onPacket([](AsyncUDPPacket packet) {
Serial.print("Received data: ");
Serial.write(packet.data(), packet.length());
Serial.println();
});
}
}
void loop(){
delay(1000);
udp.broadcastTo("A message for the server from the client.", port);
}
服务器端:
#include "WiFi.h"
#include "AsyncUDP.h"
const char *my_ssid = "my_ssid";
const char *password = "my_password";
int port = 1234;
AsyncUDP udp;
void setup(){
Serial.begin(115200);
WiFi.mode(WIFI_AP);
WiFi.softAP(my_ssid, password);
delay(100);
if(udp.listen(port)) {
udp.onPacket([](AsyncUDPPacket packet) {
Serial.print("Data: ");
Serial.write(packet.data(), packet.length());
Serial.println();
});
}
}
void loop() {
delay(1000);
udp.broadcastTo("Anyone here? Love from the server.", port);
}
这只是对 Jeremy 回答的适度补充。
文本指出服务器使用 udp.broadcast(message)
而客户端使用 udp.broadcastTo(message, port)
另一方面,所提供的代码两边都使用 broadcastTo
。
我想知道为什么会这样,在查看源代码 AsyncUPD.cpp 之后,我看到 udp.broadcast
实际上会通过调用 udp.broadcastTo
并将本地端口用作第二个参数来完成它的工作。
参考:https://github.com/espressif/arduino-esp32/blob/master/libraries/AsyncUDP/src/AsyncUDP.cpp 第 809 行。
这是一个小细节,但我认为值得一提。它允许我配对相同类型的 ESP32 板,并且(对我来说最重要的是)使用相同的代码进行 UDP 迭代。因此,这两个板可以一起工作(分层或不分层)或自主工作。
我正在尝试在两个 ESP32 DEVKITV1s 之间创建一个直接的客户端-服务器 WiFi 网络,由我的两台计算机的 USB 端口供电。
我已经使用 Arduino IDE(使用额外的开发板管理器 URL https://dl.espressif.com/dl/package_esp32_index.json)加载了示例并且 WiFi 状态(在两个开发板上)是 WL_NO_SSID_AVAIL.
客户代码:
#include "WiFi.h"
#include "AsyncUDP.h"
const char * ssid = "my_ssid";
const char * password = "my_password";
AsyncUDP udp;
void setup()
{
Serial.begin(115200);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
if (WiFi.waitForConnectResult() != WL_CONNECTED) {
Serial.println("WiFi Failed");
while(1) {
delay(1000);
}
}
if(udp.connect(IPAddress(192,168,1,100), 1234)) {
Serial.println("UDP connected");
udp.onPacket([](AsyncUDPPacket packet) {
Serial.print("UDP Packet Type: ");
Serial.print(packet.isBroadcast()?"Broadcast":packet.isMulticast()?"Multicast":"Unicast");
Serial.print(", From: ");
Serial.print(packet.remoteIP());
Serial.print(":");
Serial.print(packet.remotePort());
Serial.print(", To: ");
Serial.print(packet.localIP());
Serial.print(":");
Serial.print(packet.localPort());
Serial.print(", Length: ");
Serial.print(packet.length());
Serial.print(", Data: ");
Serial.write(packet.data(), packet.length());
Serial.println();
//reply to the client
packet.printf("Got %u bytes of data", packet.length());
});
//Send unicast
udp.print("Hello Server!");
}
}
void loop()
{
delay(1000);
//Send broadcast on port 1234
udp.broadcastTo("Anyone here?", 1234);
}
服务器代码:
#include "WiFi.h"
#include "AsyncUDP.h"
const char * ssid = "my_ssid";
const char * password = "my_password";
AsyncUDP udp;
void setup()
{
Serial.begin(115200);
WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);
if (WiFi.waitForConnectResult() != WL_CONNECTED) {
Serial.println("WiFi Failed");
while(1) {
delay(1000);
}
}
if(udp.listen(1234)) {
Serial.print("UDP Listening on IP: ");
Serial.println(WiFi.localIP());
udp.onPacket([](AsyncUDPPacket packet) {
Serial.print("UDP Packet Type: ");
Serial.print(packet.isBroadcast()?"Broadcast":packet.isMulticast()?"Multicast":"Unicast");
Serial.print(", From: ");
Serial.print(packet.remoteIP());
Serial.print(":");
Serial.print(packet.remotePort());
Serial.print(", To: ");
Serial.print(packet.localIP());
Serial.print(":");
Serial.print(packet.localPort());
Serial.print(", Length: ");
Serial.print(packet.length());
Serial.print(", Data: ");
Serial.write(packet.data(), packet.length());
Serial.println();
//reply to the client
packet.printf("Got %u bytes of data", packet.length());
});
}
}
void loop()
{
delay(1000);
//Send broadcast
udp.broadcast("Anyone here?");
}
其他人有没有遇到问题运行他们的 ESP32 上使用 Arduino IDE 的示例代码?
综上所述,我的误区是:
- AsyncUDP 示例不允许直接的客户端-服务器通信。它需要一个中间路由器,例如家用路由器。这是因为 WiFi.mode(WIFI_STA) 设置 - 服务器需要设置为 WiFi.mode(WIFI_AP) 才能连接到其他 ESP32。
- 客户端和服务端都需要使用udp.listen(端口)函数来接收消息(这里可以指定端口)。要发送消息,请对服务器使用 udp.broadcast(message),对客户端使用 udp.broadcastTo(message, port)。
以下代码是我可以使它仍然有效的最小示例。我确信有更好的示例可用,但这是我在没有 HTTP 请求的情况下使用中间路由器等在两个 ESP32 之间进行通信的示例的方式...
客户端:
#include "WiFi.h"
#include "AsyncUDP.h"
const char * ssid = "my_ssid";
const char * password = "my_password";
AsyncUDP udp;
int port = 1234;
void setup() {
Serial.begin(115200);
WiFi.mode(WIFI_STA); // Make this the client (the server is WIFI_AP)
WiFi.begin(ssid, password);
delay(100);
Serial.print("Connecting...");
// Display a period every 0.5 s to show the user something is happening.
while (WiFi.waitForConnectResult() != WL_CONNECTED) {
Serial.print(".");
delay(500);
}
Serial.println("");
if(udp.listen(port)) {
udp.onPacket([](AsyncUDPPacket packet) {
Serial.print("Received data: ");
Serial.write(packet.data(), packet.length());
Serial.println();
});
}
}
void loop(){
delay(1000);
udp.broadcastTo("A message for the server from the client.", port);
}
服务器端:
#include "WiFi.h"
#include "AsyncUDP.h"
const char *my_ssid = "my_ssid";
const char *password = "my_password";
int port = 1234;
AsyncUDP udp;
void setup(){
Serial.begin(115200);
WiFi.mode(WIFI_AP);
WiFi.softAP(my_ssid, password);
delay(100);
if(udp.listen(port)) {
udp.onPacket([](AsyncUDPPacket packet) {
Serial.print("Data: ");
Serial.write(packet.data(), packet.length());
Serial.println();
});
}
}
void loop() {
delay(1000);
udp.broadcastTo("Anyone here? Love from the server.", port);
}
这只是对 Jeremy 回答的适度补充。
文本指出服务器使用 udp.broadcast(message)
而客户端使用 udp.broadcastTo(message, port)
另一方面,所提供的代码两边都使用 broadcastTo
。
我想知道为什么会这样,在查看源代码 AsyncUPD.cpp 之后,我看到 udp.broadcast
实际上会通过调用 udp.broadcastTo
并将本地端口用作第二个参数来完成它的工作。
参考:https://github.com/espressif/arduino-esp32/blob/master/libraries/AsyncUDP/src/AsyncUDP.cpp 第 809 行。
这是一个小细节,但我认为值得一提。它允许我配对相同类型的 ESP32 板,并且(对我来说最重要的是)使用相同的代码进行 UDP 迭代。因此,这两个板可以一起工作(分层或不分层)或自主工作。