Failed to check if wifi was connected

alexandre
Posts: 10
Joined: Sun Aug 13, 2023 2:43 pm

Failed to check if wifi was connected

Postby alexandre » Tue Jan 09, 2024 10:09 pm

Hello friends, how are you? I can't check if the wifi is connected, even though it is connected. My main routine is basically:

Code: Select all

void app_main(void)
{
// initialization SPIFFS
// initialization NVS

wifi_event_group = xEventGroupCreate();

ESP_LOGI(TAG, "ESP_WIFI_MODE_STA");
wifi_init_sta(wifi_ssid, wifi_password);

while (1) 
{

vTaskDelay(10 / portTICK_PERIOD_MS);

EventBits_t bits = xEventGroupWaitBits(wifi_event_group,
                           WIFI_CONNECTED_BIT | WIFI_FAIL_BIT,
                           pdFALSE,
                           pdFALSE,
                           portMAX_DELAY);

if (bits & WIFI_CONNECTED_BIT)
{
// if wifi is connected, the code should run normally

} else If  (bits & WIFI_FAIL_BITS) {

//reconnection attempt
}
}
}

However, even though the Wi-Fi is connecting successfully and the bit is set successfully, somehow the xEventGroupWaitBits function is not returning and the code does not move forward.

Another curious thing is that it was necessary to create the event (wifi_event_group = xEventGroupCreate();) in both the wifi.c and main.c components. In the github examples, the event is only created in main.c. But in my case, if the event is not created in both files, I get the error:

Code: Select all

assert failed: xEventGroupWaitBits event_groups.c:344 (xEventGroup)


Backtrace: 0x40081afa:0x3ffbb230 0x400899bd:0x3ffbb250 0x40090f49:0x3ffbb270 0x4008d19f:0x3ffbb390 0x400d75a1:0x3ffbb3c0 0x4016ec28:0x3ffbb420 0x4008c3e5:0x3ffbb440
0x40081afa: panic_abort at C:/Users/morei/esp/esp-idf/components/esp_system/panic.c:452

0x400899bd: esp_system_abort at C:/Users/morei/esp/esp-idf/components/esp_system/port/esp_system_chip.c:84

0x40090f49: __assert_func at C:/Users/morei/esp/esp-idf/components/newlib/assert.c:81

0x4008d19f: xEventGroupWaitBits at C:/Users/morei/esp/esp-idf/components/freertos/FreeRTOS-Kernel/event_groups.c:344 (discriminator 1)

0x400d75a1: app_main at C:/esprojects/uart_events_mod2/main/uart_events_example_main.c:497 (discriminator 13)

0x4016ec28: main_task at C:/Users/morei/esp/esp-idf/components/freertos/app_startup.c:208

0x4008c3e5: vPortTaskWrapper at C:/Users/morei/esp/esp-idf/components/freertos/FreeRTOS-Kernel/portable/xtensa/port.c:162





ELF file SHA256: ae410852a7760135

Rebooting...
I tried another alternative to check if the wifi was connected successfully using semaphores:

Code: Select all

SemaphoreHandle_t conexaoWifiSemaphore = NULL;

