Search code examples
udparduino-idearduino-esp8266esp32

AsyncUDP example on two ESP32s not working: "WL_NO_SSID_AVAIL"


I am attempting to create a direct Client-Server WiFi network between two ESP32 DEVKITV1s powered by my two computer's USB ports.

I have loaded the example using the Arduino IDE (with the additional boards manager URL https://dl.espressif.com/dl/package_esp32_index.json) and the WiFi status (on both boards) is WL_NO_SSID_AVAIL.

The client code:

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

The server code:

#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?");
}

Has anyone else had problems running the example code on their ESP32 using the Arduino IDE?


Solution

  • In summary, my misunderstandings were:

    1. The AsyncUDP example does not allow direct client-server communication. It requires an intermediary router, e.g. a home router. This is because of the WiFi.mode(WIFI_STA) setting - the server needed to be set to WiFi.mode(WIFI_AP) for other ESP32s to be connected to.
    2. Both the client and server need to use the udp.listen(port) function to receive messages (where you can specify the port). To send messages, use udp.broadcast(message) for the server and udp.broadcastTo(message, port) for the client.

    The following code is the smallest example I could make that still worked. I'm sure there are better examples available, but this is the way I got the example to work to communicate between the two ESP32s without HTTP requests, using an intermediary router, etc...

    The client side:

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

    The server side:

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