Page 1 of 1

WiFi always fails and then connects

Posted: Tue Jul 30, 2024 6:32 am
by AndreaS73
I wrote this code (derived from the examples) for ESP32-S3:

Code: Select all

#include "task_wifi.h"

#include <esp_log.h>
#include <esp_system.h>
#include <sdkconfig.h>
#include <lwip/netdb.h>

#include <string.h>

#define WIFI_SSID "<ssid>"
#define WIFI_PASSWORD "<password>"

#define WIFI_DELAY_RETRY    10
#define EXAMPLE_NETIF_DESC_STA "example_netif_sta"
#define EXAMPLE_WIFI_SCAN_METHOD WIFI_FAST_SCAN
#define EXAMPLE_WIFI_CONNECT_AP_SORT_METHOD WIFI_CONNECT_AP_BY_SIGNAL
#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_OPEN
//#define EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD WIFI_AUTH_WPA_WPA2_PSK

#define EXAMPLE_STATIC_IP_ADDR        "192.168.2.222"
#define EXAMPLE_STATIC_NETMASK_ADDR   "255.255.255.0"
#define EXAMPLE_STATIC_GW_ADDR        "192.168.2.1"
#ifdef CONFIG_EXAMPLE_STATIC_DNS_AUTO
#define EXAMPLE_MAIN_DNS_SERVER       EXAMPLE_STATIC_GW_ADDR
#define EXAMPLE_BACKUP_DNS_SERVER     "0.0.0.0"
#else
#define EXAMPLE_MAIN_DNS_SERVER       "192.168.2.1"
#define EXAMPLE_BACKUP_DNS_SERVER     "192.168.2.1"
#endif
#ifdef CONFIG_EXAMPLE_STATIC_DNS_RESOLVE_TEST
#define EXAMPLE_RESOLVE_DOMAIN        CONFIG_EXAMPLE_STATIC_RESOLVE_DOMAIN
#endif

static const char *TAG = "wifi";
static esp_netif_t *sta_netif = NULL;
static SemaphoreHandle_t s_semph_get_ip_addrs = NULL;

enum TaskWiFiStates
{
    WiFiIdle,
    WiFiConnecting,
    WiFiConnected,
    WiFiError
} _state;

enum TaskWiFiFlags
{
    FlagWiFiConnected,
    FlagWiFiDisconnected
};
static int _flags = 0;

static esp_err_t example_set_dns_server(esp_netif_t *netif, uint32_t addr, esp_netif_dns_type_t type)
{
    if (addr && (addr != IPADDR_NONE)) 
    {
        esp_netif_dns_info_t dns;
        dns.ip.u_addr.ip4.addr = addr;
        dns.ip.type = IPADDR_TYPE_V4;
        ESP_ERROR_CHECK(esp_netif_set_dns_info(netif, type, &dns));
    }
    return ESP_OK;
}

static void example_set_static_ip(esp_netif_t *netif)
{
    if (esp_netif_dhcpc_stop(netif) != ESP_OK) 
    {
        ESP_LOGE(TAG, "Failed to stop dhcp client");
        return;
    }

    esp_netif_ip_info_t ip;
    memset(&ip, 0 , sizeof(esp_netif_ip_info_t));
    ip.ip.addr = ipaddr_addr(EXAMPLE_STATIC_IP_ADDR);
    ip.netmask.addr = ipaddr_addr(EXAMPLE_STATIC_NETMASK_ADDR);
    ip.gw.addr = ipaddr_addr(EXAMPLE_STATIC_GW_ADDR);

    if (esp_netif_set_ip_info(netif, &ip) != ESP_OK) 
    {
        ESP_LOGE(TAG, "Failed to set ip info");
        return;
    }

    ESP_LOGD(TAG, "Success to set static ip: %s, netmask: %s, gw: %s", EXAMPLE_STATIC_IP_ADDR, EXAMPLE_STATIC_NETMASK_ADDR, EXAMPLE_STATIC_GW_ADDR);
    ESP_ERROR_CHECK(example_set_dns_server(netif, ipaddr_addr(EXAMPLE_MAIN_DNS_SERVER), ESP_NETIF_DNS_MAIN));
    ESP_ERROR_CHECK(example_set_dns_server(netif, ipaddr_addr(EXAMPLE_BACKUP_DNS_SERVER), ESP_NETIF_DNS_BACKUP));
}

static void example_handler_on_wifi_disconnect(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data)
{

    ESP_LOGI(TAG, "WiFi disconnected");
    _flags |= (1 << FlagWiFiDisconnected);
}

