Page 1 of 1

Mixing WiFi.begin() and esp_wifi_scan_start - help needed

Posted: Thu May 18, 2023 7:20 pm
by mzincali
Hi. I am trying to add more robustness in my WiFi connection code. I wanted to try WiFi.begin(), to see if the previously used SSID would connect. When that fails, I want to scan the network for SSIDs, then look to see which of those I have in a table of credentials, and then try to connect with WiFi.begin(savedSSID, savedPwd);

I'm sort of doing what WiFiMultii does, but WiFiMulti can't handle SSIDs that are "hidden".

I tried using WiFi.scanNetworks, but it too had some quirks and I eventually found that esp_wifi_scan_start is much more reliable.

The problem I have is that even though my new scan function works well when it is before a WiFi.begin(), but when it is after a WiFi.begin(), it still finds my networks, but it does not copy them in to my output struct. It returns a count for networks seen, but the number of items copied to my struct is zero.

Here is my code:

Code: Select all

void wifi_scan2(void) {
// Location 1

  esp_wifi_stop();
  esp_wifi_deinit();
  ESP_LOGE("try", "deinit");
  ESP_LOGE("scan", "1");

  esp_netif_t* sta_netif = esp_netif_get_handle_from_ifkey("WIFI_STA_DEF");
  if (!sta_netif) {
    sta_netif = esp_netif_create_default_wifi_sta();
  }

// I've already tried doing this
  //   esp_netif_t* netif = esp_netif_get_handle_from_ifkey("WIFI_STA_DEF");
  //   if (netif) {
  //       esp_netif_destroy(netif);
// in Location 1 above, and instead doing:
  //  esp_netif_t *sta_netif = esp_netif_create_default_wifi_sta();

  assert(sta_netif);
  ESP_LOGE("scan", "2");

  wifi_init_config_t cfg = WIFI_INIT_CONFIG_DEFAULT();
  ESP_ERROR_CHECK(esp_wifi_init(&cfg));
  ESP_LOGE("scan", "3");

  wifi_ap_record_t ap_info[DEFAULT_SCAN_LIST_SIZE];
  memset(ap_info, 0, sizeof(ap_info));

  ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
  ESP_ERROR_CHECK(esp_wifi_start());
  ESP_LOGE("scan", "4");

  wifi_scan_config_t scanConf = {.ssid = NULL,
                                 .bssid = NULL,
                                 .channel = 0,
                                 .show_hidden = false,
                                 .scan_type = WIFI_SCAN_TYPE_ACTIVE};
  scanConf.scan_time.active.max = 350;
  scanConf.scan_time.active.min = 150;

    uint16_t number = DEFAULT_SCAN_LIST_SIZE;
    uint16_t ap_count = 0;

    esp_wifi_scan_start(&scanConf, true);

    ESP_ERROR_CHECK(esp_wifi_scan_get_ap_records(&number, ap_info));
    ESP_ERROR_CHECK(esp_wifi_scan_get_ap_num(&ap_count));
    ESP_LOGI(TAG, "Total BSSIDs Seen = %u (%u)", ap_count, number);
  esp_wifi_stop();
  esp_wifi_deinit();
  esp_netif_destroy(sta_netif);

}
The results I see in the log are:
[ 3182][E][KiniNetworking.cpp:833] wifi_scan2(): [try] deinit
[ 3187][E][KiniNetworking.cpp:845] wifi_scan2(): [scan] 1
[ 3193][E][KiniNetworking.cpp:853] wifi_scan2(): [scan] 2
[ 3205][E][KiniNetworking.cpp:857] wifi_scan2(): [scan] 3
[ 3258][E][KiniNetworking.cpp:864] wifi_scan2(): [scan] 4
[ 6458][KiniNetworking.cpp:881] wifi_scan2(): [scan] Total BSSIDs Seen = 2 (2)


After I call WiFi.begin(), and then call wifi_scan2():