void app_main(void)
{
// initialization SPIFFS
// initialization NVS

  conexaoWifiSemaphore = xSemaphoreCreateBinary();

  if (conexaoWifiSemaphore == NULL)
  {
    // Lidar com erro na criação do semáforo
    while (1)
    {
      ESP_LOGI(TAG, "Erro na inicialização do semaphoro.");
    }
  }
  
wifi_event_group = xEventGroupCreate();

ESP_LOGI(TAG, "ESP_WIFI_MODE_STA");
wifi_init_sta(wifi_ssid, wifi_password);

while (1) 
{

vTaskDelay(10 / portTICK_PERIOD_MS);


if (xSemaphoreTake(conexaoWifiSemaphore, pdMS_TO_TICKS(10000)) == pdTRUE));
{
// if wifi is connected, the code should run normally

} else  {

//reconnection attempt
}
}
}
/* In the wifi.c file:
 *the semaphore was declared: extern SemaphoreHandle_t conexaoWifiSemaphore;
 **after successful connection, the semaphore was released: xSemaphoreGive(conexaoWifiSemaphore);
Even after releasing the semaphore, it is not possible to acquire it in the main loop with the function:

Code: Select all

xSemaphoreTake(conexaoWifiSemaphore, pdMS_TO_TICKS(10000)) == pdTRUE)
I also used the function:

Code: Select all

int semaphore value = uxSemaphoreGetCount(conexaoWifiSemaphore);
ESP_LOGI(TAG, "Semaphore value in main: %d", semaphore value);
and when analyzing the value of the semaphore I realized that it has different values ​​in the scope of the wifi component and in the scope of the app_main() function, as if they were not the same thing.

This is the structure of my project:

dir - .vscode

- build

- components - http_client
- wifi_station
- sdcard

- main - CMakeLists.txt
- Kconfig.projbuild
- main.c

- sdkconfig

The code has no logic errors, it was copied from examples and checked several times. I even made HTTPS requests and it worked fine.

In short, I need to ensure that the code only progresses if the Wi-Fi is connected and if the connection is lost, wait until it resumes.

I tried to be as clear and objective as possible. Any suggestions on how to solve this "problem"?

MicroController
Posts: 1708
Joined: Mon Oct 17, 2022 7:38 pm
Location: Europe, Germany

Re: Failed to check if wifi was connected

Postby MicroController » Wed Jan 10, 2024 9:13 am

I need to ensure that the code only progresses if the Wi-Fi is connected
https://docs.espressif.com/projects/esp ... ming-model
The WiFi stack uses the default event loop to publish events like DISCONNECT or GOT_IP to the application. If you want to react to these events, you have to implement and register an event handler. As seen in the examples, this event handler can then set bits in an event group or use any other means to notify other tasks. Your code does not seem to have an event handler, so you won't receive any events from the WiFi stack.

alexandre
Posts: 10
Joined: Sun Aug 13, 2023 2:43 pm

Re: Failed to check if wifi was connected

Postby alexandre » Wed Jan 10, 2024 1:37 pm

MicroController wrote:
Wed Jan 10, 2024 9:13 am
I need to ensure that the code only progresses if the Wi-Fi is connected
https://docs.espressif.com/projects/esp ... ming-model
The WiFi stack uses the default event loop to publish events like DISCONNECT or GOT_IP to the application. If you want to react to these events, you have to implement and register an event handler. As seen in the examples, this event handler can then set bits in an event group or use any other means to notify other tasks. Your code does not seem to have an event handler, so you won't receive any events from the WiFi stack.
The event handler is in the wifi component:

wifi_station.c

Code: Select all

#include "wifi_station.h"

static const char *TAG = "wifi station";

static int s_retry_num = 0;

extern SemaphoreHandle_t conexaoWifiSemaphore;


static void event_handler(void* arg, esp_event_base_t event_base,
                                int32_t event_id, void* event_data)
{
    if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_START) {
        esp_wifi_connect();
    } else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) {
        if (s_retry_num < EXAMPLE_ESP_MAXIMUM_RETRY) {
            esp_wifi_connect();
            s_retry_num++;
            ESP_LOGI(TAG, "retry to connect to the AP");
        } else {
            xEventGroupSetBits(wifi_event_group, WIFI_FAIL_BIT);
            ESP_LOGI(TAG, "WIFI_FAIL_BIT was successfully set");
        }
        ESP_LOGI(TAG,"connect to the AP fail");
    } else 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(TAG, "got ip:" IPSTR, IP2STR(&event->ip_info.ip));
        s_retry_num = 0;
        xEventGroupSetBits(wifi_event_group, WIFI_CONNECTED_BIT);
        ESP_LOGI(TAG, "WIFI_CONNECTED_BIT was successfully set");

        int initial = uxSemaphoreGetCount(conexaoWifiSemaphore);
        ESP_LOGI(TAG, "Initial value of the semaphore: %d", initial);
        
        xSemaphoreGive(conexaoWifiSemaphore);
        
        int final = uxSemaphoreGetCount(conexaoWifiSemaphore);
        ESP_LOGI(TAG, "Final value of the semaphore: %d", final);
      
    }
}


void wifi_init_sta(char *wifi_ssid, char *wifi_password)
{
    wifi_event_group = xEventGroupCreate();

    ESP_ERROR_CHECK(esp_netif_init());

    ESP_ERROR_CHECK(esp_event_loop_create_default());

    esp_netif_create_default_wifi_sta();

    
    wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();

    ESP_ERROR_CHECK(esp_wifi_init(&cfg));

    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 = {
        
            .threshold.authmode = WIFI_AUTH_WPA2_PSK,
            
            .pmf_cfg = {
                .capable = true,  
                .required = false 
            },
        },
    };


    strcpy((char *)wifi_config.sta.ssid, (char *)wifi_ssid);         
    strcpy((char *)wifi_config.sta.password, (char *)wifi_password); 

    ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));

    ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config));

    ESP_ERROR_CHECK(esp_wifi_start());

    ESP_LOGI(TAG, "wifi_init_sta finished.");

    EventBits_t bits = xEventGroupWaitBits(wifi_event_group,
                                           WIFI_CONNECTED_BIT | WIFI_FAIL_BIT,
                                           pdFALSE,
                                           pdFALSE,
                                           portMAX_DELAY);

    /* xEventGroupWaitBits() returns the bits before the call returned, hence we can test which event actually
     * happened. */
    if (bits & WIFI_CONNECTED_BIT)
    {
        ESP_LOGI(TAG, "connected to ap SSID:%s password:%s",
                 EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS);
    }
    else if (bits & WIFI_FAIL_BIT)
    {
        ESP_LOGI(TAG, "Failed to connect to SSID:%s, password:%s",
                 EXAMPLE_ESP_WIFI_SSID, EXAMPLE_ESP_WIFI_PASS);
    }
    else
    {
        ESP_LOGE(TAG, "UNEXPECTED EVENT");
    }
}
wifi_station.h