static void example_handler_on_wifi_connect(void *esp_netif, esp_event_base_t event_base, int32_t event_id, void *event_data)
{
    //example_set_static_ip(esp_netif);
    _flags |= (1 << FlagWiFiConnected);
}

bool example_is_our_netif(const char *prefix, esp_netif_t *netif)
{
    return strncmp(prefix, esp_netif_get_desc(netif), strlen(prefix) - 1) == 0;
}

static void example_handler_on_sta_got_ip(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data)
{
    ip_event_got_ip_t *event = (ip_event_got_ip_t *)event_data;
    if (!example_is_our_netif(EXAMPLE_NETIF_DESC_STA, event->esp_netif)) return;
    ESP_LOGI(TAG, "Got IPv4 event: Interface \"%s\" address: " IPSTR, esp_netif_get_desc(event->esp_netif), IP2STR(&event->ip_info.ip));
    if (s_semph_get_ip_addrs) xSemaphoreGive(s_semph_get_ip_addrs);
    else ESP_LOGI(TAG, "- IPv4 address: " IPSTR ",", IP2STR(&event->ip_info.ip));
    data.system.ip = event->ip_info.ip;
}

void wifi_init()
{
    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
    ESP_ERROR_CHECK(esp_wifi_init(&cfg));

    esp_netif_inherent_config_t esp_netif_config = ESP_NETIF_INHERENT_DEFAULT_WIFI_STA();
    esp_netif_config.if_desc = EXAMPLE_NETIF_DESC_STA;
    esp_netif_config.route_prio = 128;
    sta_netif = esp_netif_create_wifi(WIFI_IF_STA, &esp_netif_config);
    esp_wifi_set_default_wifi_sta_handlers();

    ESP_ERROR_CHECK(esp_wifi_set_storage(WIFI_STORAGE_RAM));
    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
    ESP_ERROR_CHECK(esp_wifi_start());
}

esp_err_t wifi_connect()
{
    wifi_config_t wifi_config = 
    {
        .sta = 
        {
            .ssid = WIFI_SSID,
            .password = WIFI_PASSWORD,
            .scan_method = EXAMPLE_WIFI_SCAN_METHOD,
            .sort_method = EXAMPLE_WIFI_CONNECT_AP_SORT_METHOD,
            .threshold.rssi = -127,
            .threshold.authmode = EXAMPLE_WIFI_SCAN_AUTH_MODE_THRESHOLD,
        },
    };
   
    ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &example_handler_on_wifi_disconnect, NULL));
    ESP_ERROR_CHECK(esp_event_handler_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &example_handler_on_sta_got_ip, NULL));
    ESP_ERROR_CHECK(esp_event_handler_register(WIFI_EVENT, WIFI_EVENT_STA_CONNECTED, &example_handler_on_wifi_connect, sta_netif));

    ESP_LOGI(TAG, "Connecting to %s...", wifi_config.sta.ssid);
    ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));

    esp_err_t ret = esp_wifi_connect();
    if (ret != ESP_OK) 
    {
        ESP_LOGE(TAG, "WiFi connect failed! ret:%x", ret);
        return ret;
    }

    return ESP_OK;
}

esp_err_t wifi_stop()
{
    ESP_ERROR_CHECK(esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_DISCONNECTED, &example_handler_on_wifi_disconnect));
    ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, &example_handler_on_sta_got_ip));
    ESP_ERROR_CHECK(esp_event_handler_unregister(WIFI_EVENT, WIFI_EVENT_STA_CONNECTED, &example_handler_on_wifi_connect));

    if (s_semph_get_ip_addrs) vSemaphoreDelete(s_semph_get_ip_addrs);
    esp_err_t err = esp_wifi_stop();
    if (err == ESP_ERR_WIFI_NOT_INIT) return err;

    ESP_ERROR_CHECK(err);
    ESP_ERROR_CHECK(esp_wifi_deinit());
    ESP_ERROR_CHECK(esp_wifi_clear_default_wifi_driver_and_handlers(sta_netif));
    esp_netif_destroy(sta_netif);
    sta_netif = NULL;
    return ESP_OK;
}