[ 8635][E][KiniNetworking.cpp:833] wifi_scan2(): [try] deinit
[ 8640][E][KiniNetworking.cpp:845] wifi_scan2(): [scan] 1
[ 8645][E][KiniNetworking.cpp:853] wifi_scan2(): [scan] 2
[ 8658][E][KiniNetworking.cpp:857] wifi_scan2(): [scan] 3
[ 8661][D][WiFiGeneric.cpp:931] _eventCallback(): Arduino Event: 2 - STA_START
[ 8663][E][KiniNetworking.cpp:864] wifi_scan2(): [scan] 4
[ 11605][D][WiFiGeneric.cpp:931] _eventCallback(): Arduino Event: 1 - SCAN_DONE
[ 11667][KiniNetworking.cpp:881] wifi_scan2(): [scan] Total BSSIDs Seen = 2 (0)


There is clearly some leftover WiFiSTA state stuff that I need to clear out, but I don't know what. Any ideas?

Here is my calling code:

Code: Select all


wifi_scan2();

  WiFi.disconnect(true);
  ESP_LOGE("start", "disconnect again");

  wl_status_t status = WiFi.begin();
  while (status != WL_CONNECT_FAILED) {
    delay(100);
    status = WiFi.status();
    if (status == WL_CONNECTED) {
      ESP_LOGI("start ---", "%s connected! status %d and IP %s", WiFi.SSID(),
               status, WiFi.localIP().toString().c_str());
      break;
    }
  }
  WiFi.disconnect(true);
  do {
    delay(100);
    status = WiFi.status();
    ESP_LOGI("start", "Waiting Disconnect status %d", status);
  } while (status != WL_NO_SHIELD && status != WL_IDLE_STATUS);

  wifi_scan2();
[ 3190][E][KiniNetworking.cpp:856] wifi_scan2(): [try] deinit
[ 3195][E][KiniNetworking.cpp:868] wifi_scan2(): [scan] 1
[ 3201][E][KiniNetworking.cpp:876] wifi_scan2(): [scan] 2
[ 3214][E][KiniNetworking.cpp:880] wifi_scan2(): [scan] 3
[ 3265][E][KiniNetworking.cpp:887] wifi_scan2(): [scan] 4
[ 6465][KiniNetworking.cpp:904] wifi_scan2(): [scan] Total BSSIDs Seen = 2 (2)
[ 6467][E][KiniNetworking.cpp:150] startNetwork(): [start] disconnect again
[ 6476][D][WiFiGeneric.cpp:931] _eventCallback(): Arduino Event: 0 - WIFI_READY
[ 6480][D][WiFiGeneric.cpp:931] _eventCallback(): Arduino Event: 2 - STA_START
[ 6535][D][WiFiGeneric.cpp:931] _eventCallback(): Arduino Event: 4 - STA_CONNECTED
[ 8505][D][WiFiGeneric.cpp:931] _eventCallback(): Arduino Event: 7 - STA_GOT_IP
[ 8505][D][WiFiGeneric.cpp:996] _eventCallback(): STA IP: 10.1.1.181, MASK: 255.255.255.0, GW: 10.1.1.1
[ 8587][KiniNetworking.cpp:158] startNetwork(): [start ---] McCormick connected! status 3 and IP 10.1.1.181
[ 8589][D][WiFiGeneric.cpp:931] _eventCallback(): Arduino Event: 5 - STA_DISCONNECTED
[ 8594][W][WiFiGeneric.cpp:955] _eventCallback(): Reason: 8 - ASSOC_LEAVE
[ 8602][D][WiFiGeneric.cpp:931] _eventCallback(): Arduino Event: 3 - STA_STOP
[ 8709][KiniNetworking.cpp:166] startNetwork(): [start] Waiting Disconnect status 255
E (8749) wifi_init: Failed to deinit Wi-Fi driver (0x3001)
[ 8712][E][KiniNetworking.cpp:856] wifi_scan2(): [try] deinit
[ 8717][E][KiniNetworking.cpp:868] wifi_scan2(): [scan] 1
[ 8722][E][KiniNetworking.cpp:876] wifi_scan2(): [scan] 2
[ 8734][E][KiniNetworking.cpp:880] wifi_scan2(): [scan] 3
[ 8737][D][WiFiGeneric.cpp:931] _eventCallback(): Arduino Event: 2 - STA_START
[ 8740][E][KiniNetworking.cpp:887] wifi_scan2(): [scan] 4
[ 11879][D][WiFiGeneric.cpp:931] _eventCallback(): Arduino Event: 1 - SCAN_DONE
[ 11944][KiniNetworking.cpp:904] wifi_scan2(): [scan] Total BSSIDs Seen = 2 (0)
[ 11945][D][WiFiGeneric.cpp:931] _eventCallback(): Arduino Event: 3 - STA_STOP


