From b3ab3d0920319f9d0f615aa3cbd1b121f51f4b38 Mon Sep 17 00:00:00 2001 From: Terrence Date: Tue, 24 Jun 2025 04:59:00 +0800 Subject: [PATCH] =?UTF-8?q?=E5=9C=A8S3=E8=8A=AF=E7=89=87=E4=B8=8A=E4=BD=BF?= =?UTF-8?q?=E7=94=A8=E6=9B=B4=E5=A4=9A=E7=9A=84PSRAM=EF=BC=8C=E8=A7=A3?= =?UTF-8?q?=E5=86=B3=E7=AB=8B=E5=88=9B=E5=BC=80=E5=8F=91=E6=9D=BF=E6=8B=8D?= =?UTF-8?q?=E7=85=A7=E6=97=B6=E5=8F=AF=E8=83=BD=E5=87=BA=E7=8E=B0=E5=86=85?= =?UTF-8?q?=E5=AD=98=E4=B8=8D=E8=B6=B3=E7=9A=84=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main/application.cc | 39 ++++++++++----------- main/application.h | 6 ++-- main/boards/common/esp32_camera.cc | 52 +++++++++++++--------------- main/boards/lichuang-dev/config.json | 3 +- sdkconfig.defaults.esp32s3 | 4 +-- 5 files changed, 50 insertions(+), 54 deletions(-) diff --git a/main/application.cc b/main/application.cc index fe0d4df4..b5cedd10 100644 --- a/main/application.cc +++ b/main/application.cc @@ -100,7 +100,7 @@ Application::~Application() { vEventGroupDelete(event_group_); } -void Application::CheckNewVersion() { +void Application::CheckNewVersion(Ota& ota) { const int MAX_RETRY = 10; int retry_count = 0; int retry_delay = 10; // 初始重试延迟为10秒 @@ -110,7 +110,7 @@ void Application::CheckNewVersion() { auto display = Board::GetInstance().GetDisplay(); display->SetStatus(Lang::Strings::CHECKING_NEW_VERSION); - if (!ota_.CheckVersion()) { + if (!ota.CheckVersion()) { retry_count++; if (retry_count >= MAX_RETRY) { ESP_LOGE(TAG, "Too many retries, exit version check"); @@ -118,7 +118,7 @@ void Application::CheckNewVersion() { } char buffer[128]; - snprintf(buffer, sizeof(buffer), Lang::Strings::CHECK_NEW_VERSION_FAILED, retry_delay, ota_.GetCheckVersionUrl().c_str()); + snprintf(buffer, sizeof(buffer), Lang::Strings::CHECK_NEW_VERSION_FAILED, retry_delay, ota.GetCheckVersionUrl().c_str()); Alert(Lang::Strings::ERROR, buffer, "sad", Lang::Sounds::P3_EXCLAMATION); ESP_LOGW(TAG, "Check new version failed, retry in %d seconds (%d/%d)", retry_delay, retry_count, MAX_RETRY); @@ -134,7 +134,7 @@ void Application::CheckNewVersion() { retry_count = 0; retry_delay = 10; // 重置重试延迟时间 - if (ota_.HasNewVersion()) { + if (ota.HasNewVersion()) { Alert(Lang::Strings::OTA_UPGRADE, Lang::Strings::UPGRADING, "happy", Lang::Sounds::P3_UPGRADE); vTaskDelay(pdMS_TO_TICKS(3000)); @@ -142,7 +142,7 @@ void Application::CheckNewVersion() { SetDeviceState(kDeviceStateUpgrading); display->SetIcon(FONT_AWESOME_DOWNLOAD); - std::string message = std::string(Lang::Strings::NEW_VERSION) + ota_.GetFirmwareVersion(); + std::string message = std::string(Lang::Strings::NEW_VERSION) + ota.GetFirmwareVersion(); display->SetChatMessage("system", message.c_str()); auto& board = Board::GetInstance(); @@ -161,7 +161,7 @@ void Application::CheckNewVersion() { background_task_ = nullptr; vTaskDelay(pdMS_TO_TICKS(1000)); - ota_.StartUpgrade([display](int progress, size_t speed) { + ota.StartUpgrade([display](int progress, size_t speed) { char buffer[64]; snprintf(buffer, sizeof(buffer), "%d%% %uKB/s", progress, speed / 1024); display->SetChatMessage("system", buffer); @@ -176,8 +176,8 @@ void Application::CheckNewVersion() { } // No new version, mark the current version as valid - ota_.MarkCurrentVersionValid(); - if (!ota_.HasActivationCode() && !ota_.HasActivationChallenge()) { + ota.MarkCurrentVersionValid(); + if (!ota.HasActivationCode() && !ota.HasActivationChallenge()) { xEventGroupSetBits(event_group_, CHECK_NEW_VERSION_DONE_EVENT); // Exit the loop if done checking new version break; @@ -185,14 +185,14 @@ void Application::CheckNewVersion() { display->SetStatus(Lang::Strings::ACTIVATION); // Activation code is shown to the user and waiting for the user to input - if (ota_.HasActivationCode()) { - ShowActivationCode(); + if (ota.HasActivationCode()) { + ShowActivationCode(ota.GetActivationCode(), ota.GetActivationMessage()); } // This will block the loop until the activation is done or timeout for (int i = 0; i < 10; ++i) { ESP_LOGI(TAG, "Activating... %d/%d", i + 1, 10); - esp_err_t err = ota_.Activate(); + esp_err_t err = ota.Activate(); if (err == ESP_OK) { xEventGroupSetBits(event_group_, CHECK_NEW_VERSION_DONE_EVENT); break; @@ -208,10 +208,7 @@ void Application::CheckNewVersion() { } } -void Application::ShowActivationCode() { - auto& message = ota_.GetActivationMessage(); - auto& code = ota_.GetActivationCode(); - +void Application::ShowActivationCode(const std::string& code, const std::string& message) { struct digit_sound { char digit; const std::string_view& sound; @@ -454,7 +451,8 @@ void Application::Start() { display->UpdateStatusBar(true); // Check for new firmware version or get the MQTT broker address - CheckNewVersion(); + Ota ota; + CheckNewVersion(ota); // Initialize the protocol display->SetStatus(Lang::Strings::LOADING_PROTOCOL); @@ -464,9 +462,9 @@ void Application::Start() { McpServer::GetInstance().AddCommonTools(); #endif - if (ota_.HasMqttConfig()) { + if (ota.HasMqttConfig()) { protocol_ = std::make_unique(); - } else if (ota_.HasWebsocketConfig()) { + } else if (ota.HasWebsocketConfig()) { protocol_ = std::make_unique(); } else { ESP_LOGW(TAG, "No protocol specified in the OTA config, using MQTT"); @@ -702,8 +700,9 @@ void Application::Start() { xEventGroupWaitBits(event_group_, CHECK_NEW_VERSION_DONE_EVENT, pdTRUE, pdFALSE, portMAX_DELAY); SetDeviceState(kDeviceStateIdle); + has_server_time_ = ota.HasServerTime(); if (protocol_started) { - std::string message = std::string(Lang::Strings::VERSION) + ota_.GetCurrentVersion(); + std::string message = std::string(Lang::Strings::VERSION) + ota.GetCurrentVersion(); display->ShowNotification(message.c_str()); display->SetChatMessage("system", ""); // Play the success sound to indicate the device is ready @@ -731,7 +730,7 @@ void Application::OnClockTimer() { SystemInfo::PrintHeapStats(); // If we have synchronized server time, set the status to clock "HH:MM" if the device is idle - if (ota_.HasServerTime()) { + if (has_server_time_) { if (device_state_ == kDeviceStateIdle) { Schedule([this]() { // Set status to clock "HH:MM" diff --git a/main/application.h b/main/application.h index 82ab9a1b..b73075c2 100644 --- a/main/application.h +++ b/main/application.h @@ -90,7 +90,6 @@ private: std::unique_ptr wake_word_; std::unique_ptr audio_processor_; std::unique_ptr audio_debugger_; - Ota ota_; std::mutex mutex_; std::list> main_tasks_; std::unique_ptr protocol_; @@ -100,6 +99,7 @@ private: ListeningMode listening_mode_ = kListeningModeAutoStop; AecMode aec_mode_ = kAecOff; + bool has_server_time_ = false; bool aborted_ = false; bool voice_detected_ = false; bool busy_decoding_audio_ = false; @@ -132,8 +132,8 @@ private: bool ReadAudio(std::vector& data, int sample_rate, int samples); void ResetDecoder(); void SetDecodeSampleRate(int sample_rate, int frame_duration); - void CheckNewVersion(); - void ShowActivationCode(); + void CheckNewVersion(Ota& ota); + void ShowActivationCode(const std::string& code, const std::string& message); void OnClockTimer(); void SetListeningMode(ListeningMode mode); void AudioLoop(); diff --git a/main/boards/common/esp32_camera.cc b/main/boards/common/esp32_camera.cc index 380414cd..17b5d972 100644 --- a/main/boards/common/esp32_camera.cc +++ b/main/boards/common/esp32_camera.cc @@ -212,24 +212,6 @@ std::string Esp32Camera::Explain(const std::string& question) { auto http = Board::GetInstance().CreateHttp(); // 构造multipart/form-data请求体 std::string boundary = "----ESP32_CAMERA_BOUNDARY"; - - // 构造question字段 - std::string question_field; - question_field += "--" + boundary + "\r\n"; - question_field += "Content-Disposition: form-data; name=\"question\"\r\n"; - question_field += "\r\n"; - question_field += question + "\r\n"; - - // 构造文件字段头部 - std::string file_header; - file_header += "--" + boundary + "\r\n"; - file_header += "Content-Disposition: form-data; name=\"file\"; filename=\"camera.jpg\"\r\n"; - file_header += "Content-Type: image/jpeg\r\n"; - file_header += "\r\n"; - - // 构造尾部 - std::string multipart_footer; - multipart_footer += "\r\n--" + boundary + "--\r\n"; // 配置HTTP客户端,使用分块传输编码 http->SetHeader("Device-Id", SystemInfo::GetMacAddress().c_str()); @@ -255,12 +237,25 @@ std::string Esp32Camera::Explain(const std::string& question) { return "{\"success\": false, \"message\": \"Failed to connect to explain URL\"}"; } - // 第一块:question字段 - http->Write(question_field.c_str(), question_field.size()); - - // 第二块:文件字段头部 - http->Write(file_header.c_str(), file_header.size()); - + { + // 第一块:question字段 + std::string question_field; + question_field += "--" + boundary + "\r\n"; + question_field += "Content-Disposition: form-data; name=\"question\"\r\n"; + question_field += "\r\n"; + question_field += question + "\r\n"; + http->Write(question_field.c_str(), question_field.size()); + } + { + // 第二块:文件字段头部 + std::string file_header; + file_header += "--" + boundary + "\r\n"; + file_header += "Content-Disposition: form-data; name=\"file\"; filename=\"camera.jpg\"\r\n"; + file_header += "Content-Type: image/jpeg\r\n"; + file_header += "\r\n"; + http->Write(file_header.c_str(), file_header.size()); + } + // 第三块:JPEG数据 size_t total_sent = 0; while (true) { @@ -281,9 +276,12 @@ std::string Esp32Camera::Explain(const std::string& question) { // 清理队列 vQueueDelete(jpeg_queue); - // 第四块:multipart尾部 - http->Write(multipart_footer.c_str(), multipart_footer.size()); - + { + // 第四块:multipart尾部 + std::string multipart_footer; + multipart_footer += "\r\n--" + boundary + "--\r\n"; + http->Write(multipart_footer.c_str(), multipart_footer.size()); + } // 结束块 http->Write("", 0); diff --git a/main/boards/lichuang-dev/config.json b/main/boards/lichuang-dev/config.json index bc10ac90..e2a7090e 100644 --- a/main/boards/lichuang-dev/config.json +++ b/main/boards/lichuang-dev/config.json @@ -4,8 +4,7 @@ { "name": "lichuang-dev", "sdkconfig_append": [ - "CONFIG_USE_DEVICE_AEC=y", - "CONFIG_SR_NSN_NSNET2=y" + "CONFIG_USE_DEVICE_AEC=y" ] } ] diff --git a/sdkconfig.defaults.esp32s3 b/sdkconfig.defaults.esp32s3 index c9bc1b68..40036e44 100644 --- a/sdkconfig.defaults.esp32s3 +++ b/sdkconfig.defaults.esp32s3 @@ -7,8 +7,8 @@ CONFIG_ESP_DEFAULT_CPU_FREQ_MHZ_240=y CONFIG_SPIRAM=y CONFIG_SPIRAM_MODE_OCT=y CONFIG_SPIRAM_SPEED_80M=y -CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=4096 -CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=49152 +CONFIG_SPIRAM_MALLOC_ALWAYSINTERNAL=512 +CONFIG_SPIRAM_MALLOC_RESERVE_INTERNAL=65536 CONFIG_SPIRAM_MEMTEST=n CONFIG_MBEDTLS_EXTERNAL_MEM_ALLOC=y