Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion boards/seed_studio/xiao_esp32s3
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,16 @@ CONFIG_IDF_TARGET="esp32s3"
CONFIG_IDF_TARGET_ESP32S3=y
CONFIG_LED_DEBUG_GPIO=21
CONFIG_ESPTOOLPY_FLASHSIZE_8MB=y
CONFIG_ESP32S3_DEFAULT_CPU_FREQ_240=y
# CPU at 160MHz instead of the 240MHz in sdkconfig.base_defaults, to cut heat.
# ESP_DEFAULT_CPU_FREQ_MHZ* are the authoritative symbols; the ESP32S3_* names are legacy
# aliases. switchBoardType.py merges base and board configs by exact key, so the 240 entries
# have to be turned off explicitly here - omitting them just leaves the base values in place.
CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=n
CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_160=y
CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ=160
CONFIG_ESP32S3_DEFAULT_CPU_FREQ_240=n
CONFIG_ESP32S3_DEFAULT_CPU_FREQ_160=y
CONFIG_ESP32S3_DEFAULT_CPU_FREQ_MHZ=160
CONFIG_ESP32S3_SPIRAM_SUPPORT=y
CONFIG_SPIRAM_MODE_OCT=y
# CONFIG_ESPTOOLPY_FLASHSIZE_1MB is not set
Expand Down
12 changes: 11 additions & 1 deletion components/CameraManager/CameraManager/CameraManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,19 @@ void CameraManager::setupCameraPinout()
ESP_LOGI(CAMERA_MANAGER_TAG, "CAM_BOARD");
#endif
#if CONFIG_GENERAL_INCLUDE_UVC_MODE
xclk_freq_hz = CONFIG_CAMERA_USB_XCLK_FREQ;
// Pick the clock from the mode the device will actually run in, not from whether UVC
// support happens to be compiled in. Choosing at compile time meant every build with
// UVC enabled ran the sensor at the USB clock even in WiFi mode, which left
// CAMERA_WIFI_XCLK_FREQ dead. Mode is loaded before streaming starts, and switching
// modes already requires a reboot, so this is settled by the time the camera comes up.
if (projectConfig->getDeviceMode() == StreamingMode::UVC)
{
xclk_freq_hz = CONFIG_CAMERA_USB_XCLK_FREQ;
}
#endif

ESP_LOGI(CAMERA_MANAGER_TAG, "[Camera]: XCLK set to %d Hz", xclk_freq_hz);

