forked from xiaozhi/xiaozhi-esp32
start AP if WiFi station fails to connect
This commit is contained in:
@@ -1,6 +1,5 @@
|
|||||||
#include "Application.h"
|
#include "Application.h"
|
||||||
#include "BuiltinLed.h"
|
#include "BuiltinLed.h"
|
||||||
#include "WifiStation.h"
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include "esp_log.h"
|
#include "esp_log.h"
|
||||||
#include "model_path.h"
|
#include "model_path.h"
|
||||||
@@ -31,6 +30,8 @@ Application::Application() {
|
|||||||
if (opus_decode_sample_rate_ != CONFIG_AUDIO_OUTPUT_SAMPLE_RATE) {
|
if (opus_decode_sample_rate_ != CONFIG_AUDIO_OUTPUT_SAMPLE_RATE) {
|
||||||
opus_resampler_.Configure(opus_decode_sample_rate_, CONFIG_AUDIO_OUTPUT_SAMPLE_RATE);
|
opus_resampler_.Configure(opus_decode_sample_rate_, CONFIG_AUDIO_OUTPUT_SAMPLE_RATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
firmware_upgrade_.SetCheckVersionUrl(CONFIG_OTA_VERSION_URL);
|
||||||
}
|
}
|
||||||
|
|
||||||
Application::~Application() {
|
Application::~Application() {
|
||||||
@@ -67,6 +68,24 @@ Application::~Application() {
|
|||||||
vEventGroupDelete(event_group_);
|
vEventGroupDelete(event_group_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void Application::CheckNewVersion() {
|
||||||
|
// Check if there is a new firmware version available
|
||||||
|
firmware_upgrade_.CheckVersion();
|
||||||
|
if (firmware_upgrade_.HasNewVersion()) {
|
||||||
|
// Wait for the chat state to be idle
|
||||||
|
while (chat_state_ != kChatStateIdle) {
|
||||||
|
vTaskDelay(100);
|
||||||
|
}
|
||||||
|
SetChatState(kChatStateUpgrading);
|
||||||
|
firmware_upgrade_.StartUpgrade();
|
||||||
|
// If upgrade success, the device will reboot and never reach here
|
||||||
|
ESP_LOGI(TAG, "Firmware upgrade failed...");
|
||||||
|
SetChatState(kChatStateIdle);
|
||||||
|
} else {
|
||||||
|
firmware_upgrade_.MarkValid();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void Application::Start() {
|
void Application::Start() {
|
||||||
// Initialize the audio device
|
// Initialize the audio device
|
||||||
audio_device_.Start(CONFIG_AUDIO_INPUT_SAMPLE_RATE, CONFIG_AUDIO_OUTPUT_SAMPLE_RATE);
|
audio_device_.Start(CONFIG_AUDIO_INPUT_SAMPLE_RATE, CONFIG_AUDIO_OUTPUT_SAMPLE_RATE);
|
||||||
@@ -96,31 +115,21 @@ void Application::Start() {
|
|||||||
app->AudioDecodeTask();
|
app->AudioDecodeTask();
|
||||||
}, "opus_decode", opus_stack_size, this, 1, audio_decode_task_stack_, &audio_decode_task_buffer_);
|
}, "opus_decode", opus_stack_size, this, 1, audio_decode_task_stack_, &audio_decode_task_buffer_);
|
||||||
|
|
||||||
auto& builtin_led = BuiltinLed::GetInstance();
|
|
||||||
// Blink the LED to indicate the device is connecting
|
|
||||||
builtin_led.SetBlue();
|
|
||||||
builtin_led.BlinkOnce();
|
|
||||||
WifiStation::GetInstance().Start();
|
|
||||||
|
|
||||||
// Check if there is a new firmware version available
|
|
||||||
firmware_upgrade_.CheckVersion();
|
|
||||||
if (firmware_upgrade_.HasNewVersion()) {
|
|
||||||
builtin_led.TurnOn();
|
|
||||||
firmware_upgrade_.StartUpgrade();
|
|
||||||
// If upgrade success, the device will reboot and never reach here
|
|
||||||
ESP_LOGI(TAG, "Firmware upgrade failed...");
|
|
||||||
builtin_led.TurnOff();
|
|
||||||
} else {
|
|
||||||
firmware_upgrade_.MarkValid();
|
|
||||||
}
|
|
||||||
|
|
||||||
StartCommunication();
|
StartCommunication();
|
||||||
StartDetection();
|
StartDetection();
|
||||||
|
|
||||||
// Blink the LED to indicate the device is running
|
// Blink the LED to indicate the device is running
|
||||||
|
auto& builtin_led = BuiltinLed::GetInstance();
|
||||||
builtin_led.SetGreen();
|
builtin_led.SetGreen();
|
||||||
builtin_led.BlinkOnce();
|
builtin_led.BlinkOnce();
|
||||||
xEventGroupSetBits(event_group_, DETECTION_RUNNING);
|
xEventGroupSetBits(event_group_, DETECTION_RUNNING);
|
||||||
|
|
||||||
|
// Launch a task to check for new firmware version
|
||||||
|
xTaskCreate([](void* arg) {
|
||||||
|
Application* app = (Application*)arg;
|
||||||
|
app->CheckNewVersion();
|
||||||
|
vTaskDelete(NULL);
|
||||||
|
}, "check_new_version", 4096 * 2, this, 1, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Application::SetChatState(ChatState state) {
|
void Application::SetChatState(ChatState state) {
|
||||||
@@ -156,6 +165,11 @@ void Application::SetChatState(ChatState state) {
|
|||||||
builtin_led.SetRed();
|
builtin_led.SetRed();
|
||||||
builtin_led.TurnOn();
|
builtin_led.TurnOn();
|
||||||
break;
|
break;
|
||||||
|
case kChatStateUpgrading:
|
||||||
|
ESP_LOGI(TAG, "Chat state: upgrading");
|
||||||
|
builtin_led.SetGreen();
|
||||||
|
builtin_led.StartContinuousBlink(100);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char* state_str[] = { "idle", "connecting", "listening", "speaking", "wake_word_detected", "testing", "unknown" };
|
const char* state_str[] = { "idle", "connecting", "listening", "speaking", "wake_word_detected", "testing", "unknown" };
|
||||||
@@ -175,7 +189,7 @@ void Application::StartCommunication() {
|
|||||||
afe_config_t afe_config = {
|
afe_config_t afe_config = {
|
||||||
.aec_init = false,
|
.aec_init = false,
|
||||||
.se_init = true,
|
.se_init = true,
|
||||||
.vad_init = false,
|
.vad_init = true,
|
||||||
.wakenet_init = false,
|
.wakenet_init = false,
|
||||||
.voice_communication_init = true,
|
.voice_communication_init = true,
|
||||||
.voice_communication_agc_init = true,
|
.voice_communication_agc_init = true,
|
||||||
@@ -406,7 +420,7 @@ void Application::AudioDetectionTask() {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res->wakeup_state == WAKENET_DETECTED) {
|
if (chat_state_ == kChatStateIdle && res->wakeup_state == WAKENET_DETECTED) {
|
||||||
xEventGroupClearBits(event_group_, DETECTION_RUNNING);
|
xEventGroupClearBits(event_group_, DETECTION_RUNNING);
|
||||||
SetChatState(kChatStateConnecting);
|
SetChatState(kChatStateConnecting);
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,8 @@ enum ChatState {
|
|||||||
kChatStateListening,
|
kChatStateListening,
|
||||||
kChatStateSpeaking,
|
kChatStateSpeaking,
|
||||||
kChatStateWakeWordDetected,
|
kChatStateWakeWordDetected,
|
||||||
kChatStateTesting
|
kChatStateTesting,
|
||||||
|
kChatStateUpgrading
|
||||||
};
|
};
|
||||||
|
|
||||||
class Application {
|
class Application {
|
||||||
@@ -96,6 +97,7 @@ private:
|
|||||||
void SendWakeWordData();
|
void SendWakeWordData();
|
||||||
void CheckTestButton();
|
void CheckTestButton();
|
||||||
void PlayTestAudio();
|
void PlayTestAudio();
|
||||||
|
void CheckNewVersion();
|
||||||
|
|
||||||
void AudioFeedTask();
|
void AudioFeedTask();
|
||||||
void AudioDetectionTask();
|
void AudioDetectionTask();
|
||||||
|
|||||||
@@ -1,14 +1,20 @@
|
|||||||
menu "Xiaozhi Assistant"
|
menu "Xiaozhi Assistant"
|
||||||
|
|
||||||
|
config OTA_VERSION_URL
|
||||||
|
string "OTA Version URL"
|
||||||
|
default "https://api.tenclass.net/xiaozhi/ota/"
|
||||||
|
help
|
||||||
|
The application will access this URL to check for updates.
|
||||||
|
|
||||||
config WEBSOCKET_URL
|
config WEBSOCKET_URL
|
||||||
string "Websocket URL"
|
string "Websocket URL"
|
||||||
default "wss://"
|
default "wss://api.tenclass.net/xiaozhi/v1/"
|
||||||
help
|
help
|
||||||
Communication with the server through websocket after wake up.
|
Communication with the server through websocket after wake up.
|
||||||
|
|
||||||
config WEBSOCKET_ACCESS_TOKEN
|
config WEBSOCKET_ACCESS_TOKEN
|
||||||
string "Websocket Access Token"
|
string "Websocket Access Token"
|
||||||
default ""
|
default "test-token"
|
||||||
help
|
help
|
||||||
Access token for websocket communication.
|
Access token for websocket communication.
|
||||||
|
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
## IDF Component Manager Manifest File
|
## IDF Component Manager Manifest File
|
||||||
dependencies:
|
dependencies:
|
||||||
78/esp-builtin-led: "^1.0.0"
|
78/esp-builtin-led: "^1.0.1"
|
||||||
78/esp-wifi-connect: "^1.0.0"
|
78/esp-wifi-connect: "^1.0.1"
|
||||||
78/esp-ota: "^1.0.0"
|
78/esp-ota: "^1.0.1"
|
||||||
78/esp-websocket: "^1.0.0"
|
78/esp-websocket: "^1.0.0"
|
||||||
78/esp-opus-encoder: "^1.0.1"
|
78/esp-opus-encoder: "^1.0.1"
|
||||||
espressif/esp-sr: "^1.9.0"
|
espressif/esp-sr: "^1.9.0"
|
||||||
|
|||||||
17
main/main.cc
17
main/main.cc
@@ -11,6 +11,7 @@
|
|||||||
#include "SystemInfo.h"
|
#include "SystemInfo.h"
|
||||||
#include "SystemReset.h"
|
#include "SystemReset.h"
|
||||||
#include "BuiltinLed.h"
|
#include "BuiltinLed.h"
|
||||||
|
#include "WifiStation.h"
|
||||||
|
|
||||||
#define TAG "main"
|
#define TAG "main"
|
||||||
#define STATS_TICKS pdMS_TO_TICKS(1000)
|
#define STATS_TICKS pdMS_TO_TICKS(1000)
|
||||||
@@ -32,20 +33,18 @@ extern "C" void app_main(void)
|
|||||||
}
|
}
|
||||||
ESP_ERROR_CHECK(ret);
|
ESP_ERROR_CHECK(ret);
|
||||||
|
|
||||||
// Get the WiFi configuration
|
// Try to connect to WiFi, if failed, launch the WiFi configuration AP
|
||||||
nvs_handle_t nvs_handle;
|
auto& builtin_led = BuiltinLed::GetInstance();
|
||||||
ret = nvs_open("wifi", NVS_READONLY, &nvs_handle);
|
auto& wifi_station = WifiStation::GetInstance();
|
||||||
|
builtin_led.SetBlue();
|
||||||
// If the WiFi configuration is not found, launch the WiFi configuration AP
|
builtin_led.StartContinuousBlink(100);
|
||||||
if (ret != ESP_OK) {
|
wifi_station.Start();
|
||||||
auto& builtin_led = BuiltinLed::GetInstance();
|
if (!wifi_station.IsConnected()) {
|
||||||
builtin_led.SetBlue();
|
builtin_led.SetBlue();
|
||||||
builtin_led.Blink(1000, 500);
|
builtin_led.Blink(1000, 500);
|
||||||
|
|
||||||
WifiConfigurationAp::GetInstance().Start("Xiaozhi");
|
WifiConfigurationAp::GetInstance().Start("Xiaozhi");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
nvs_close(nvs_handle);
|
|
||||||
|
|
||||||
// Otherwise, launch the application
|
// Otherwise, launch the application
|
||||||
Application::GetInstance().Start();
|
Application::GetInstance().Start();
|
||||||
|
|||||||
Reference in New Issue
Block a user