ESP32 SoftAP, AsyncServer freezes

Hello Experts,
i would like to ask for your expertise.
I plan to establish a WiFi Soft-Access-Point with my ESP32. The ESP32 should accept incoming connections and serve a static HTML/JS webpage when a client opens the ESP32s IP-Address in the browser. So far, i have written the Access-Point code and while my laptop can connect to it, my mobile (Android) can not.
Also, when i try to sanity check the server and the websocket (which will later communicate sensor-data to the clients devices javascript), the esp32 stops running. sometimes the server is created successfully and gets a valid memory address, sometimes it does not, but everytime it stops before printing the websocket. What do you think of this?

void setup() {
    // esp as a variable has a lot of members to look at.
    // increase log level for debugging purposes
    esp_log_level_set("*", ESP_LOG_VERBOSE);

    Serial.begin(115200); // Start ESP32 serial communication

    // TCP/IP stack
    esp_err_t result = esp_netif_init();
    if (result != ESP_OK) {
        Serial.println("Network Interface Initiation failed");
    }
    Serial.printf("Network Interface Init result: %d\n", result);

    // WiFi Driver
    wifi_init_config_t config = WIFI_INIT_CONFIG_DEFAULT();
    result = esp_wifi_init(&config);
    if (result != ESP_OK) {
        Serial.printf("WiFi init failed: %d\n", result);
        return;
    }
    Serial.printf("WiFi-Driver Init result: %d\n", result);

    // Network Interface
    esp_netif_t *netif_ap = esp_netif_create_default_wifi_ap();
    if (!netif_ap) {
        Serial.println("Network Interface AP Creation failed");
    } // attach network interface for ap mode
    result = esp_netif_attach_wifi_ap(netif_ap);
    if (result != ESP_OK) {
        Serial.printf("WiFi-AP and Network Interface could not be connected: %d\n", result);
    }
    // manual creation
    // esp_netif_t *netif_ap = esp_netif_get_handle_from_ifkey("WIFI_AP_DEF");
    // result = esp_netif_attach_wifi_ap(netif_ap);

    // Check WiFi-Mode
    wifi_mode_t wifi_mode;
    result = esp_wifi_get_mode(&wifi_mode);
    Serial.printf("Get WiFi-Mode: %d\n", result);
    if (wifi_mode != WIFI_MODE_AP) {
        result = esp_wifi_set_mode(WIFI_MODE_AP);
        Serial.printf("Changing WiFi-Mode: %d\n", result);

        result = esp_wifi_get_mode(&wifi_mode);
        Serial.printf("Get WiFi-Mode: %d\n", result);
    }

    // Access-Point Configuration
    wifi_config_t apConfig = {};
    strcpy((char *) apConfig.ap.ssid, "ambient_disco_ap");
    strcpy((char *) apConfig.ap.password, "rocking_stone");
    apConfig.ap.channel = 1;
    apConfig.ap.max_connection = 4;// apConfig.ap.authmode = WIFI_AUTH_WPA_WPA2_PSK;

    // Setter for Configuration
    result = esp_wifi_set_config(WIFI_IF_AP, &apConfig);
    apConfig.ap.authmode = WIFI_AUTH_OPEN;
    if (result != ESP_OK) {
        Serial.printf("Failed to configure AP: %d\n", result);
        return;
    }
    Serial.printf("WiFi Configuration result: %d\n", result);

    // stop DHCP-Client and Server (just in case they are up) to configure the DHCP-Server
    result = esp_netif_dhcpc_stop(netif_ap); // Stop DHCP client (if running)
    if (result == ESP_ERR_ESP_NETIF_DHCP_NOT_STOPPED) {
        Serial.printf("DHCP Client was already stopped.");
    }
    else if (result != ESP_OK) {
        Serial.printf("Failed to stop DHCP client: %s\n", esp_err_to_name(result));
    }
    result = esp_netif_dhcps_stop(netif_ap); // Stop DHCP server
    if (result != ESP_ERR_ESP_NETIF_DHCP_ALREADY_STOPPED && result != ESP_OK) {
        Serial.printf("Failed to stop DHCP server: %s\n", esp_err_to_name(result));
    }

    result = esp_netif_is_netif_up(netif_ap);
    Serial.printf("Network Interface is (0=up, 1=down): %d\n", result);

    // configure DHCP
    esp_netif_ip_info_t ip_info;
    ip_info.ip.addr = ESP_IP4TOADDR(192, 168, 4, 1); // Local IP
    ip_info.gw.addr = ESP_IP4TOADDR(192, 168, 4, 1); // Gateway
    ip_info.netmask.addr = ESP_IP4TOADDR(255, 255, 255, 0); // Subnet mask
    result = esp_netif_set_ip_info(netif_ap, &ip_info);
    if (result != ESP_OK) {
        Serial.printf("Failed to set IP info: %s\n", esp_err_to_name(result));
        return;
    }
    Serial.println("Static IP set.");

    // start DHCP Server
    result = esp_netif_dhcps_start(netif_ap);
    Serial.printf("DHCP-Server-Status code: %d\n", result);

    // check Server Status
    esp_netif_dhcp_status_t dhcps_status;
    result = esp_netif_dhcps_get_status(netif_ap, &dhcps_status);
    Serial.printf("DHCP-Result after getter: %d\n", result);
    Serial.printf("DHCP-Status after getter: %d\n", dhcps_status);

    // WiFi Event Handler
    wifi_event_id_t wifi_event = WiFi.onEvent(WiFiEventHandler);
    Serial.printf("Amount of WiFi Event Handlers registered: %d\n", wifi_event);

    // Start WiFi
    result = esp_wifi_start();
    if (result != ESP_OK) {
        Serial.printf("Failed to start WiFi: %d\n", result);
        return;
    }

    // Retrieve IP address of the AP
    result = esp_netif_get_ip_info(netif_ap, &ip_info);
    if (result == ESP_OK) {
        Serial.printf("AP IP Address: %s\n", ip4addr_ntoa(reinterpret_cast<const ip4_addr_t *>(&ip_info.ip)));
    } else {
        Serial.printf("Failed to retrieve IP address: %s\n", esp_err_to_name(result));
    }

    // wie viel Speicher ist noch da?
    Serial.printf("Free heap: %u bytes\n", ESP.getFreeHeap());

    // let everything settle
    delay(1000);

    // create server and socket
    static AsyncWebServer as_server(81);
    delay(1000);

    static AsyncWebSocket ws("/weppsocket");
    delay(1000);

    Serial.printf("Address of as_server: %p\n", (void*)&as_server);
    Serial.printf("Address of ws: %p\n", (void*)&ws);

    // Start listening for events on the websocket server
    Serial.println("ws.onEvent()");
    ws.onEvent(onEvent);

    // Add the websocket server handler to the webserver
    Serial.println("server.addHandler()");
    as_server.addHandler(&ws);

    // Start listening for socket connections
    Serial.println("Server.begin()");
    as_server.begin();

    // wie viel Speicher ist noch da?
    Serial.printf("Free heap: %u bytes\n", ESP.getFreeHeap());

    // Serve static HTML/JS files
    as_server.on("/", HTTP_GET, [](AsyncWebServerRequest *request){
        request->send(200, "text/html", R"rawliteral(
        <!DOCTYPE html>
        <html lang="en">
... js code
        </html>
    )rawliteral");
    });
    Serial.println("Finished setup.");
}