Code: Select all


#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/event_groups.h"
#include "esp_system.h"
#include "esp_wifi.h"
#include "esp_event.h"
#include "esp_log.h"
#include "nvs_flash.h"

#include "lwip/err.h"
#include "lwip/sys.h"

#define EXAMPLE_ESP_WIFI_SSID      "Wifi"
#define EXAMPLE_ESP_WIFI_PASS      "######"
#define EXAMPLE_ESP_MAXIMUM_RETRY  CONFIG_ESP_MAXIMUM_RETRY

#define WIFI_CONNECTED_BIT BIT0 
#define WIFI_FAIL_BIT      BIT1

static EventGroupHandle_t wifi_event_group;

void wifi_init_sta(char* wifi_ssid, char* wifi_password);

As you can see, I tried to notify the other tasks via semaphore. It is released right after the WiFi connection. But for some reason its value is different in the scope of the wifi component and app_main().

The strangest thing is that the wifi connects and it is possible to make requests.

alexandre
Posts: 10
Joined: Sun Aug 13, 2023 2:43 pm

Re: Failed to check if wifi was connected

Postby alexandre » Thu Jan 11, 2024 2:51 pm

I created a function in wifi.c that receives a pointer. The pointer would work like a traffic light and, if there was a WiFi connection, its value would change to 1.
The function was called in the main function app_main(), which passes the address of the pointer. But for some reason the function is not recognized in main.c.

My guess is that the problem is with component linking. The strange thing is that the wifi connects normally, I just can't check if there was a connection.

I migrated all the components to the main directory because I thought the problem was with the linking of the components. Unfortunately the problem continues. The next step will be to reinstall IDF and all dependencies.

MicroController
Posts: 1708
Joined: Mon Oct 17, 2022 7:38 pm
Location: Europe, Germany

Re: Failed to check if wifi was connected

Postby MicroController » Thu Jan 11, 2024 9:40 pm

You're running into problems trying to share variables between multiple source files, see e.g. https://stackoverflow.com/a/71601939

Code: Select all

static EventGroupHandle_t wifi_event_group;
A static variable in a .h file is almost never what you want.
Generally, you should avoid sharing global variables; this coding pattern is frowned upon for several good reasons.

Who is online

Users browsing this forum: Majestic-12 [Bot] and 127 guests