void Wifi_Task(void *pvParameters)
{
    int tick = 0;
    _state = WiFiIdle;    

    while (1)
    {
        vTaskDelay(1000 / portTICK_PERIOD_MS);

        switch (_state)
        {
        case WiFiIdle:
            wifi_init();
            wifi_connect();
            _state = WiFiConnecting;
            break;

        case WiFiConnecting:
            if (_flags & (1 << FlagWiFiConnected))
            {                                
                _state = WiFiConnected;
                _flags &= ~(1 << FlagWiFiConnected);
            }
            else if (_flags & (1 << FlagWiFiDisconnected))
            {    
                wifi_stop();
                tick = WIFI_DELAY_RETRY;        
                _state = WiFiError;
                _flags &= ~(1 << FlagWiFiDisconnected);
            }
            break;

        case WiFiConnected:
            if (_flags & (1 << FlagWiFiDisconnected))
            {    
                wifi_stop();
                tick = WIFI_DELAY_RETRY;        
                _state = WiFiError;
                _flags &= ~(1 << FlagWiFiDisconnected);
            }
            break;

        case WiFiError:
            if (--tick == 0) _state = WiFiIdle;
            break;        
        }
    }
}

esp_netif_t *Wifi_GetNetif(void)
{
    return sta_netif;
}
But the output is always the same:

Code: Select all

