blocking code not blocking

mtraven
Posts: 28
Joined: Thu Jul 07, 2022 3:34 am

blocking code not blocking

Postby mtraven » Tue Apr 09, 2024 9:26 pm

foreword: I dont know if I come across as a programmer, or an idiot...but I'm not a programmer :D . I'm a farmer. please keep that in mind. Please know that, although I might make a lot of threads, I dont clutter things up lightly. Its only after countless hours of trying & reading on my own that I reach out.

lets start with the conceptual:
scenario A:
DO_OTA() - connects to wifi AP (init everything for wifi station, waits while connecting)
- OTA UPDATE() -checks HTTPS page for updated firmware, if found, transfers new FW, restarts on alt partition
-if nothing new, or not found,failed to connect, other failure: resumes normal program


if I run my wifi init & connect methods from the start of the program, the whole process works as intended.
Scenario B: In practice, the "normal program" runs ESP NOW. When I initiate & configure espNow to run first, then stop it to check for an OTA update, the blocking code that holds the program while wifi connects, fails. It just plows into the OTA update, which fails because there is no connection. 5-10 seconds later, the wifi hooks(so the reconfig of wifi is ~right?), but the OTA has already failed.

I've considered some work around to lock it out of the OTA task, until wifi is connected, something about that makes me un-easy.

I'd rather understand why it is the exact same method calls, start wifi with & without the block.

to compound my problems, advancing my Log level past "info", causes a bunch of compile errors relating to "pthreads". So I cant see the verbose logs to see what might be different in the two scenarios. Thats 1st on my list tonight, but any guidance would be great!

Not sure what code yall will want to see, and this point is a mess. so I'll start with the wifi event handler & wifi init below. They are largely based on the IDF5.2 Note that iv'e listed the "full init", I've been playing with various combinations of shutting down the wifi & then restarting the appropriate parts. Best I've gotten is a full shut down (killWifi() seen below), and full restart. After typing this, I realize thats awfully "brute forcish", so I'm open to a gentler way was transitioning from ESP NOW to wifi (and back).

Code: Select all

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();
        printf("eventhandler case 1:TX power: %i\n", getTxPower());
    } 
    else if (event_base == WIFI_EVENT && event_id == WIFI_EVENT_STA_DISCONNECTED) 
    {
        if (s_retry_num < MAXIMUM_RETRY) 
        {
            esp_wifi_connect();
            s_retry_num++;
            ESP_LOGW(TAG_wifi, "\n\n----------------------\n connect retry #%i \n------------------\n", s_retry_num);
        } 
        else 
        {
            xEventGroupSetBits(s_wifi_event_group, WIFI_FAIL_BIT);
        }
        ESP_LOGI(TAG_wifi,"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_wifi, "got ip:" IPSTR, IP2STR(&event->ip_info.ip));
        s_retry_num = 0;
        xEventGroupSetBits(s_wifi_event_group, WIFI_CONNECTED_BIT);
    }
}
WIFI INIT

Code: Select all

void wifi_init_sta(void)
{
    ESP_LOGW("wifiInit", "initiating wifi...");
    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 = {
                .ssid = SSID,
                .password = WIFI_PASS,
                /*.threshold.authmode = ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD,*/ //C++ says no
                .sae_pwe_h2e = wifi_sae_pwe_method_t(WPA3_SAE_PWE_BOTH),
                .sae_h2e_identifier = "",
                },
    };
    wifi_config.sta.threshold.authmode=ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD; //wont allow this(inC++) in init above ^^
    ESP_LOGI("wifi_init:", "authorization mode: %i", (uint8_t)wifi_config.sta.threshold.authmode); //ensure auth mode is being set
    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, "wifi_init_sta finished.");
    /* Waiting until either the connection is established (WIFI_CONNECTED_BIT) or connection failed for the maximum
     * number of re-tries (WIFI_FAIL_BIT). The bits are set by event_handler() (see above) */
    EventBits_t bits = xEventGroupWaitBits(s_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_wifi, "connected to ap SSID:%s password:%s",SSID, WIFI_PASS);
    else if (bits & WIFI_FAIL_BIT) 
        ESP_LOGI(TAG_wifi, "Failed to connect to SSID:%s, password:%s",SSID, WIFI_PASS);
    else 
        ESP_LOGE(TAG_wifi, "UNEXPECTED EVENT");
    /* The event will not be processed after unregister */
    ESP_ERROR_CHECK(esp_event_handler_instance_unregister(IP_EVENT, IP_EVENT_STA_GOT_IP, instance_got_ip));
    ESP_ERROR_CHECK(esp_event_handler_instance_unregister(WIFI_EVENT, ESP_EVENT_ANY_ID, instance_any_id));
    vEventGroupDelete(s_wifi_event_group);
}

Code: Select all

void killWifi()
{
    (esp_wifi_disconnect());
    (esp_wifi_stop());
    (esp_wifi_deinit()); //shut down wifi once update it complete
    (esp_event_loop_delete_default());
    (esp_netif_deinit());
 }

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

Re: blocking code not blocking

Postby MicroController » Tue Apr 09, 2024 10:32 pm

I'm not a programmer :D
You sure about that? ;-)
I'd say the vast majority of people here are hobbyists. And to me, the great level of work, learning, and understanding you put into things before asking here very much comes across. - This despite your day-time job already being the most important profession there is!
I encourage you to keep asking, even for little things for which you might need a quick answer or clarification to complete the bigger puzzle.

Btw,

Code: Select all

/*.threshold.authmode = ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD,*/ //C++ says no
yeah, C++ "prefers" you write

Code: Select all

.threshold = {
  .authmode = ESP_WIFI_SCAN_AUTH_MODE_THRESHOLD
 }
Moreover, viewtopic.php?t=22865 says that WiFi and ESP-NOW should be usable at the same time, which could avoid any problems you have now with 'switching over' between ESP-NOW and WiFi.

mtraven
Posts: 28
Joined: Thu Jul 07, 2022 3:34 am

Re: blocking code not blocking

Postby mtraven » Wed Apr 10, 2024 2:08 am

hey thanks! for the encouraging words & the proper syntax on the initializer, you saw my work around, which worked, but annoyed me!

I've gone back & forth on trying to run wifi & espnow together, I probably should at least try it...but I'll still need to disconnect, I have no other need for wifi in the system and I dont need the battery drain, or the security risk associated with being connected to my network.

I just figured out how to get my verbose log running, so I'm gonna take a deep dive into the logs, see if I cant find a difference. I also want to read through that thread you gave me on running them together. Even if I opt to not, there may very well be something in there that helps me!.

mtraven
Posts: 28
Joined: Thu Jul 07, 2022 3:34 am

Re: blocking code not blocking

Postby mtraven » Thu Apr 11, 2024 7:49 pm

well I found my monumentally stupid mistake: I had made a copy of the wifi init method and renamed it "restart" -- I figured the restart might need different things than the first start. Well I missed copying the "waiting bits" part of the method, which is what blocked the program while wifi connected. After that, just had to figure out I needed to re-register the espnow peers and now, everything seems in order. I am able to switch between esp-now & wifi and back without issue.

I did read the thread about running them together...in fact, I've read many threads like that. Honestly, I'm dubious....and I've yet to see any actual working example of simultaneous wifi & epsnow on one module. The major impediment I ran into was, the event loop. I think both wifi & espnow would need their own event loop...the only way I know how to do that is create_event_loop_default(), and you can only make 1 of those. I know create_even_loop() is a way of making more even loops, but I haven't worked out how to use that yet....and since I dont need to, I probably wont.

Who is online

Users browsing this forum: No registered users and 57 guests