Closed NoNullptr closed 7 months ago
Hi @NoNullptr Could you provide a little demo to reproduce this issue, then i can debug this issue locally.
I have made a little demo to illustrate the behavior. The demo deep-sleeps between connections and does the following:
I am getting about 117ms before using APSTA once and about 135ms after using APSTA once.
#include <esp_log.h>
#include <esp_netif.h>
#include <esp_sleep.h>
#include <esp_wifi.h>
#include <freertos/FreeRTOS.h>
#include <freertos/task.h>
#include <nvs_flash.h>
/* number of connections to ignore */
#define M 2
/* number of connections to time */
#define N 10
static int RTC_FAST_ATTR boot_num = 0;
static float RTC_FAST_ATTR timing_before = 0;
static float RTC_FAST_ATTR timing_after = 0;
static void wifi_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data)
{
ESP_ERROR_CHECK(esp_wifi_connect());
}
static void ip_event_handler(void *arg, esp_event_base_t event_base, int32_t event_id, void *event_data)
{
TickType_t t = xTaskGetTickCount() * (1000 / configTICK_RATE_HZ);
if (M <= boot_num && boot_num <= M + N - 1) {
timing_before += t;
printf("boot %d (before): %d\n", boot_num, t);
} else if (2 * M + N + 1 <= boot_num && boot_num <= 2 * M + 2 * N) {
timing_after += t;
printf("boot %d (after): %d\n", boot_num, t);
} else {
printf("boot %d (ignored): %d\n", boot_num, t);
}
}
static wifi_config_t wifi_config_ap = {
.ap = {
.authmode = WIFI_AUTH_WPA2_PSK,
.pairwise_cipher = WIFI_CIPHER_TYPE_CCMP,
.ssid = "esp32ap",
.ssid_hidden = 0,
.ssid_len = 0,
.password = "esp32pwd",
},
};
static wifi_config_t wifi_config_sta = {
.sta = {
.ssid = "",
.password = "",
}
};
static void erase_nvs_net80211()
{
nvs_handle_t handle;
nvs_entry_info_t info;
nvs_iterator_t it;
esp_err_t rc;
ESP_ERROR_CHECK(nvs_open("nvs.net80211", NVS_READWRITE, &handle));
it = nvs_entry_find("nvs", "nvs.net80211", NVS_TYPE_ANY);
while (it != NULL) {
nvs_entry_info(it, &info);
rc = nvs_erase_key(handle, info.key);
if (rc != ESP_OK && rc != ESP_ERR_NVS_NOT_FOUND) {
ESP_ERROR_CHECK(rc);
}
it = nvs_entry_next(it);
}
ESP_ERROR_CHECK(nvs_commit(handle));
nvs_close(handle);
}
void app_main()
{
ESP_ERROR_CHECK(nvs_flash_init());
if (boot_num == 0) {
erase_nvs_net80211();
}
ESP_ERROR_CHECK(esp_netif_init());
ESP_ERROR_CHECK(esp_event_loop_create_default());
esp_netif_create_default_wifi_sta();
if (boot_num == 1 + N) {
esp_netif_create_default_wifi_ap();
}
wifi_init_config_t wifi_init_config = WIFI_INIT_CONFIG_DEFAULT();
ESP_ERROR_CHECK(esp_wifi_init(&wifi_init_config));
esp_event_handler_instance_t instance_wifi;
esp_event_handler_instance_t instance_ip;
ESP_ERROR_CHECK(esp_event_handler_instance_register(WIFI_EVENT, WIFI_EVENT_STA_START, &wifi_event_handler, NULL, &instance_wifi));
ESP_ERROR_CHECK(esp_event_handler_instance_register(IP_EVENT, IP_EVENT_STA_GOT_IP, &ip_event_handler, NULL, &instance_ip));
if (boot_num == M + N) {
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_APSTA));
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_AP, &wifi_config_ap));
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config_sta));
} else {
ESP_ERROR_CHECK(esp_wifi_set_mode(WIFI_MODE_STA));
ESP_ERROR_CHECK(esp_wifi_set_config(WIFI_IF_STA, &wifi_config_sta));
}
ESP_ERROR_CHECK(esp_wifi_start());
vTaskDelay(pdMS_TO_TICKS(3000));
if (++boot_num <= 2 * M + 2 * N) {
esp_deep_sleep(1000000);
} else {
printf("average connection time before using AP: %.2f\n", timing_before / N);
printf("average connection time after using AP: %.2f\n", timing_after / N);
}
}
Hi @NoNullptr For the robustness of the program, erase_nvs_net80211() is not recommended to use. Using erase_nvs_net80211() may cause some nvs.net80211 keys to be lost.
Hi @NoNullptr For the robustness of the program, erase_nvs_net80211() is not recommended to use. Using erase_nvs_net80211() may cause some nvs.net80211 keys to be lost.
It is a demo specifically illustrating the issue; it won't cause "some" keys to be lost, it will erase all of them. If you prefer to manually erase NVS instead of programmatically doing so, then you can do comment out the offending line and use idf.py erase-flash
.
Hi @NoNullptr It is also feasible if erase some keys does not introduce problems. You demo illustrating that erase some keys can reduce connect time.
@mhdong Please go ahead and test it after erasing flash and not calling erase_nvs_net80211(). The results are the same and you should have already tested that anyways.
The issue seems to be that connecting to AP writes persistent values to NVS, which are not removed later. These values seem to slow down future connections even when one doesn't use AP. Since the code reading the NVS is not open sourced, there is no way for me to pinpoint the exact problem.
Thanks for reporting, feel free to reopen.
In which commit is it fixed?
I am deeply sorry for my late reply. As reply at https://github.com/espressif/esp-idf/issues/9909#issuecomment-1305321729, we will not erase all key about AP, even if the mode is set to STA. We can provide example to demonstrate how to erase these keys manually. We'd appreciate you providing relevant examples by pull request.
@mhdong, the reason given in #9909 is to reboot faster, which is not even a valid response to #9909 since it adds keys that do not even exist in the documented code. With the code I already gave in this bug report, you can check that it not only slows down new connections, it also slows down booting. This makes the reasoning given in #9909 invalid.
Hello,
I have a bug that I think is related to this one.
When I use scanNetworks() in STA mode, ok, esp32 as wifi client is ok
When I use scanNetworks() in AP mode, esp32 as wifi server will every time screw the client connected to it.
As soon as scanNetworks() starts, the client connected to the ESP32(in AP mode) lost connectivity. Easy to watch with a continuous ping.
Why scanNetworks() in AP mode ??
Well, the only way to configure a fresh ESP32 device is to login with known credential From the configure page, I want to help customer join my gadget to his wifi network. here comes the scan networks to display SSID available to him.
After random delay, the client can (not often) recover the wifi link and receive the server response. But most of the time, no way to have reliable server/client link.
I can open a specific bug if this behavior is not a hint to this one.
sorry for my late reply @Franck78 do the scanNetworks() means esp_wifi_scan_start()? esp_wifi_scan_start() only work in sta or sta/softap coexistence mode or could you provide some examples about it thank for you report!
Thanks for reporting, will close due to short of feedback, feel free to reopen with more updates. Thanks for using our Espressif product!
Answers checklist.
IDF version.
v4.4.2
Operating System used.
macOS
How did you build your project?
Command line with idf.py
If you are using Windows, please specify command line type.
No response
Development Kit.
ESP32-S3-MINI-1
Power Supply used.
USB
What is the expected behavior?
After using SoftAP for provisioning or other purposes (WIFI_MODE_AP or WIFI_MODE_APSTA), and then switching to WIFI_MODE_STA does not leave remnant configuration of the SoftAP mode, in particular, the STA initialization/connection performance is not impacted by having used AP-mode in the past.
What is the actual behavior?
Using the SoftAP-mode just once stores configuration on NVS, which are left behind when mode is switched to STA-only. Performance measurement indicates that these NVS-keys take up to 20ms when initialising and connecting wifi, even when SoftAP-mode is never used again.
Steps to reproduce.
Compare startup time between 1. and 3. step.
Debug Logs.
No response
More Information.
Performance can be recovered by deleting all AP-related keys from nvs.net80211