I (26) boot: ESP-IDF v5.3-dev-1162-gee3a46dbc3 2nd stage bootloader
I (27) boot: compile time Jul 22 2024 15:22:23
I (27) boot: Multicore bootloader
I (31) boot: chip revision: v0.2
I (35) boot.esp32s3: Boot SPI Speed : 80MHz
I (40) boot.esp32s3: SPI Mode       : DIO
I (45) boot.esp32s3: SPI Flash Size : 8MB
I (49) boot: Enabling RNG early entropy source...
I (55) boot: Partition Table:
I (58) boot: ## Label            Usage          Type ST Offset   Length
I (66) boot:  0 nvs              WiFi data        01 02 00009000 00006000
I (73) boot:  1 phy_init         RF data          01 01 0000f000 00001000
I (81) boot:  2 factory          factory app      00 00 00010000 00100000
I (88) boot: End of partition table
I (92) esp_image: segment 0: paddr=00010020 vaddr=3c0a0020 size=2e178h (188792) map
I (135) esp_image: segment 1: paddr=0003e1a0 vaddr=3fc9b800 size=01e78h (  7800) load
I (137) esp_image: segment 2: paddr=00040020 vaddr=42000020 size=984c4h (623812) map
I (252) esp_image: segment 3: paddr=000d84ec vaddr=3fc9d678 size=02b44h ( 11076) load
I (255) esp_image: segment 4: paddr=000db038 vaddr=40374000 size=1771ch ( 96028) load
I (288) boot: Loaded app from partition at offset 0x10000
I (289) boot: Disabling RNG early entropy source...
I (289) cpu_start: Multicore app
I (302) cpu_start: Pro cpu start user code
I (302) cpu_start: cpu freq: 160000000 Hz
I (302) cpu_start: Application information:
I (303) cpu_start: Project name:     GLT.firmware
I (303) cpu_start: App version:      1
I (303) cpu_start: Compile time:     Jul 22 2024 15:22:21
I (303) cpu_start: ELF file SHA256:  aa57d6f9f...
I (304) cpu_start: ESP-IDF:          v5.3-dev-1162-gee3a46dbc3
I (304) cpu_start: Min chip rev:     v0.0
I (304) cpu_start: Max chip rev:     v0.99 
I (304) cpu_start: Chip rev:         v0.2
I (305) heap_init: Initializing. RAM available for dynamic allocation:
I (305) heap_init: At 3FCA4BF0 len 00044B20 (274 KiB): RAM
I (305) heap_init: At 3FCE9710 len 00005724 (21 KiB): RAM
I (305) heap_init: At 3FCF0000 len 00008000 (32 KiB): DRAM
I (306) heap_init: At 600FE010 len 00001FD8 (7 KiB): RTCRAM
I (307) spi_flash: detected chip: gd
I (307) spi_flash: flash io: dio
I (308) sleep: Configure to isolate all GPIO pins in sleep state
I (308) sleep: Enable automatic switching of GPIO sleep configuration
I (309) main_task: Started on CPU0
I (319) main_task: Calling app_main()
I (349) gpio: GPIO[39]| InputEn: 0| OutputEn: 0| OpenDrain: 0| Pullup: 1| Pulldown: 0| Intr:0 
I (1049) gpio: GPIO[14]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0 
I (1049) gpio: GPIO[47]| InputEn: 0| OutputEn: 1| OpenDrain: 0| Pullup: 0| Pulldown: 0| Intr:0 
I (1299) gpio: GPIO[15]| InputEn: 1| OutputEn: 1| OpenDrain: 1| Pullup: 0| Pulldown: 0| Intr:0 
I (1299) gpio: GPIO[16]| InputEn: 1| OutputEn: 1| OpenDrain: 1| Pullup: 0| Pulldown: 0| Intr:0 
I (1299) gpio: GPIO[17]| InputEn: 1| OutputEn: 1| OpenDrain: 1| Pullup: 0| Pulldown: 0| Intr:0 
I (1309) gpio: GPIO[18]| InputEn: 1| OutputEn: 1| OpenDrain: 1| Pullup: 0| Pulldown: 0| Intr:0 
I (2409) pp: pp rom version: e7ae62f
I (2409) net80211: net80211 rom version: e7ae62f
I (2419) wifi:wifi driver task: 3fcb155c, prio:23, stack:6656, core=0
I (2429) wifi:wifi firmware version: 1160f50
I (2429) wifi:wifi certification version: v7.0
I (2429) wifi:config NVS flash: enabled
I (2429) wifi:config nano formating: disabled
I (2429) wifi:Init data frame dynamic rx buffer num: 32
I (2429) wifi:Init static rx mgmt buffer num: 5
I (2429) wifi:Init management short buffer num: 32
I (2439) wifi:Init dynamic tx buffer num: 32
I (2439) wifi:Init static tx FG buffer num: 2
I (2439) wifi:Init static rx buffer size: 1600
I (2439) wifi:Init static rx buffer num: 10
I (2439) wifi:Init dynamic rx buffer num: 32
I (2439) wifi_init: rx ba win: 6
I (2439) wifi_init: tcpip mbox: 32
I (2439) wifi_init: udp mbox: 6
I (2439) wifi_init: tcp mbox: 6
I (2439) wifi_init: tcp tx win: 5760
I (2439) wifi_init: tcp rx win: 5760
I (2439) wifi_init: tcp mss: 1440
I (2439) wifi_init: WiFi IRAM OP enabled
I (2439) wifi_init: WiFi RX IRAM OP enabled
I (2439) phy_init: phy_version 620,ec7ec30,Sep  5 2023,13:49:13
I (2479) wifi:mode : sta (24:58:7c:f4:96:30)
I (2479) wifi:enable tsf
I (2479) wifi: Connecting to <ssid>...
W (2539) wifi:Haven't to connect to a suitable AP now!
W (3629) wifi:Haven't to connect to a suitable AP now!
I (3709) wifi:new:<11,0>, old:<1,0>, ap:<255,255>, sta:<11,0>, prof:1
I (3709) wifi:state: init -> auth (b0)
I (3709) wifi:state: auth -> init (8a0)
I (3709) wifi:new:<11,0>, old:<11,0>, ap:<255,255>, sta:<11,0>, prof:1
I (3719) wifi: WiFi disconnected
I (4489) wifi:flush txq
I (4489) wifi:stop sw txq
I (4489) wifi:lmac stop hw txq
I (4489) wifi:Deinit lldesc rx mblock:10
I (15499) pp: pp rom version: e7ae62f
I (15499) net80211: net80211 rom version: e7ae62f
I (15509) wifi:wifi driver task: 3fcb76f4, prio:23, stack:6656, core=0
I (15519) wifi:wifi firmware version: 1160f50
I (15519) wifi:wifi certification version: v7.0
I (15519) wifi:config NVS flash: enabled
I (15519) wifi:config nano formating: disabled
I (15519) wifi:Init data frame dynamic rx buffer num: 32
I (15519) wifi:Init static rx mgmt buffer num: 5
I (15519) wifi:Init management short buffer num: 32
I (15519) wifi:Init dynamic tx buffer num: 32
I (15529) wifi:Init static tx FG buffer num: 2
I (15529) wifi:Init static rx buffer size: 1600
I (15529) wifi:Init static rx buffer num: 10
I (15529) wifi:Init dynamic rx buffer num: 32
I (15529) wifi_init: rx ba win: 6
I (15529) wifi_init: tcpip mbox: 32
I (15529) wifi_init: udp mbox: 6
I (15529) wifi_init: tcp mbox: 6
I (15529) wifi_init: tcp tx win: 5760
I (15529) wifi_init: tcp rx win: 5760
I (15529) wifi_init: tcp mss: 1440
I (15529) wifi_init: WiFi IRAM OP enabled
I (15529) wifi_init: WiFi RX IRAM OP enabled
I (15529) wifi:mode : sta (24:58:7c:f4:96:30)
I (15529) wifi:enable tsf
I (15529) wifi: Connecting to <ssid>...
W (16109) wifi:Haven't to connect to a suitable AP now!
I (16759) wifi:new:<11,0>, old:<1,0>, ap:<255,255>, sta:<11,0>, prof:1
I (16759) wifi:state: init -> auth (b0)
I (16759) wifi:state: auth -> assoc (0)
I (16769) wifi:state: assoc -> run (10)
I (16799) wifi:connected with <ssid>, aid = 3, channel 11, BW20, bssid = 3c:a6:2f:38:34:07
I (16799) wifi:security: WPA2-PSK, phy: bgn, rssi: -68
I (16799) wifi:pm start, type: 1

