From c7c5b74d37cb7657d006efc8d529345b78866715 Mon Sep 17 00:00:00 2001 From: Terrence Date: Sun, 5 Jan 2025 19:34:28 +0800 Subject: [PATCH] reconstruct led control --- main/CMakeLists.txt | 5 +- main/application.cc | 117 +++++----- main/application.h | 25 +- .../compact_ml307_board.cc | 8 +- .../bread-compact-wifi/compact_wifi_board.cc | 10 +- main/boards/common/board.cc | 4 + main/boards/common/board.h | 4 +- main/boards/common/led.cc | 62 ----- main/boards/common/led.h | 38 --- main/boards/common/ml307_board.cc | 2 +- main/boards/common/wifi_board.cc | 4 +- main/boards/esp-box-3/esp_box3_board.cc | 6 - main/boards/kevin-box-1/kevin_box_board.cc | 6 +- main/boards/kevin-box-2/kevin_box_board.cc | 10 +- main/boards/kevin-c3/kevin_box_board.cc | 10 +- .../boards/lichuang-dev/lichuang_dev_board.cc | 8 +- main/display/display.cc | 4 +- main/led/circular_strip.cc | 218 ++++++++++++++++++ main/led/circular_strip.h | 44 ++++ .../led_strip_wrapper.cc => led/led.cc} | 10 +- main/led/led.h | 17 ++ main/led/single_led.cc | 158 +++++++++++++ main/led/single_led.h | 38 +++ main/led_strip/led_strip_wrapper.h | 58 ----- main/led_strip/multiple_led.cc | 39 ---- main/led_strip/multiple_led.h | 14 -- main/led_strip/single_led.cc | 39 ---- main/led_strip/single_led.h | 14 -- 28 files changed, 586 insertions(+), 386 deletions(-) delete mode 100644 main/boards/common/led.cc delete mode 100644 main/boards/common/led.h create mode 100644 main/led/circular_strip.cc create mode 100644 main/led/circular_strip.h rename main/{led_strip/led_strip_wrapper.cc => led/led.cc} (96%) create mode 100644 main/led/led.h create mode 100644 main/led/single_led.cc create mode 100644 main/led/single_led.h delete mode 100644 main/led_strip/led_strip_wrapper.h delete mode 100644 main/led_strip/multiple_led.cc delete mode 100644 main/led_strip/multiple_led.h delete mode 100644 main/led_strip/single_led.cc delete mode 100644 main/led_strip/single_led.h diff --git a/main/CMakeLists.txt b/main/CMakeLists.txt index 3745605d..6eb69dca 100644 --- a/main/CMakeLists.txt +++ b/main/CMakeLists.txt @@ -3,9 +3,8 @@ set(SOURCES "audio_codecs/audio_codec.cc" "audio_codecs/box_audio_codec.cc" "audio_codecs/es8311_audio_codec.cc" "audio_codecs/cores3_audio_codec.cc" - "led_strip/single_led.cc" - "led_strip/multiple_led.cc" - "led_strip/led_strip_wrapper.cc" + "led/single_led.cc" + "led/circular_strip.cc" "display/display.cc" "display/no_display.cc" "display/st7789_display.cc" diff --git a/main/application.cc b/main/application.cc index 80e0daba..d4d6b783 100644 --- a/main/application.cc +++ b/main/application.cc @@ -26,11 +26,14 @@ extern const char p3_err_wificonfig_end[] asm("_binary_err_wificonfig_p3_end"); static const char* const STATE_STRINGS[] = { "unknown", + "starting", + "configuring", "idle", "connecting", "listening", "speaking", "upgrading", + "fatal_error", "invalid_state" }; @@ -57,9 +60,9 @@ void Application::CheckNewVersion() { // Wait for the chat state to be idle do { vTaskDelay(pdMS_TO_TICKS(3000)); - } while (GetChatState() != kChatStateIdle); + } while (GetDeviceState() != kDeviceStateIdle); - SetChatState(kChatStateUpgrading); + SetDeviceState(kDeviceStateUpgrading); display->SetIcon(FONT_AWESOME_DOWNLOAD); display->SetStatus("新版本 " + ota_.GetFirmwareVersion()); @@ -75,7 +78,7 @@ void Application::CheckNewVersion() { // If upgrade success, the device will reboot and never reach here ESP_LOGI(TAG, "Firmware upgrade failed..."); - SetChatState(kChatStateIdle); + SetDeviceState(kDeviceStateIdle); } else { ota_.MarkCurrentVersionValid(); display->ShowNotification("版本 " + ota_.GetCurrentVersion()); @@ -127,20 +130,20 @@ void Application::ToggleChatState() { return; } - if (chat_state_ == kChatStateIdle) { - SetChatState(kChatStateConnecting); + if (device_state_ == kDeviceStateIdle) { + SetDeviceState(kDeviceStateConnecting); if (!protocol_->OpenAudioChannel()) { Alert("Error", "Failed to open audio channel"); - SetChatState(kChatStateIdle); + SetDeviceState(kDeviceStateIdle); return; } keep_listening_ = true; protocol_->SendStartListening(kListeningModeAutoStop); - SetChatState(kChatStateListening); - } else if (chat_state_ == kChatStateSpeaking) { + SetDeviceState(kDeviceStateListening); + } else if (device_state_ == kDeviceStateSpeaking) { AbortSpeaking(kAbortReasonNone); - } else if (chat_state_ == kChatStateListening) { + } else if (device_state_ == kDeviceStateListening) { protocol_->CloseAudioChannel(); } }); @@ -154,40 +157,39 @@ void Application::StartListening() { } keep_listening_ = false; - if (chat_state_ == kChatStateIdle) { + if (device_state_ == kDeviceStateIdle) { if (!protocol_->IsAudioChannelOpened()) { - SetChatState(kChatStateConnecting); + SetDeviceState(kDeviceStateConnecting); if (!protocol_->OpenAudioChannel()) { - SetChatState(kChatStateIdle); + SetDeviceState(kDeviceStateIdle); Alert("Error", "Failed to open audio channel"); return; } } protocol_->SendStartListening(kListeningModeManualStop); - SetChatState(kChatStateListening); - } else if (chat_state_ == kChatStateSpeaking) { + SetDeviceState(kDeviceStateListening); + } else if (device_state_ == kDeviceStateSpeaking) { AbortSpeaking(kAbortReasonNone); protocol_->SendStartListening(kListeningModeManualStop); // FIXME: Wait for the speaker to empty the buffer vTaskDelay(pdMS_TO_TICKS(120)); - SetChatState(kChatStateListening); + SetDeviceState(kDeviceStateListening); } }); } void Application::StopListening() { Schedule([this]() { - if (chat_state_ == kChatStateListening) { + if (device_state_ == kDeviceStateListening) { protocol_->SendStopListening(); - SetChatState(kChatStateIdle); + SetDeviceState(kDeviceStateIdle); } }); } void Application::Start() { auto& board = Board::GetInstance(); - auto led_strip = board.GetLedStrip(); - led_strip->LightOn(kStartup); + SetDeviceState(kDeviceStateStarting); /* Setup the display */ auto display = board.GetDisplay(); @@ -245,26 +247,27 @@ void Application::Start() { wake_word_detect_.Initialize(codec->input_channels(), codec->input_reference()); wake_word_detect_.OnVadStateChange([this](bool speaking) { Schedule([this, speaking]() { - auto led_strip = Board::GetInstance().GetLedStrip(); - if (chat_state_ == kChatStateListening) { + if (device_state_ == kDeviceStateListening) { if (speaking) { - led_strip->LightOn(kListeningAndSpeaking); + voice_detected_ = true; } else { - led_strip->LightOn(kListening); + voice_detected_ = false; } + auto led = Board::GetInstance().GetLed(); + led->OnStateChanged(); } }); }); wake_word_detect_.OnWakeWordDetected([this](const std::string& wake_word) { Schedule([this, &wake_word]() { - if (chat_state_ == kChatStateIdle) { - SetChatState(kChatStateConnecting); + if (device_state_ == kDeviceStateIdle) { + SetDeviceState(kDeviceStateConnecting); wake_word_detect_.EncodeWakeWordData(); if (!protocol_->OpenAudioChannel()) { ESP_LOGE(TAG, "Failed to open audio channel"); - SetChatState(kChatStateIdle); + SetDeviceState(kDeviceStateIdle); wake_word_detect_.StartDetection(); return; } @@ -278,8 +281,8 @@ void Application::Start() { protocol_->SendWakeWordDetected(wake_word); ESP_LOGI(TAG, "Wake word detected: %s", wake_word.c_str()); keep_listening_ = true; - SetChatState(kChatStateListening); - } else if (chat_state_ == kChatStateSpeaking) { + SetDeviceState(kDeviceStateListening); + } else if (device_state_ == kDeviceStateSpeaking) { AbortSpeaking(kAbortReasonWakeWordDetected); } @@ -302,7 +305,7 @@ void Application::Start() { }); protocol_->OnIncomingAudio([this](std::vector&& data) { std::lock_guard lock(mutex_); - if (chat_state_ == kChatStateSpeaking) { + if (device_state_ == kDeviceStateSpeaking) { audio_decode_queue_.emplace_back(std::move(data)); } }); @@ -321,7 +324,7 @@ void Application::Start() { protocol_->OnAudioChannelClosed([this, &board]() { board.SetPowerSaveMode(true); Schedule([this]() { - SetChatState(kChatStateIdle); + SetDeviceState(kDeviceStateIdle); }); }); protocol_->OnIncomingJson([this, display](const cJSON* root) { @@ -332,19 +335,19 @@ void Application::Start() { if (strcmp(state->valuestring, "start") == 0) { Schedule([this]() { aborted_ = false; - if (chat_state_ == kChatStateIdle || chat_state_ == kChatStateListening) { - SetChatState(kChatStateSpeaking); + if (device_state_ == kDeviceStateIdle || device_state_ == kDeviceStateListening) { + SetDeviceState(kDeviceStateSpeaking); } }); } else if (strcmp(state->valuestring, "stop") == 0) { Schedule([this]() { - if (chat_state_ == kChatStateSpeaking) { + if (device_state_ == kDeviceStateSpeaking) { background_task_.WaitForCompletion(); if (keep_listening_) { protocol_->SendStartListening(kListeningModeAutoStop); - SetChatState(kChatStateListening); + SetDeviceState(kDeviceStateListening); } else { - SetChatState(kChatStateIdle); + SetDeviceState(kDeviceStateIdle); } } }); @@ -378,11 +381,7 @@ void Application::Start() { } }); - // Blink the LED to indicate the device is running - display->SetStatus("待命"); - led_strip->LightOn(kStandby); - - SetChatState(kChatStateIdle); + SetDeviceState(kDeviceStateIdle); } void Application::Schedule(std::function callback) { @@ -433,7 +432,7 @@ void Application::OutputAudio() { std::unique_lock lock(mutex_); if (audio_decode_queue_.empty()) { // Disable the output if there is no audio data for a long time - if (chat_state_ == kChatStateIdle) { + if (device_state_ == kDeviceStateIdle) { auto duration = std::chrono::duration_cast(now - last_output_time_).count(); if (duration > max_silence_seconds) { codec->EnableOutput(false); @@ -442,7 +441,7 @@ void Application::OutputAudio() { return; } - if (chat_state_ == kChatStateListening) { + if (device_state_ == kDeviceStateListening) { audio_decode_queue_.clear(); return; } @@ -513,7 +512,7 @@ void Application::InputAudio() { wake_word_detect_.Feed(data); } #else - if (chat_state_ == kChatStateListening) { + if (device_state_ == kDeviceStateListening) { background_task_.Schedule([this, data = std::move(data)]() mutable { opus_encoder_->Encode(std::move(data), [this](std::vector&& opus) { Schedule([this, opus = std::move(opus)]() { @@ -531,34 +530,32 @@ void Application::AbortSpeaking(AbortReason reason) { protocol_->SendAbortSpeaking(reason); } -void Application::SetChatState(ChatState state) { - if (chat_state_ == state) { +void Application::SetDeviceState(DeviceState state) { + if (device_state_ == state) { return; } - chat_state_ = state; - ESP_LOGI(TAG, "STATE: %s", STATE_STRINGS[chat_state_]); + device_state_ = state; + ESP_LOGI(TAG, "STATE: %s", STATE_STRINGS[device_state_]); // The state is changed, wait for all background tasks to finish background_task_.WaitForCompletion(); auto display = Board::GetInstance().GetDisplay(); - auto led_strip = Board::GetInstance().GetLedStrip(); + auto led = Board::GetInstance().GetLed(); + led->OnStateChanged(); switch (state) { - case kChatStateUnknown: - case kChatStateIdle: - led_strip->LightOff(); + case kDeviceStateUnknown: + case kDeviceStateIdle: display->SetStatus("待命"); display->SetEmotion("neutral"); #ifdef CONFIG_IDF_TARGET_ESP32S3 audio_processor_.Stop(); #endif break; - case kChatStateConnecting: - led_strip->LightOn(kConnecting); + case kDeviceStateConnecting: display->SetStatus("连接中..."); break; - case kChatStateListening: - led_strip->LightOn(kListening); + case kDeviceStateListening: display->SetStatus("聆听中..."); display->SetEmotion("neutral"); ResetDecoder(); @@ -568,20 +565,16 @@ void Application::SetChatState(ChatState state) { #endif UpdateIotStates(); break; - case kChatStateSpeaking: - led_strip->LightOn(kSpeaking); + case kDeviceStateSpeaking: display->SetStatus("说话中..."); ResetDecoder(); #if CONFIG_IDF_TARGET_ESP32S3 audio_processor_.Stop(); #endif break; - case kChatStateUpgrading: - led_strip->LightOn(kUpgrading); - break; default: - ESP_LOGE(TAG, "Invalid chat state: %d", chat_state_); - return; + // Do nothing + break; } } diff --git a/main/application.h b/main/application.h index c31f803b..45bdaaf4 100644 --- a/main/application.h +++ b/main/application.h @@ -26,13 +26,16 @@ #define AUDIO_INPUT_READY_EVENT (1 << 1) #define AUDIO_OUTPUT_READY_EVENT (1 << 2) -enum ChatState { - kChatStateUnknown, - kChatStateIdle, - kChatStateConnecting, - kChatStateListening, - kChatStateSpeaking, - kChatStateUpgrading +enum DeviceState { + kDeviceStateUnknown, + kDeviceStateStarting, + kDeviceStateWifiConfiguring, + kDeviceStateIdle, + kDeviceStateConnecting, + kDeviceStateListening, + kDeviceStateSpeaking, + kDeviceStateUpgrading, + kDeviceStateFatalError }; #define OPUS_FRAME_DURATION_MS 60 @@ -48,9 +51,10 @@ public: Application& operator=(const Application&) = delete; void Start(); - ChatState GetChatState() const { return chat_state_; } + DeviceState GetDeviceState() const { return device_state_; } + bool IsVoiceDetected() const { return voice_detected_; } void Schedule(std::function callback); - void SetChatState(ChatState state); + void SetDeviceState(DeviceState state); void Alert(const std::string& title, const std::string& message); void AbortSpeaking(AbortReason reason); void ToggleChatState(); @@ -71,9 +75,10 @@ private: std::list> main_tasks_; std::unique_ptr protocol_; EventGroupHandle_t event_group_; - volatile ChatState chat_state_ = kChatStateUnknown; + volatile DeviceState device_state_ = kDeviceStateUnknown; bool keep_listening_ = false; bool aborted_ = false; + bool voice_detected_ = false; std::string last_iot_states_; // Audio encode / decode diff --git a/main/boards/bread-compact-ml307/compact_ml307_board.cc b/main/boards/bread-compact-ml307/compact_ml307_board.cc index 604871b6..37a53cf0 100644 --- a/main/boards/bread-compact-ml307/compact_ml307_board.cc +++ b/main/boards/bread-compact-ml307/compact_ml307_board.cc @@ -6,7 +6,7 @@ #include "button.h" #include "config.h" #include "iot/thing_manager.h" -#include "led_strip/single_led.h" +#include "led/single_led.h" #include #include @@ -102,9 +102,9 @@ public: InitializeIot(); } - virtual LedStripWrapper* GetLedStrip() override { - static SingleLed led_strip(BUILTIN_LED_GPIO); - return &led_strip; + virtual Led* GetLed() override { + static SingleLed led(BUILTIN_LED_GPIO); + return &led; } virtual AudioCodec* GetAudioCodec() override { diff --git a/main/boards/bread-compact-wifi/compact_wifi_board.cc b/main/boards/bread-compact-wifi/compact_wifi_board.cc index 38b2fe15..b1c78246 100644 --- a/main/boards/bread-compact-wifi/compact_wifi_board.cc +++ b/main/boards/bread-compact-wifi/compact_wifi_board.cc @@ -6,7 +6,7 @@ #include "button.h" #include "config.h" #include "iot/thing_manager.h" -#include "led_strip/single_led.h" +#include "led/single_led.h" #include #include @@ -42,7 +42,7 @@ private: void InitializeButtons() { boot_button_.OnClick([this]() { auto& app = Application::GetInstance(); - if (app.GetChatState() == kChatStateUnknown && !WifiStation::GetInstance().IsConnected()) { + if (app.GetDeviceState() == kDeviceStateStarting && !WifiStation::GetInstance().IsConnected()) { ResetWifiConfiguration(); } app.ToggleChatState(); @@ -107,9 +107,9 @@ public: InitializeIot(); } - virtual LedStripWrapper* GetLedStrip() override { - static SingleLed led_strip(BUILTIN_LED_GPIO); - return &led_strip; + virtual Led* GetLed() override { + static SingleLed led(BUILTIN_LED_GPIO); + return &led; } virtual AudioCodec* GetAudioCodec() override { diff --git a/main/boards/common/board.cc b/main/boards/common/board.cc index e43b210f..b0f61829 100644 --- a/main/boards/common/board.cc +++ b/main/boards/common/board.cc @@ -20,6 +20,10 @@ Display* Board::GetDisplay() { return &display; } +Led* Board::GetLed() { + static NoLed led; + return &led; +} std::string Board::GetJson() { /* diff --git a/main/boards/common/board.h b/main/boards/common/board.h index 6a4bd43d..ce08e763 100644 --- a/main/boards/common/board.h +++ b/main/boards/common/board.h @@ -7,7 +7,7 @@ #include #include -#include "led_strip/led_strip_wrapper.h" +#include "led/led.h" void* create_board(); class AudioCodec; @@ -32,7 +32,7 @@ public: virtual void StartNetwork() = 0; virtual ~Board() = default; - virtual LedStripWrapper* GetLedStrip() = 0; + virtual Led* GetLed() = 0; virtual AudioCodec* GetAudioCodec() = 0; virtual Display* GetDisplay(); virtual Http* CreateHttp() = 0; diff --git a/main/boards/common/led.cc b/main/boards/common/led.cc deleted file mode 100644 index 61ac0285..00000000 --- a/main/boards/common/led.cc +++ /dev/null @@ -1,62 +0,0 @@ -#include "led.h" -#include "board.h" - -#include -#include - -#define TAG "Led" - -Led::Led(gpio_num_t gpio, uint8_t max_leds) { - if (gpio == GPIO_NUM_NC) { - ESP_LOGI(TAG, "Builtin LED not connected"); - return; - } - - led_strip_config_t strip_config = {}; - strip_config.strip_gpio_num = gpio; - strip_config.max_leds = max_leds; - strip_config.led_pixel_format = LED_PIXEL_FORMAT_GRB; - strip_config.led_model = LED_MODEL_WS2812; - - led_strip_rmt_config_t rmt_config = {}; - rmt_config.resolution_hz = 10 * 1000 * 1000; // 10MHz - - max_leds_ = max_leds; - ESP_ERROR_CHECK(led_strip_new_rmt_device(&strip_config, &rmt_config, &led_strip_)); - - led_strip_clear(led_strip_); - SetGrey(); -} - -Led::~Led() { - if (led_strip_ != nullptr) { - led_strip_del(led_strip_); - } -} - -void Led::SetColor(uint8_t r, uint8_t g, uint8_t b) { - r_ = r; - g_ = g; - b_ = b; -} - -void Led::TurnOn() { - if (led_strip_ == nullptr) { - return; - } - - std::lock_guard lock(mutex_); - for (int i = 0; i < max_leds_; i++) { - led_strip_set_pixel(led_strip_, i, r_, g_, b_); - } - led_strip_refresh(led_strip_); -} - -void Led::TurnOff() { - if (led_strip_ == nullptr) { - return; - } - - std::lock_guard lock(mutex_); - led_strip_clear(led_strip_); -} diff --git a/main/boards/common/led.h b/main/boards/common/led.h deleted file mode 100644 index 8cd1858d..00000000 --- a/main/boards/common/led.h +++ /dev/null @@ -1,38 +0,0 @@ -#ifndef _LED_H_ -#define _LED_H_ - -#include -#include -#include -#include - - -#define DEFAULT_BRIGHTNESS 4 -#define HIGH_BRIGHTNESS 16 -#define LOW_BRIGHTNESS 2 - -class Led { -public: - Led(gpio_num_t gpio, uint8_t max_leds); - ~Led(); - - led_strip_handle_t led_strip() { return led_strip_; } - uint8_t max_leds() { return max_leds_; } - - void TurnOn(); - void TurnOff(); - void SetColor(uint8_t r, uint8_t g, uint8_t b); - void SetWhite(uint8_t brightness = DEFAULT_BRIGHTNESS) { SetColor(brightness, brightness, brightness); } - void SetGrey(uint8_t brightness = DEFAULT_BRIGHTNESS) { SetColor(brightness, brightness, brightness); } - void SetRed(uint8_t brightness = DEFAULT_BRIGHTNESS) { SetColor(brightness, 0, 0); } - void SetGreen(uint8_t brightness = DEFAULT_BRIGHTNESS) { SetColor(0, brightness, 0); } - void SetBlue(uint8_t brightness = DEFAULT_BRIGHTNESS) { SetColor(0, 0, brightness); } - -private: - std::mutex mutex_; - uint8_t max_leds_ = -1; - led_strip_handle_t led_strip_ = nullptr; - uint8_t r_ = 0, g_ = 0, b_ = 0; -}; - -#endif // _LED_H_ diff --git a/main/boards/common/ml307_board.cc b/main/boards/common/ml307_board.cc index 3efd8bcd..db3665d9 100644 --- a/main/boards/common/ml307_board.cc +++ b/main/boards/common/ml307_board.cc @@ -46,7 +46,7 @@ void Ml307Board::StartNetwork() { modem_.OnMaterialReady([this, &application]() { ESP_LOGI(TAG, "ML307 material ready"); application.Schedule([this, &application]() { - application.SetChatState(kChatStateIdle); + application.SetDeviceState(kDeviceStateIdle); WaitForNetworkReady(); }); }); diff --git a/main/boards/common/wifi_board.cc b/main/boards/common/wifi_board.cc index 27deca28..cee969e5 100644 --- a/main/boards/common/wifi_board.cc +++ b/main/boards/common/wifi_board.cc @@ -38,14 +38,14 @@ static std::string rssi_to_string(int rssi) { void WifiBoard::StartNetwork() { auto& application = Application::GetInstance(); auto display = Board::GetInstance().GetDisplay(); - auto led_strip = Board::GetInstance().GetLedStrip(); // Try to connect to WiFi, if failed, launch the WiFi configuration AP auto& wifi_station = WifiStation::GetInstance(); display->SetStatus(std::string("正在连接 ") + wifi_station.GetSsid()); wifi_station.Start(); if (!wifi_station.IsConnected()) { - led_strip->LightOn(kConnecting); + application.SetDeviceState(kDeviceStateWifiConfiguring); + auto& wifi_ap = WifiConfigurationAp::GetInstance(); wifi_ap.SetSsidPrefix("Xiaozhi"); wifi_ap.Start(); diff --git a/main/boards/esp-box-3/esp_box3_board.cc b/main/boards/esp-box-3/esp_box3_board.cc index c47c620f..5ef418f9 100644 --- a/main/boards/esp-box-3/esp_box3_board.cc +++ b/main/boards/esp-box-3/esp_box3_board.cc @@ -7,7 +7,6 @@ #include "button.h" #include "config.h" #include "iot/thing_manager.h" -#include "led_strip/single_led.h" #include #include @@ -214,11 +213,6 @@ public: InitializeButtons(); InitializeIot(); } - - virtual LedStripWrapper* GetLedStrip() override { - static SingleLed led_strip(GPIO_NUM_NC); - return &led_strip; - } virtual AudioCodec* GetAudioCodec() override { static BoxAudioCodec* audio_codec = nullptr; diff --git a/main/boards/kevin-box-1/kevin_box_board.cc b/main/boards/kevin-box-1/kevin_box_board.cc index ba79f4f7..f6a9c55f 100644 --- a/main/boards/kevin-box-1/kevin_box_board.cc +++ b/main/boards/kevin-box-1/kevin_box_board.cc @@ -136,9 +136,9 @@ public: InitializeIot(); } - virtual LedStripWrapper* GetLedStrip() override { - static SingleLed led_strip(BUILTIN_LED_GPIO); - return &led_strip; + virtual Led* GetLed() override { + static SingleLed led(BUILTIN_LED_GPIO); + return &led; } virtual AudioCodec* GetAudioCodec() override { diff --git a/main/boards/kevin-box-2/kevin_box_board.cc b/main/boards/kevin-box-2/kevin_box_board.cc index e65be333..5ed8a774 100644 --- a/main/boards/kevin-box-2/kevin_box_board.cc +++ b/main/boards/kevin-box-2/kevin_box_board.cc @@ -6,7 +6,7 @@ #include "config.h" #include "axp2101.h" #include "iot/thing_manager.h" -#include "led_strip/single_led.h" +#include "led/single_led.h" #include #include @@ -46,7 +46,7 @@ private: // 电池放电模式下,如果待机超过一定时间,则自动关机 const int seconds_to_shutdown = 600; static int seconds = 0; - if (Application::GetInstance().GetChatState() != kChatStateIdle) { + if (Application::GetInstance().GetDeviceState() != kDeviceStateIdle) { seconds = 0; return; } @@ -180,9 +180,9 @@ public: InitializeIot(); } - virtual LedStripWrapper* GetLedStrip() override { - static SingleLed led_strip(BUILTIN_LED_GPIO); - return &led_strip; + virtual Led* GetLed() override { + static SingleLed led(BUILTIN_LED_GPIO); + return &led; } virtual AudioCodec* GetAudioCodec() override { diff --git a/main/boards/kevin-c3/kevin_box_board.cc b/main/boards/kevin-c3/kevin_box_board.cc index fac28051..caf9cb81 100644 --- a/main/boards/kevin-c3/kevin_box_board.cc +++ b/main/boards/kevin-c3/kevin_box_board.cc @@ -4,7 +4,7 @@ #include "button.h" #include "config.h" #include "iot/thing_manager.h" -#include "led_strip/multiple_led.h" +#include "led/circular_strip.h" #include #include @@ -38,7 +38,7 @@ private: void InitializeButtons() { boot_button_.OnClick([this]() { auto& app = Application::GetInstance(); - if (app.GetChatState() == kChatStateUnknown && !WifiStation::GetInstance().IsConnected()) { + if (app.GetDeviceState() == kDeviceStateUnknown && !WifiStation::GetInstance().IsConnected()) { ResetWifiConfiguration(); } }); @@ -66,9 +66,9 @@ public: InitializeIot(); } - virtual LedStripWrapper* GetLedStrip() override { - static MultipleLed led_strip(BUILTIN_LED_GPIO, 8); - return &led_strip; + virtual Led* GetLed() override { + static CircularStrip led(BUILTIN_LED_GPIO, 8); + return &led; } virtual AudioCodec* GetAudioCodec() override { diff --git a/main/boards/lichuang-dev/lichuang_dev_board.cc b/main/boards/lichuang-dev/lichuang_dev_board.cc index 257fee0a..996e43bc 100644 --- a/main/boards/lichuang-dev/lichuang_dev_board.cc +++ b/main/boards/lichuang-dev/lichuang_dev_board.cc @@ -6,7 +6,6 @@ #include "config.h" #include "i2c_device.h" #include "iot/thing_manager.h" -#include "led_strip/single_led.h" #include #include @@ -74,7 +73,7 @@ private: void InitializeButtons() { boot_button_.OnClick([this]() { auto& app = Application::GetInstance(); - if (app.GetChatState() == kChatStateUnknown && !WifiStation::GetInstance().IsConnected()) { + if (app.GetDeviceState() == kDeviceStateUnknown && !WifiStation::GetInstance().IsConnected()) { ResetWifiConfiguration(); } }); @@ -135,11 +134,6 @@ public: InitializeIot(); } - virtual LedStripWrapper* GetLedStrip() override { - static SingleLed led_strip(GPIO_NUM_NC); - return &led_strip; - } - virtual AudioCodec* GetAudioCodec() override { static BoxAudioCodec* audio_codec = nullptr; if (audio_codec == nullptr) { diff --git a/main/display/display.cc b/main/display/display.cc index 5b21cedc..50f5190a 100644 --- a/main/display/display.cc +++ b/main/display/display.cc @@ -121,8 +121,8 @@ void Display::Update() { } // 仅在聊天状态为空闲时,读取网络状态(避免升级时占用 UART 资源) - auto chat_state = Application::GetInstance().GetChatState(); - if (chat_state == kChatStateIdle || chat_state == kChatStateUnknown) { + auto device_state = Application::GetInstance().GetDeviceState(); + if (device_state == kDeviceStateIdle || device_state == kDeviceStateStarting) { icon = board.GetNetworkStateIcon(); if (network_icon_ != icon) { network_icon_ = icon; diff --git a/main/led/circular_strip.cc b/main/led/circular_strip.cc new file mode 100644 index 00000000..6be6a083 --- /dev/null +++ b/main/led/circular_strip.cc @@ -0,0 +1,218 @@ +#include "circular_strip.h" +#include "application.h" +#include + +#define TAG "CircularStrip" + +#define DEFAULT_BRIGHTNESS 4 +#define HIGH_BRIGHTNESS 16 +#define LOW_BRIGHTNESS 1 + +#define BLINK_INFINITE -1 + +CircularStrip::CircularStrip(gpio_num_t gpio, uint8_t max_leds) : max_leds_(max_leds) { + // If the gpio is not connected, you should use NoLed class + assert(gpio != GPIO_NUM_NC); + + colors_.resize(max_leds_); + + led_strip_config_t strip_config = {}; + strip_config.strip_gpio_num = gpio; + strip_config.max_leds = max_leds_; + strip_config.led_pixel_format = LED_PIXEL_FORMAT_GRB; + strip_config.led_model = LED_MODEL_WS2812; + + led_strip_rmt_config_t rmt_config = {}; + rmt_config.resolution_hz = 10 * 1000 * 1000; // 10MHz + + ESP_ERROR_CHECK(led_strip_new_rmt_device(&strip_config, &rmt_config, &led_strip_)); + led_strip_clear(led_strip_); + + esp_timer_create_args_t strip_timer_args = { + .callback = [](void *arg) { + auto strip = static_cast(arg); + std::lock_guard lock(strip->mutex_); + if (strip->strip_callback_ != nullptr) { + strip->strip_callback_(); + } + }, + .arg = this, + .dispatch_method = ESP_TIMER_TASK, + .name = "Strip Timer", + .skip_unhandled_events = false, + }; + ESP_ERROR_CHECK(esp_timer_create(&strip_timer_args, &strip_timer_)); +} + +CircularStrip::~CircularStrip() { + esp_timer_stop(strip_timer_); + if (led_strip_ != nullptr) { + led_strip_del(led_strip_); + } +} + + +void CircularStrip::StaticColor(StripColor color) { + std::lock_guard lock(mutex_); + esp_timer_stop(strip_timer_); + for (int i = 0; i < max_leds_; i++) { + colors_[i] = color; + led_strip_set_pixel(led_strip_, i, color.red, color.green, color.blue); + } + led_strip_refresh(led_strip_); +} + +void CircularStrip::Blink(StripColor color, int interval_ms) { + for (int i = 0; i < max_leds_; i++) { + colors_[i] = color; + } + StartStripTask(interval_ms, [this]() { + static bool on = true; + if (on) { + for (int i = 0; i < max_leds_; i++) { + led_strip_set_pixel(led_strip_, i, colors_[i].red, colors_[i].green, colors_[i].blue); + } + led_strip_refresh(led_strip_); + } else { + led_strip_clear(led_strip_); + } + on = !on; + }); +} + +void CircularStrip::FadeOut(int interval_ms) { + StartStripTask(interval_ms, [this]() { + bool all_off = true; + for (int i = 0; i < max_leds_; i++) { + colors_[i].red /= 2; + colors_[i].green /= 2; + colors_[i].blue /= 2; + if (colors_[i].red != 0 || colors_[i].green != 0 || colors_[i].blue != 0) { + all_off = false; + } + led_strip_set_pixel(led_strip_, i, colors_[i].red, colors_[i].green, colors_[i].blue); + } + if (all_off) { + led_strip_clear(led_strip_); + esp_timer_stop(strip_timer_); + } else { + led_strip_refresh(led_strip_); + } + }); +} + +void CircularStrip::Breathe(StripColor low, StripColor high, int interval_ms) { + StartStripTask(interval_ms, [this, low, high]() { + static bool increase = true; + static StripColor color = low; + if (increase) { + if (color.red < high.red) { + color.red++; + } + if (color.green < high.green) { + color.green++; + } + if (color.blue < high.blue) { + color.blue++; + } + if (color.red == high.red && color.green == high.green && color.blue == high.blue) { + increase = false; + } + } else { + if (color.red > low.red) { + color.red--; + } + if (color.green > low.green) { + color.green--; + } + if (color.blue > low.blue) { + color.blue--; + } + if (color.red == low.red && color.green == low.green && color.blue == low.blue) { + increase = true; + } + } + for (int i = 0; i < max_leds_; i++) { + led_strip_set_pixel(led_strip_, i, color.red, color.green, color.blue); + } + led_strip_refresh(led_strip_); + }); +} + +void CircularStrip::Scroll(StripColor low, StripColor high, int length, int interval_ms) { + for (int i = 0; i < max_leds_; i++) { + colors_[i] = low; + } + StartStripTask(interval_ms, [this, low, high, length]() { + static int offset = 0; + for (int i = 0; i < max_leds_; i++) { + colors_[i] = low; + } + for (int j = 0; j < length; j++) { + int i = (offset + j) % max_leds_; + colors_[i] = high; + } + for (int i = 0; i < max_leds_; i++) { + led_strip_set_pixel(led_strip_, i, colors_[i].red, colors_[i].green, colors_[i].blue); + } + led_strip_refresh(led_strip_); + offset = (offset + 1) % max_leds_; + }); +} + +void CircularStrip::StartStripTask(int interval_ms, std::function cb) { + if (led_strip_ == nullptr) { + return; + } + + std::lock_guard lock(mutex_); + esp_timer_stop(strip_timer_); + + strip_callback_ = cb; + esp_timer_start_periodic(strip_timer_, interval_ms * 1000); +} + + +void CircularStrip::OnStateChanged() { + auto& app = Application::GetInstance(); + auto device_state = app.GetDeviceState(); + switch (device_state) { + case kDeviceStateStarting: { + StripColor low = { 0, 0, 0 }; + StripColor high = { LOW_BRIGHTNESS, LOW_BRIGHTNESS, DEFAULT_BRIGHTNESS }; + Scroll(low, high, 3, 100); + break; + } + case kDeviceStateWifiConfiguring: { + StripColor color = { LOW_BRIGHTNESS, LOW_BRIGHTNESS, DEFAULT_BRIGHTNESS }; + Blink(color, 500); + break; + } + case kDeviceStateIdle: + FadeOut(50); + break; + case kDeviceStateConnecting: { + StripColor color = { LOW_BRIGHTNESS, LOW_BRIGHTNESS, DEFAULT_BRIGHTNESS }; + StaticColor(color); + break; + } + case kDeviceStateListening: { + StripColor color = { DEFAULT_BRIGHTNESS, LOW_BRIGHTNESS, LOW_BRIGHTNESS }; + StaticColor(color); + break; + } + case kDeviceStateSpeaking: { + StripColor color = { LOW_BRIGHTNESS, DEFAULT_BRIGHTNESS, LOW_BRIGHTNESS }; + StaticColor(color); + break; + } + case kDeviceStateUpgrading: { + StripColor color = { LOW_BRIGHTNESS, DEFAULT_BRIGHTNESS, LOW_BRIGHTNESS }; + Blink(color, 100); + break; + } + default: + ESP_LOGE(TAG, "Invalid led strip event: %d", device_state); + return; + } +} diff --git a/main/led/circular_strip.h b/main/led/circular_strip.h new file mode 100644 index 00000000..5c684dde --- /dev/null +++ b/main/led/circular_strip.h @@ -0,0 +1,44 @@ +#ifndef _CIRCULAR_STRIP_H_ +#define _CIRCULAR_STRIP_H_ + +#include "led.h" +#include +#include +#include +#include +#include +#include + +struct StripColor { + uint8_t red = 0, green = 0, blue = 0; +}; + +class CircularStrip : public Led { +public: + CircularStrip(gpio_num_t gpio, uint8_t max_leds); + virtual ~CircularStrip(); + + void OnStateChanged() override; + +private: + std::mutex mutex_; + TaskHandle_t blink_task_ = nullptr; + led_strip_handle_t led_strip_ = nullptr; + int max_leds_ = 0; + std::vector colors_; + int blink_counter_ = 0; + int blink_interval_ms_ = 0; + esp_timer_handle_t strip_timer_ = nullptr; + std::function strip_callback_ = nullptr; + + void StartStripTask(int interval_ms, std::function cb); + + void StaticColor(StripColor color); + void Blink(StripColor color, int interval_ms); + void Breathe(StripColor low, StripColor high, int interval_ms); + void Rainbow(StripColor low, StripColor high, int interval_ms); + void Scroll(StripColor low, StripColor high, int length, int interval_ms); + void FadeOut(int interval_ms); +}; + +#endif // _CIRCULAR_STRIP_H_ diff --git a/main/led_strip/led_strip_wrapper.cc b/main/led/led.cc similarity index 96% rename from main/led_strip/led_strip_wrapper.cc rename to main/led/led.cc index d631445d..bc86ab1f 100644 --- a/main/led_strip/led_strip_wrapper.cc +++ b/main/led/led.cc @@ -1,13 +1,13 @@ -#include "led_strip_wrapper.h" +#include "led.h" #include "board.h" #include #include #include -#define TAG "LedStripWrapper" +#define TAG "Led" -LedStripWrapper::LedStripWrapper(gpio_num_t gpio, uint8_t max_leds) { +Led::Led(gpio_num_t gpio, uint8_t max_leds) { if (gpio == GPIO_NUM_NC) { ESP_LOGI(TAG, "Builtin LED not connected"); return; @@ -198,9 +198,9 @@ void LedStripWrapper::BreathLight(LedBasicColor color, uint32_t interval_ms) { } if (increase) { - brightness += 2; + brightness += 1; } else { - brightness -= 2; + brightness -= 1; } }; esp_timer_start_periodic(led_strip_timer_, interval_ms * 1000); diff --git a/main/led/led.h b/main/led/led.h new file mode 100644 index 00000000..251fd6a4 --- /dev/null +++ b/main/led/led.h @@ -0,0 +1,17 @@ +#ifndef _LED_H_ +#define _LED_H_ + +class Led { +public: + virtual ~Led() = default; + // Set the led state based on the device state + virtual void OnStateChanged() = 0; +}; + + +class NoLed : public Led { +public: + virtual void OnStateChanged() override {} +}; + +#endif // _LED_H_ diff --git a/main/led/single_led.cc b/main/led/single_led.cc new file mode 100644 index 00000000..d4df70be --- /dev/null +++ b/main/led/single_led.cc @@ -0,0 +1,158 @@ +#include "single_led.h" +#include "application.h" +#include + +#define TAG "SingleLed" + +#define DEFAULT_BRIGHTNESS 4 +#define HIGH_BRIGHTNESS 16 +#define LOW_BRIGHTNESS 2 + +#define BLINK_INFINITE -1 + + +SingleLed::SingleLed(gpio_num_t gpio) { + // If the gpio is not connected, you should use NoLed class + assert(gpio != GPIO_NUM_NC); + + led_strip_config_t strip_config = {}; + strip_config.strip_gpio_num = gpio; + strip_config.max_leds = 1; + strip_config.led_pixel_format = LED_PIXEL_FORMAT_GRB; + strip_config.led_model = LED_MODEL_WS2812; + + led_strip_rmt_config_t rmt_config = {}; + rmt_config.resolution_hz = 10 * 1000 * 1000; // 10MHz + + ESP_ERROR_CHECK(led_strip_new_rmt_device(&strip_config, &rmt_config, &led_strip_)); + led_strip_clear(led_strip_); + + esp_timer_create_args_t blink_timer_args = { + .callback = [](void *arg) { + auto led = static_cast(arg); + led->OnBlinkTimer(); + }, + .arg = this, + .dispatch_method = ESP_TIMER_TASK, + .name = "Blink Timer", + .skip_unhandled_events = false, + }; + ESP_ERROR_CHECK(esp_timer_create(&blink_timer_args, &blink_timer_)); +} + +SingleLed::~SingleLed() { + esp_timer_stop(blink_timer_); + if (led_strip_ != nullptr) { + led_strip_del(led_strip_); + } +} + + +void SingleLed::SetColor(uint8_t r, uint8_t g, uint8_t b) { + r_ = r; + g_ = g; + b_ = b; +} + +void SingleLed::TurnOn() { + if (led_strip_ == nullptr) { + return; + } + + std::lock_guard lock(mutex_); + esp_timer_stop(blink_timer_); + led_strip_set_pixel(led_strip_, 0, r_, g_, b_); + led_strip_refresh(led_strip_); +} + +void SingleLed::TurnOff() { + if (led_strip_ == nullptr) { + return; + } + + std::lock_guard lock(mutex_); + esp_timer_stop(blink_timer_); + led_strip_clear(led_strip_); +} + +void SingleLed::BlinkOnce() { + Blink(1, 100); +} + +void SingleLed::Blink(int times, int interval_ms) { + StartBlinkTask(times, interval_ms); +} + +void SingleLed::StartContinuousBlink(int interval_ms) { + StartBlinkTask(BLINK_INFINITE, interval_ms); +} + +void SingleLed::StartBlinkTask(int times, int interval_ms) { + if (led_strip_ == nullptr) { + return; + } + + std::lock_guard lock(mutex_); + esp_timer_stop(blink_timer_); + + blink_counter_ = times * 2; + blink_interval_ms_ = interval_ms; + esp_timer_start_periodic(blink_timer_, interval_ms * 1000); +} + +void SingleLed::OnBlinkTimer() { + std::lock_guard lock(mutex_); + blink_counter_--; + if (blink_counter_ & 1) { + led_strip_set_pixel(led_strip_, 0, r_, g_, b_); + led_strip_refresh(led_strip_); + } else { + led_strip_clear(led_strip_); + + if (blink_counter_ == 0) { + esp_timer_stop(blink_timer_); + } + } +} + + +void SingleLed::OnStateChanged() { + auto& app = Application::GetInstance(); + auto device_state = app.GetDeviceState(); + switch (device_state) { + case kDeviceStateStarting: + SetColor(0, 0, DEFAULT_BRIGHTNESS); + StartContinuousBlink(100); + break; + case kDeviceStateWifiConfiguring: + SetColor(0, 0, DEFAULT_BRIGHTNESS); + StartContinuousBlink(500); + break; + case kDeviceStateIdle: + TurnOff(); + break; + case kDeviceStateConnecting: + SetColor(0, 0, DEFAULT_BRIGHTNESS); + TurnOn(); + break; + case kDeviceStateListening: + if (app.IsVoiceDetected()) { + SetColor(HIGH_BRIGHTNESS, 0, 0); + } else { + SetColor(LOW_BRIGHTNESS, 0, 0); + } + TurnOn(); + break; + case kDeviceStateSpeaking: + SetColor(0, DEFAULT_BRIGHTNESS, 0); + TurnOn(); + break; + case kDeviceStateUpgrading: + SetColor(0, DEFAULT_BRIGHTNESS, 0); + StartContinuousBlink(100); + break; + default: + ESP_LOGE(TAG, "Invalid led strip event: %d", device_state); + return; + } +} diff --git a/main/led/single_led.h b/main/led/single_led.h new file mode 100644 index 00000000..b949f747 --- /dev/null +++ b/main/led/single_led.h @@ -0,0 +1,38 @@ +#ifndef _SINGLE_LED_H_ +#define _SINGLE_LED_H_ + +#include "led.h" +#include +#include +#include +#include +#include + +class SingleLed : public Led { +public: + SingleLed(gpio_num_t gpio); + virtual ~SingleLed(); + + void OnStateChanged() override; + +private: + std::mutex mutex_; + TaskHandle_t blink_task_ = nullptr; + led_strip_handle_t led_strip_ = nullptr; + uint8_t r_ = 0, g_ = 0, b_ = 0; + int blink_counter_ = 0; + int blink_interval_ms_ = 0; + esp_timer_handle_t blink_timer_ = nullptr; + + void StartBlinkTask(int times, int interval_ms); + void OnBlinkTimer(); + + void BlinkOnce(); + void Blink(int times, int interval_ms); + void StartContinuousBlink(int interval_ms); + void TurnOn(); + void TurnOff(); + void SetColor(uint8_t r, uint8_t g, uint8_t b); +}; + +#endif // _SINGLE_LED_H_ diff --git a/main/led_strip/led_strip_wrapper.h b/main/led_strip/led_strip_wrapper.h deleted file mode 100644 index 92ca93a8..00000000 --- a/main/led_strip/led_strip_wrapper.h +++ /dev/null @@ -1,58 +0,0 @@ -#ifndef _LED_STRIP_WRAPPER_H_ -#define _LED_STRIP_WRAPPER_H_ - -#include "led.h" - -#define COUNTER_INFINITE -1 - -enum LedStripEvent { - kStartup, - kListening, - kListeningAndSpeaking, - kSpeaking, - kStandby, - kConnecting, - kUpgrading, -}; - -enum LedBasicColor { - kLedColorWhite, - kLedColorGrey, - kLedColorRed, - kLedColorGreen, - kLedColorBlue, -}; - -typedef std::function TimerCallback; - -class LedStripWrapper { -private: - Led* led_ = nullptr; - std::mutex mutex_; - - uint32_t counter_ = 0; - esp_timer_handle_t led_strip_timer_ = nullptr; - TimerCallback timer_callback_; - - void SetLedBasicColor(LedBasicColor color, uint8_t brightness); - void SetLedStripBasicColor(uint8_t index, LedBasicColor color, uint8_t brightness = DEFAULT_BRIGHTNESS); - void StartBlinkTask(uint32_t times, uint32_t interval_ms); - void OnBlinkTimer(); - -public: - LedStripWrapper(gpio_num_t gpio, uint8_t max_leds); - virtual ~LedStripWrapper(); - - void LightOff(); - virtual void LightOn(LedStripEvent event) = 0; - -protected: - void BlinkOnce(LedBasicColor color, uint8_t brightness = DEFAULT_BRIGHTNESS); - void Blink(LedBasicColor color, uint32_t times, uint32_t interval_ms, uint8_t brightness = DEFAULT_BRIGHTNESS); - void ContinuousBlink(LedBasicColor color, uint32_t interval_ms, uint8_t brightness = DEFAULT_BRIGHTNESS); - void StaticLight(LedBasicColor color, uint8_t brightness = DEFAULT_BRIGHTNESS); - void ChasingLight(LedBasicColor base_color, LedBasicColor color, uint32_t interval_ms, uint8_t brightness = DEFAULT_BRIGHTNESS); - void BreathLight(LedBasicColor color, uint32_t interval_ms); -}; - -#endif // _LED_STRIP_WRAPPER_H_ diff --git a/main/led_strip/multiple_led.cc b/main/led_strip/multiple_led.cc deleted file mode 100644 index 8b261d40..00000000 --- a/main/led_strip/multiple_led.cc +++ /dev/null @@ -1,39 +0,0 @@ -#include "multiple_led.h" -#include - -#define TAG "MultipleLed" - -MultipleLed::MultipleLed(gpio_num_t gpio, uint8_t max_leds) : LedStripWrapper(gpio, max_leds) { -} - -MultipleLed::~MultipleLed() { -} - -void MultipleLed::LightOn(LedStripEvent event) { - switch (event) { - case kStartup: - ChasingLight(kLedColorWhite, kLedColorBlue, 100, HIGH_BRIGHTNESS); - break; - case kListeningAndSpeaking: - BreathLight(kLedColorRed, 100); - break; - case kListening: - BreathLight(kLedColorRed, 100); - break; - case kSpeaking: - StaticLight(kLedColorGreen, HIGH_BRIGHTNESS); - break; - case kStandby: - BlinkOnce(kLedColorGreen); - break; - case kConnecting: - Blink(kLedColorBlue, 1000, 500); - break; - case kUpgrading: - ContinuousBlink(kLedColorGreen, 100); - break; - default: - ESP_LOGE(TAG, "Invalid led strip event: %d", event); - return; - } -} diff --git a/main/led_strip/multiple_led.h b/main/led_strip/multiple_led.h deleted file mode 100644 index 14cacd44..00000000 --- a/main/led_strip/multiple_led.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef _LED_STRIP_EFFECT_V2_H_ -#define _LED_STRIP_EFFECT_V2_H_ - -#include "led_strip_wrapper.h" - -class MultipleLed : public LedStripWrapper { -public: - MultipleLed(gpio_num_t gpio, uint8_t max_leds); - virtual ~MultipleLed(); - - void LightOn(LedStripEvent event) override; -}; - -#endif // _LED_STRIP_EFFECT_V2_H_ diff --git a/main/led_strip/single_led.cc b/main/led_strip/single_led.cc deleted file mode 100644 index fd467914..00000000 --- a/main/led_strip/single_led.cc +++ /dev/null @@ -1,39 +0,0 @@ -#include "single_led.h" -#include - -#define TAG "SingleLed" - -SingleLed::SingleLed(gpio_num_t gpio) : LedStripWrapper(gpio, 1) { -} - -SingleLed::~SingleLed() { -} - -void SingleLed::LightOn(LedStripEvent event) { - switch (event) { - case kStartup: - ContinuousBlink(kLedColorBlue, 100); - break; - case kListeningAndSpeaking: - StaticLight(kLedColorRed, HIGH_BRIGHTNESS); - break; - case kListening: - StaticLight(kLedColorRed, LOW_BRIGHTNESS); - break; - case kSpeaking: - StaticLight(kLedColorGreen, HIGH_BRIGHTNESS); - break; - case kStandby: - BlinkOnce(kLedColorGreen); - break; - case kConnecting: - Blink(kLedColorBlue, 1000, 500); - break; - case kUpgrading: - ContinuousBlink(kLedColorGreen, 100); - break; - default: - ESP_LOGE(TAG, "Invalid led strip event: %d", event); - return; - } -} diff --git a/main/led_strip/single_led.h b/main/led_strip/single_led.h deleted file mode 100644 index 1d64ea33..00000000 --- a/main/led_strip/single_led.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef _LED_STRIP_EFFECT_V1_H_ -#define _LED_STRIP_EFFECT_V1_H_ - -#include "led_strip_wrapper.h" - -class SingleLed : public LedStripWrapper { -public: - SingleLed(gpio_num_t gpio); - virtual ~SingleLed(); - - void LightOn(LedStripEvent event) override; -}; - -#endif // _LED_STRIP_EFFECT_V1_H_