If I comment out the WiFi code:

Code: Select all


  wifi_scan2();

//   WiFi.disconnect(true);
//   ESP_LOGE("start", "disconnect again");

//   wl_status_t status = WiFi.begin();
//   while (status != WL_CONNECT_FAILED) {
//     delay(100);
//     status = WiFi.status();
//     if (status == WL_CONNECTED) {
//       ESP_LOGI("start ---", "%s connected! status %d and IP %s", WiFi.SSID(),
//                status, WiFi.localIP().toString().c_str());
//       break;
//     }
//   }
  wl_status_t status;
  WiFi.disconnect(true);
  do {
    delay(100);
    status = WiFi.status();
    ESP_LOGI("start", "Waiting Disconnect status %d", status);
  } while (status != WL_NO_SHIELD && status != WL_IDLE_STATUS);

  wifi_scan2();
The log:
[ 3190][E][KiniNetworking.cpp:857] wifi_scan2(): [try] deinit
[ 3196][E][KiniNetworking.cpp:869] wifi_scan2(): [scan] 1
[ 3201][E][KiniNetworking.cpp:877] wifi_scan2(): [scan] 2
[ 3214][E][KiniNetworking.cpp:881] wifi_scan2(): [scan] 3
[ 3265][E][KiniNetworking.cpp:888] wifi_scan2(): [scan] 4
[ 6466][KiniNetworking.cpp:905] wifi_scan2(): [scan] Total BSSIDs Seen = 2 (2)
[ 6567][KiniNetworking.cpp:167] startNetwork(): [start] Waiting Disconnect status 255
E (6607) wifi_init: Failed to deinit Wi-Fi driver (0x3001)
[ 6570][E][KiniNetworking.cpp:857] wifi_scan2(): [try] deinit
[ 6575][E][KiniNetworking.cpp:869] wifi_scan2(): [scan] 1
[ 6580][E][KiniNetworking.cpp:877] wifi_scan2(): [scan] 2
[ 6593][E][KiniNetworking.cpp:881] wifi_scan2(): [scan] 3
[ 6595][E][KiniNetworking.cpp:888] wifi_scan2(): [scan] 4
[ 9796][KiniNetworking.cpp:905] wifi_scan2(): [scan] Total BSSIDs Seen = 2 (2)

Re: Mixing WiFi.begin() and esp_wifi_scan_start - help needed

Posted: Thu May 18, 2023 8:02 pm
by boarchuz
It looks like the Arduino WiFi event handlers are still registered in the latter case, so the scan results are fetched (and cleared) in the SCAN_DONE event before you have a chance to grab them.

Maybe WiFi.stop() will do the trick for this problem, but you can probably expect more issues to appear with this approach. Is it worth migrating the WiFi connection handling out of Arduino too?

Re: Mixing WiFi.begin() and esp_wifi_scan_start - help needed

Posted: Thu May 18, 2023 8:33 pm
by mzincali
Is it worth migrating the WiFi connection handling out of Arduino too?
That is what I am thinking. Just wanted to make sure I'm not missing anything obvious.
It looks like the Arduino WiFi event handlers are still registered in the latter case, so the scan results are fetched (and cleared) in the SCAN_DONE event before you have a chance to grab them.
I'm not sure why scan results would be cleared by a handler. The handler should only notify a client that there's results and not actually do much more...

Re: Mixing WiFi.begin() and esp_wifi_scan_start - help needed

Posted: Thu May 18, 2023 8:39 pm
by boarchuz
mzincali wrote:
Thu May 18, 2023 8:33 pm
I'm not sure why scan results would be cleared by a handler
Not explicitly, but esp_wifi_scan_get_ap_records frees the records internally, ie. it can only be used once per SCAN_DONE.

Re: Mixing WiFi.begin() and esp_wifi_scan_start - help needed

Posted: Thu May 18, 2023 9:51 pm
by mzincali
Is there a WiFi.stop()? -- I don't seem to see it.

Re: Mixing WiFi.begin() and esp_wifi_scan_start - help needed

Posted: Thu May 18, 2023 10:17 pm
by boarchuz
Maybe .end()? Maybe not. I was only guessing sorry.