config = {
.pin_pwdn = CONFIG_PWDN_GPIO_NUM, // CAM_PIN_PWDN,
.pin_reset = CONFIG_RESET_GPIO_NUM, // CAM_PIN_RESET,
Expand Down
39 changes: 33 additions & 6 deletions components/wifiManager/wifiManager/wifiManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,10 @@ void WiFiManagerHelpers::event_handler(void* arg, esp_event_base_t event_base, i

if (s_retry_num < EXAMPLE_ESP_MAXIMUM_RETRY)
{
vTaskDelay(pdMS_TO_TICKS(WIFI_RETRY_BACKOFF_MS));
esp_wifi_connect();
s_retry_num++;
ESP_LOGI(WIFI_MANAGER_TAG, "retry to connect to the AP");
ESP_LOGI(WIFI_MANAGER_TAG, "retry %d/%d to connect to the AP", s_retry_num, EXAMPLE_ESP_MAXIMUM_RETRY);
}
else
{
Expand All @@ -51,6 +52,27 @@ WiFiManager::WiFiManager(std::shared_ptr<ProjectConfig> deviceConfig, QueueHandl
{
}

void WiFiManager::ApplyTxPower()
{
// esp_wifi_set_max_tx_power only takes effect once the driver is started - calling it
// before esp_wifi_start() is silently ignored. Units are 0.25dBm, valid range 8-84.
uint8_t configured = this->deviceConfig->getWiFiTxPowerConfig().power;
if (configured < 8)
configured = 8;
if (configured > 84)
configured = 84;

if (const auto err = esp_wifi_set_max_tx_power(static_cast<int8_t>(configured)); err != ESP_OK)
{
ESP_LOGW(WIFI_MANAGER_TAG, "Failed to set TX power to %u: %s", configured, esp_err_to_name(err));
return;
}

int8_t applied = 0;
esp_wifi_get_max_tx_power(&applied);
ESP_LOGI(WIFI_MANAGER_TAG, "TX power set to %d (%d.%02d dBm)", applied, applied / 4, (applied % 4) * 25);
}

std::vector<uint8_t> WiFiManager::ParseBSSID(std::string_view bssid_string)
{
return bssid_string
Expand Down Expand Up @@ -108,8 +130,10 @@ void WiFiManager::SetCredentials(const char* ssid, const std::vector<uint8_t> bs
_wifi_cfg.sta.pmf_cfg.capable = false;
_wifi_cfg.sta.pmf_cfg.required = false;

// OPTIMIZATION: Use fast scan instead of all channel scan for quicker connection
_wifi_cfg.sta.scan_method = WIFI_FAST_SCAN;
// IMPORTANT: Must be ALL_CHANNEL_SCAN for sort_method below to take effect. WIFI_FAST_SCAN
// stops at the first SSID match, so on a mesh/repeater network it latches onto whichever
// node answers the probe first - often a distant one - and association becomes a coin flip.
_wifi_cfg.sta.scan_method = WIFI_ALL_CHANNEL_SCAN;
_wifi_cfg.sta.bssid_set = use_bssid; // Don't use specific BSSID
_wifi_cfg.sta.channel = 0; // Auto channel detection

Expand Down Expand Up @@ -144,12 +168,14 @@ void WiFiManager::ConnectWithHardcodedCredentials()

xQueueSend(this->eventQueue, &event, 10);
esp_wifi_start();
this->ApplyTxPower();

event.value = WiFiState_e::WiFiState_Connecting;
xQueueSend(this->eventQueue, &event, 10);

// Use shorter timeout for faster startup - 8 seconds should be enough for most networks
EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group, WIFI_CONNECTED_BIT | WIFI_FAIL_BIT, pdFALSE, pdFALSE, pdMS_TO_TICKS(8000));
// Budget must cover EXAMPLE_ESP_MAXIMUM_RETRY attempts: an all-channel scan costs ~2-3s per
// attempt, so timing out earlier than that abandons retries that were about to succeed.
EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group, WIFI_CONNECTED_BIT | WIFI_FAIL_BIT, pdFALSE, pdFALSE, pdMS_TO_TICKS(18000));

/* xEventGroupWaitBits() returns the bits before the call returned, hence we can test which event actually
* happened. */
Expand Down Expand Up @@ -216,12 +242,13 @@ void WiFiManager::ConnectWithStoredCredentials()
ESP_LOGE(WIFI_MANAGER_TAG, "Failed to start WiFi: %s", esp_err_to_name(start_err));
continue;
}
this->ApplyTxPower();

event.value = WiFiState_e::WiFiState_Connecting;
xQueueSend(this->eventQueue, &event, 10);

EventBits_t bits = xEventGroupWaitBits(s_wifi_event_group, WIFI_CONNECTED_BIT | WIFI_FAIL_BIT, pdFALSE, pdFALSE,
pdMS_TO_TICKS(10000)); // 10 second timeout for faster failover
pdMS_TO_TICKS(18000)); // must cover all retries, see ConnectWithHardcodedCredentials
if (bits & WIFI_CONNECTED_BIT)
{
ESP_LOGI(WIFI_MANAGER_TAG, "connected to ap SSID:%s", network.ssid.c_str());
Expand Down
6 changes: 5 additions & 1 deletion components/wifiManager/wifiManager/wifiManager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"

#define EXAMPLE_ESP_MAXIMUM_RETRY 3
#define EXAMPLE_ESP_MAXIMUM_RETRY 5
// Spacing between reconnect attempts. Retrying with no gap burns the whole retry budget in
// under a second, which is not enough time for a busy or distant AP to answer.
#define WIFI_RETRY_BACKOFF_MS 300
#define WIFI_CONNECTED_BIT BIT0
#define WIFI_FAIL_BIT BIT1

Expand All @@ -41,6 +44,7 @@ class WiFiManager

int8_t power;

void ApplyTxPower();
void SetCredentials(const char* ssid, const std::vector<uint8_t> bssid, const char* password, bool use_bssid);
void ConnectWithHardcodedCredentials();
void ConnectWithStoredCredentials();
Expand Down