forked from xiaozhi/xiaozhi-esp32
在S3芯片上使用更多的PSRAM,解决立创开发板拍照时可能出现内存不足的问题
This commit is contained in:
@@ -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<MqttProtocol>();
|
||||
} else if (ota_.HasWebsocketConfig()) {
|
||||
} else if (ota.HasWebsocketConfig()) {
|
||||
protocol_ = std::make_unique<WebsocketProtocol>();
|
||||
} 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"
|
||||
|
||||
@@ -90,7 +90,6 @@ private:
|
||||
std::unique_ptr<WakeWord> wake_word_;
|
||||
std::unique_ptr<AudioProcessor> audio_processor_;
|
||||
std::unique_ptr<AudioDebugger> audio_debugger_;
|
||||
Ota ota_;
|
||||
std::mutex mutex_;
|
||||
std::list<std::function<void()>> main_tasks_;
|
||||
std::unique_ptr<Protocol> 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<int16_t>& 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();
|
||||
|
||||
@@ -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);
|
||||
|
||||
|
||||
@@ -4,8 +4,7 @@
|
||||
{
|
||||
"name": "lichuang-dev",
|
||||
"sdkconfig_append": [
|
||||
"CONFIG_USE_DEVICE_AEC=y",
|
||||
"CONFIG_SR_NSN_NSNET2=y"
|
||||
"CONFIG_USE_DEVICE_AEC=y"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
Reference in New Issue
Block a user