Debug Statements (Serial Monitor)
Network Interface Init result: 0
WiFi-Driver Init result: 0
Get WiFi-Mode: 0
WiFi Configuration result: 0
Network Interface is (0=up, 1=down): 0
Static IP set.
DHCP-Server-Status code: 0
DHCP-Result after getter: 0
DHCP-Status after getter: 0
Amount of WiFi Event Handlers registered: 1
AP IP Address: 192.168.4.1
Free heap: 226272 bytes
Address of as_server: 0

Platform.io
[env:esp32dev]
platform = espressif32
board = esp32dev
framework = arduino
monitor_speed = 115200
lib_deps =
mathieucarbou/ESPAsyncWebServer@^3.3.22
me-no-dev/AsyncTCP@^1.1.1
claws/BH1750@^1.3.0
adafruit/Adafruit BME280 Library @ ^2.2.4
adafruit/Adafruit Unified Sensor@^1.1.14
adafruit/Adafruit BusIO@^1.16.2
build_flags = -g -DCORE_DEBUG_LEVEL=3
monitor_filters = esp32_exception_decoder

Your sketch looks a bit overcomplicated!

All you need is …

main.cpp:

#include <Arduino.h>
#include <WiFi.h>
#include <ESPAsyncWebServer.h>

AsyncWebServer server(80);

const char* ssid =     "ambient_disco_ap";
const char* password = "rocking_stone";

const char* rootPage = R"(
<!DOCTYPE html>
<html lang="en">
<body>
  Hello World!
</body>
</html>
)";

void handleNotFound(AsyncWebServerRequest *request) {
    request->send(404, "text/plain", "Not found");
}

void handleRoot(AsyncWebServerRequest* request) {
    request->send(200, "text/html", rootPage);
}

void setupWebServer() {
    server.on("/", HTTP_GET, handleRoot);
    server.onNotFound(handleNotFound);
    server.begin();
}

void setupWiFiAP() {
    WiFi.softAP(ssid, password);
}

void setup() {
    Serial.begin(115200);

    setupWiFiAP();
    setupWebServer();
}

void loop() {
}

platformio.ini

[env:esp32dev]
platform = espressif32 @6.9.0
board = esp32dev
framework = arduino
monitor_speed = 115200
lib_deps = 
  https://github.com/me-no-dev/ESPAsyncWebServer
1 Like

Hello Sivar,
thank you for your answer!

I kept thinking that i need to do it all “manually” since its programming a microcontroller and that it is supposed to be sophisticated low-level c++.

While i am happy about your friendly words and the code that actually works, i am a little sad my “sophisticated” approach did not work.

Have a nice week :slight_smile:

Maybe this is a good starting point for you:

1 Like

I like that collection. I was skeptical first, but it seems there are tons of projects covering all sorts of areas.
As for my code, i have tried to work with the libraries you suggested in your platform.io file and, like magic, my own code runs. complicated, yes, very, but then again i will be graded at university and it might come off as a good effort. also, its kind of fun to tinker at this lower level.