Code not go forward after "xEventGroupWaitBits"

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

Code not go forward after "xEventGroupWaitBits"

Postby alexandre » Wed Aug 16, 2023 5:51 pm

Hello makers! My code does not go forward after function

Code: Select all

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

Everything seems to be going well, the device receives an IP and is connected to WI-FI. The function runs, returns the log "I(30134) wifi:<ba-add>idx:1 (ifx:0, 24:fd:0d:9e:a2:3c), tid:6, ssn:2, winSize : 64" and nothing else happens. Code behavior is demonstrated in the video https://www.youtube.com/watch?v=_S8BSBYQnRI&t=1s

Added lines 366 and 380 to help with debugging.

Sorry, I'm newbie using esp-idf, I used to program with arduino framework.

ESP_Sprite
Posts: 9730
Joined: Thu Nov 26, 2015 4:08 am

Re: Code not go forward after "xEventGroupWaitBits"

Postby ESP_Sprite » Thu Aug 17, 2023 1:59 am

Well, to start with, do you have any function that sets those event group bits? If you don't, the task will never proceed past that.

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

Re: Code not go forward after "xEventGroupWaitBits"

Postby alexandre » Thu Aug 17, 2023 4:18 pm

ESP_Sprite wrote:
Thu Aug 17, 2023 1:59 am
Well, to start with, do you have any function that sets those event group bits? If you don't, the task will never proceed past that.
Hello ESP_Sprite! Thanks for the answer!

Yes, the bits are set in the function:

Code: Select all

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(s_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;
        ESP_LOGI(TAG, "WIFI_CONNECTED_BIT was successfully set");
        xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
    }
}
I used the wifi_station example from ESP-IDF itself as a base to develop my code.

See the video: https://www.youtube.com/watch?v=DpUyKtksRJU

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

Re: Code not go forward after "xEventGroupWaitBits"

Postby alexandre » Thu Aug 17, 2023 7:52 pm

alexandre wrote:
Thu Aug 17, 2023 4:18 pm
Hello ESP_Sprite! Thanks for the answer!

Yes, the bits are set in the function:

Code: Select all

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(s_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;
        ESP_LOGI(TAG, "WIFI_CONNECTED_BIT was successfully set");
        xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
    }
}
I used the wifi_station example from ESP-IDF itself as a base to develop my code.

See the video: https://www.youtube.com/watch?v=DpUyKtksRJU
I removed the function

Code: Select all

    EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group,
            WIFI_CONNECTED_BIT | WIFI_FAIL_BIT,
            pdFALSE,
            pdFALSE,
            portMAX_DELAY);
and adapted the code using the example https://docs.espressif.com/projects/esp ... TickType_t.

Apparently the WIFI_CONNECTED_BIT was successfully set, and the device received an IP.

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

Re: Code not go forward after "xEventGroupWaitBits"

Postby alexandre » Thu Aug 17, 2023 8:14 pm

Since the issue was not resolved, I made another change. The code needs to go to the switch and wait for the user to press the button. So I changed portMAX_DELAY by xTickToWait

Code: Select all

    const TickType_t xTicksToWait = 1000 / portTICK_PERIOD_MS;

    EventBits_t uxBits = xEventGroupWaitBits(s_wifi_event_group,
            WIFI_CONNECTED_BIT | WIFI_FAIL_BIT,
            pdFALSE,
            pdFALSE,
            xTicksToWait);
But for some reason, the condition

Code: Select all

if (uxBits & WIFI_CONNECTED_BIT)
is not satisfied.

The condition only became true after I removed uxBits

Code: Select all

if (WIFI_CONNECTED_BIT)
and so the condition becomes true for a moment and the code jumps forward, and then the code immediately goes back without the user having time to press the button, and finally it gets stuck in the while