I (16799) wifi:dp: 1, bi: 102400, li: 3, scale listen interval from 307200 us to 307200 us
I (16809) wifi:set rx beacon pti, rx_bcn_pti: 0, bcn_timeout: 25000, mt_pti: 0, mt_time: 10000
I (16809) wifi:<ba-add>idx:0 (ifx:0, 3c:a6:2f:38:34:07), tid:6, ssn:2, winSize:64
I (16869) wifi:AP's beacon interval = 102400 us, DTIM period = 1
I (17859) esp_netif_handlers: example_netif_sta ip: 192.168.2.138, mask: 255.255.0.0, gw: 192.168.2.1
I (17859) wifi: Got IPv4 event: Interface "example_netif_sta" address: 192.168.2.138
I (17859) wifi: - IPv4 address: 192.168.2.138,
On the first try it fails to connect, but I cannot understand the reason. After 10 seconds my FSM tries again and this time it connects.
This happens 100% of the times, so I'm pretty sure I did something wrong!

Re: WiFi always fails and then connects

Posted: Tue Jul 30, 2024 8:22 pm
by MicroController
Same here (ESP32-C3, IDF v5.1):

Code: Select all

I (560) example_connect: Connecting to <My SSID>...
I (570) example_connect: Waiting for IP(s)
W (2970) wifi: [ieee80211_ht.c,2036] new:<11,0>, old:<1,0>, ap:<255,255>, sta:<11,0>, prof:1
W (3500) wifi: [ieee80211_sta.c,204] state: init -> auth (b0)
W (3510) wifi: [ieee80211_sta.c,204] state: auth -> init (8a0)
W (3510) wifi: [ieee80211_ht.c,2036] new:<11,0>, old:<11,0>, ap:<255,255>, sta:<11,0>, prof:1
I (3510) example_connect: Wi-Fi disconnected, trying to reconnect in 1s...
I (4520) example_connect: Reconnecting...
I (6920) example_connect: Wi-Fi disconnected, trying to reconnect in 2s...
I (8920) example_connect: Reconnecting...
W (11320) wifi: [ieee80211_ht.c,2036] new:<11,0>, old:<11,0>, ap:<255,255>, sta:<11,0>, prof:1
W (11320) wifi: [ieee80211_sta.c,204] state: init -> auth (b0)
W (11330) wifi: [ieee80211_sta.c,204] state: auth -> assoc (0)
W (11350) wifi: [ieee80211_sta.c,204] state: assoc -> run (10)
W (11380) wifi: [wl_cnx.c,3087] connected with <My SSID>, aid = 3, channel 11, BW20, bssid = ...
W (11380) wifi: [wl_cnx.c,3097] security: WPA2-PSK, phy: bgn, rssi: -52
My hypotheses:
1) an (implicit) WiFi scan or RF calibration interfering with connecting immediately after starting WiFi, or
2) some quirk of my router

My solution:
Upon receiving a WiFi disconnect event, start a timer to trigger a (new) connection attempt after a little while.

Re: WiFi always fails and then connects

Posted: Wed Jul 31, 2024 7:11 am
by AndreaS73
My solution:
Upon receiving a WiFi disconnect event, start a timer to trigger a (new) connection attempt after a little while.

Yeah, I'm doing the same, but it's an ugly workaround!
I'd like to understand why it fails and how to fix it.
I have other ESP32 boards, programmed using the Arduino framework, that connects at first try to the very same router.

I also tried to delay few seconds the `wifi_connect` after `wifi_init` but it changes nothing.

Re: WiFi always fails and then connects

Posted: Wed Jul 31, 2024 8:36 am
by eriksl
Here too.

But I am seeing it on the eso8266 as well..