Reconnect Issue in station_example_main.c - working with an added loop

GvTardy
Posts: 23
Joined: Tue Jan 01, 2019 3:26 pm

Reconnect Issue in station_example_main.c - working with an added loop

Postby GvTardy » Mon Dec 27, 2021 12:06 pm

Hi to everybody,

I tried to run the ESP32's WIFI in station mode, trying the IDF example as a starter.

I seem to work fine but would not reconnect after reset of the access-point (windows 10 or mobile phone).

Checking the code I found that the services get unregistered right after a connect or time-out while trying to connect.

By adding an infinite loop, the problem gets solved, see the code snippet below, taken from the "station_example_mail.c" out of the routine

Code: Select all


int sta_retry_num = 0;
EventGroupHandle_t sta_wifi_event_group;

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

    // patched up event handler ...

    if (event_base == WIFI_EVENT)
    
    switch (event_id){
        case WIFI_EVENT_STA_START: 
            esp_wifi_connect(); 
            ESP_LOGI("WIFI_STA", "connecting to AP...");
            break;
        case WIFI_EVENT_STA_CONNECTED:
            ESP_LOGI("WIFI_STA", "connectes to AP");
            break;
        case WIFI_EVENT_STA_DISCONNECTED:
            xEventGroupClearBits(sta_wifi_event_group, WIFI_CONNECTED_BIT);
            if (sta_retry_num < ESP_MAXIMUM_RETRY) {
                esp_wifi_connect();
                sta_retry_num++;
                ESP_LOGI("WIFI_STA", "retry to connect to AP");
            } else {
                xEventGroupSetBits(sta_wifi_event_group, WIFI_FAIL_BIT);
                ESP_LOGI("WIFI_STA", "could not connect to AP");
            };
            break;
        default:
            ESP_LOGI("WIFI_STA", "unhandled WITI event: ID=%u",event_id);
        } 

        if (event_base == IP_EVENT && event_id == IP_EVENT_STA_GOT_IP) {
            ip_event_got_ip_t* event = (ip_event_got_ip_t*) event_data;
            ESP_LOGI("WIFI_STA", "got ip:" IPSTR, IP2STR(&event->ip_info.ip));
            sta_retry_num = 0;
            xEventGroupSetBits(sta_wifi_event_group, WIFI_CONNECTED_BIT);
            xEventGroupClearBits(sta_wifi_event_group, WIFI_FAIL_BIT);
        } 
}

    esp_err_t WIFI_STA_init(void)
    {
        //Create an event group
        sta_wifi_event_group = xEventGroupCreate();

        ESP_ERROR_CHECK(esp_netif_init());
        ESP_ERROR_CHECK(esp_event_loop_create_default());
        esp_netif_t *sta_netif = esp_netif_create_default_wifi_sta();
        assert(sta_netif);

        wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
        ESP_ERROR_CHECK(esp_wifi_init(&cfg));

        //Registration event handling service
        esp_event_handler_instance_t instance_any_id;
        esp_event_handler_instance_t instance_got_ip;
        ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler,
                                                            NULL, &instance_any_id));
        ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler,
                                                            NULL, &instance_got_ip));

        wifi_config_t wifi_config = {
            .sta = {
                .ssid = ESP_WIFI_SSID,
                .password = ESP_WIFI_PASS,
                //Equipment from the AP listener sign
                .listen_interval = DEFAULT_LISTEN_INTERVAL, 
                //Setting your password means that the device will connect all security modes, including WEP, WPA. However, these patterns are not recommended, if your access point does not support WPA2, comment to enable other modes
                .threshold.authmode = WIFI_AUTH_WPA2_PSK,

                .pmf_cfg = {
                    .capable = true,
                    .required = false
                },
            },
        };

        ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA) );
        ESP_ERROR_CHECK(esp_wifi_set_config(ESP_IF_WIFI_STA, &wifi_config) );
        ESP_ERROR_CHECK(esp_wifi_start() );
        ESP_LOGI("WIFI_STA", "esp_wifi_set_ps().");
        esp_wifi_set_ps(DEFAULT_PS_MODE);
        ESP_LOGI("WIFI_STA", "wifi_init_sta finished.");

	// While loops keeps event handler alive ********************************************************
        while(1){
            bits = xEventGroupWaitBits(sta_wifi_event_group, WIFI_CONNECTED_BIT | WIFI_FAIL_BIT,
                                       pdFALSE, pdFALSE, portMAX_DELAY);

            if (bits & WIFI_FAIL_BIT) {
                ESP_LOGI("WIFI_STA", "Failed to connect, restarting station");
                ESP_ERROR_CHECK(esp_wifi_stop());
                vTaskDelay(1000 / portTICK_PERIOD_MS);
                ESP_ERROR_CHECK(esp_wifi_start());
            };
        
            vTaskDelay(10000 / portTICK_PERIOD_MS);
        };

        // Should never reach here, unless you terminate the while loop to end event_handling....
        
        ESP_ERROR_CHECK(esp_event_handler_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, &event_handler));
        ESP_ERROR_CHECK(esp_event_handler_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, &event_handler));
        vEventGroupDelete(sta_wifi_event_group);

        return ESP_OK;
    }
Hope it helps someone. Maybe there is an even better way to establish reconnect, if so, please add a replay.

Greetings and merry Christmas
Georg

Who is online

Users browsing this forum: No registered users and 27 guests