Code: Select all

  while(1)
  {
    first_time = true;
    ESP_LOGI(TAG, "PRE EVENT");

    const TickType_t xTicksToWait = 1000 / portTICK_PERIOD_MS;

    EventBits_t uxBits = xEventGroupWaitBits(s_wifi_event_group,
            WIFI_CONNECTED_BIT | WIFI_FAIL_BIT,
            pdFALSE,
            pdFALSE,
            xTicksToWait);
   
    ESP_LOGI(TAG, "POST EVENT");
    /* xEventGroupWaitBits() returns the bits before the call returned, hence we can test which event actually
     * happened. */
printing to the screen, until it is reset:

"PRE EVENT"
"POST EVENT"

Shouldn't the code wait in the first case, until the user presses the button?

https://youtu.be/UGaTtB7im60

As you can see in the video, the code jumps to the first case and immediately returns to the while, is this right or am I crazy?

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

Re: Code not go forward after "xEventGroupWaitBits"

Postby MicroController » Fri Aug 18, 2023 5:13 pm

But for some reason, the condition... is not satisfied.
The reason is that xTicksToWait = 1000 / portTICK_PERIOD_MS causes txEventGroupWaitBits to time out and return after 1 second when no bits are set.

And you want to pass xClearOnExit as pdTRUE to the function, else the bits never get cleared and once a bit has been set all following iterations will immediately return the still set bits.

You are aware of the FreeRTOS documentation, right?
Last edited by MicroController on Sat Aug 19, 2023 8:57 am, edited 1 time in total.

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

Re: Code not go forward after "xEventGroupWaitBits"

Postby alexandre » Sat Aug 19, 2023 1:50 am

MicroController wrote:
Fri Aug 18, 2023 5:13 pm
But for some reason, the condition... is not satisfied.
The reason is that xTicksToWait = 1000 / portTICK_PERIOD_MS causes txEventGroupWaitBits to time out and return after 1 second when no even bits are set.

And you want to pass xClearOnExit as pdTRUE to the function, else the bits never get cleared and once a bit has been set all following iterations will immediately return the still set bits.

You are aware of the FreeRTOS documentation, right?
This is actually my first project using freeRTOS. I used ESP-IDF's own sample wifi station.

Even if I use a longer delay time "portMAX_DELAY", for example, the bits are not set correctly.

the original condition was

Code: Select all

if (uxBits & WIFI_CONNECTED_BIT)
and then the code never went any further, when I removed uxBits

Code: Select all

if (WIFI_CONNECTED_BIT)
the condition was met.

I'm sorry, but maybe I didn't understand the real usefulness of "uxBits".

All I need is for the code to step up to the switch and wait for the user to press the button. Any tips?

Code: Select all

    if (uxBits & WIFI_CONNECTED_BIT) {
      switch (current_status)
      {
        case STATUS_WAIT_USER_INPUT:
          if (primeira_vez == true) {
            ESP_LOGI(TAG, "ENTER SWITCH");
            sprintf(info, "PRESS BUTTON");
            lcdDrawString(&dev, fx24G, 6, 46, (uint8_t *) info, YELLOW);
            lcdDrawString(&dev, fx24G, 6, 76, (uint8_t *) info, YELLOW);
            primeira_vez = false;
          }
          if (gpio_get_level(BUTTON_INPUT) == 0) 
          {
            if (tickNumber == 50) {
              current_status = STATUS_REQUEST_QRCODE;
              last_id++;
              save_nvs_data(&nvs_handle, last_id);
              print_last_order(&dev, info, last_id);
            }
          } else {
            tickNumber = 0;
          }
          break;
I would like to wait until the user presses the button, at which point the status changes and the code moves on to the next case, and so on.
But the code enters the first case and then returns to the while loop.

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

Re: Code not go forward after "xEventGroupWaitBits"

Postby MicroController » Sat Aug 19, 2023 9:14 am

1. If your code doesn't progress to after xEventGroupWaitBits you need to double check that a) xEventGroupSetBits is actually called on the event group you're waiting on and b) xEventGroupSetBits actually sets at least one of the bits you give to xEventGroupWaitBits. In your case, the press of a button is supposed to set the "WIFI_CONNECTED_BIT"?

2. xEventGroupWaitBits returns when either one of two conditions are met: a) at least one of the event bits it is waiting on is set by a call to xEventGroupSetBits, or b) the maximum wait time you specify in ticksToWait elapses. The value returned by xEventGroupWaitBits contains the bit(s) which were set. In the first case, the value will have one or more of the bits you specified to wait on set. In the latter case, i.e. timeout, none of the bits you waited on are set in the returned value. (Or, if you pass xWaitForAllBits as pdTRUE, all bits specified need to be set in order for the wait condition to be satisfied.) So if you use a timeout value which is not portMAX_DELAY, you can check the returned value to distinguish between your bits being set and your bits not being set due to a timeout.

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

Re: Code not go forward after "xEventGroupWaitBits"

Postby alexandre » Sat Aug 19, 2023 2:41 pm

MicroController wrote:
Sat Aug 19, 2023 9:14 am
1. If your code doesn't progress to after xEventGroupWaitBits you need to double check that a) xEventGroupSetBits is actually called on the event group you're waiting on and b) xEventGroupSetBits actually sets at least one of the bits you give to xEventGroupWaitBits. In your case, the press of a button is supposed to set the "WIFI_CONNECTED_BIT"?

2. xEventGroupWaitBits returns when either one of two conditions are met: a) at least one of the event bits it is waiting on is set by a call to xEventGroupSetBits, or b) the maximum wait time you specify in ticksToWait elapses. The value returned by xEventGroupWaitBits contains the bit(s) which were set. In the first case, the value will have one or more of the bits you specified to wait on set. In the latter case, i.e. timeout, none of the bits you waited on are set in the returned value. (Or, if you pass xWaitForAllBits as pdTRUE, all bits specified need to be set in order for the wait condition to be satisfied.) So if you use a timeout value which is not portMAX_DELAY, you can check the returned value to distinguish between your bits being set and your bits not being set due to a timeout.
The function of the button is to wait until the user presses it, so that the code advances.

I am using wifi station example, the WIFI_CONNECTED_BIT bit is not set when connection is successful and WIFI_FAIL_BIT when connection fails?

My intention is to wait in the first case until the user presses the button. And as soon as the button is pressed, the value of current_status is updated so that the code proceeds to the next case, until all the steps are completed.

From the tests I did, everything indicates that the function is not returning.

This is the wifi driver implementation:

Code: Select all

#include "wifi_station.h"

static const char *TAG = "wifi station";

static int s_retry_num = 0;

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(s_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;
        ESP_LOGI(TAG, "WIFI_CONNECTED_BIT was successfully set");
        xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
    }
}

void wifi_init_sta(char* wifi_ssid, char* wifi_password)
{
    s_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 = { 
            /* Setting a password implies station will connect to all security modes including WEP/WPA.
             * However these modes are deprecated and not advisable to be used. Incase your Access point
             * doesn't support WPA2, these mode can be enabled by commenting below line */
	    .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.");
}

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

Re: Code not go forward after "xEventGroupWaitBits"

Postby alexandre » Wed Aug 23, 2023 12:30 am

Hello friends! My problem remains unresolved, so I decided to post it on espressif's github. To follow just follow the link: https://github.com/espressif/esp-idf/issues/12121

Who is online

Users browsing this forum: No registered users and 106 guests