diff --git a/main/boards/kevin-c3/kevin_c3_board.cc b/main/boards/kevin-c3/kevin_c3_board.cc index f28ad2a..ab51c60 100644 --- a/main/boards/kevin-c3/kevin_c3_board.cc +++ b/main/boards/kevin-c3/kevin_c3_board.cc @@ -5,6 +5,7 @@ #include "config.h" #include "iot/thing_manager.h" #include "led/circular_strip.h" +#include "led_strip_control.h" #include #include @@ -17,6 +18,7 @@ class KevinBoxBoard : public WifiBoard { private: i2c_master_bus_handle_t codec_i2c_bus_; Button boot_button_; + CircularStrip* led_strip_; void InitializeCodecI2c() { // Initialize I2C peripheral @@ -54,6 +56,10 @@ private: void InitializeIot() { auto& thing_manager = iot::ThingManager::GetInstance(); thing_manager.AddThing(iot::CreateThing("Speaker")); + + led_strip_ = new CircularStrip(BUILTIN_LED_GPIO, 8); + auto led_strip_control = new LedStripControl(led_strip_); + thing_manager.AddThing(led_strip_control); } public: @@ -67,8 +73,7 @@ public: } virtual Led* GetLed() override { - static CircularStrip led(BUILTIN_LED_GPIO, 8); - return &led; + return led_strip_; } virtual AudioCodec* GetAudioCodec() override { diff --git a/main/boards/kevin-c3/led_strip_control.cc b/main/boards/kevin-c3/led_strip_control.cc new file mode 100644 index 0000000..48634c0 --- /dev/null +++ b/main/boards/kevin-c3/led_strip_control.cc @@ -0,0 +1,123 @@ +#include "led_strip_control.h" +#include "settings.h" +#include + +#define TAG "LedStripControl" + + +int LedStripControl::LevelToBrightness(int level) const { + if (level < 0) level = 0; + if (level > 8) level = 8; + return (1 << level) - 1; // 2^n - 1 +} + +StripColor LedStripControl::RGBToColor(int red, int green, int blue) { + if (red < 0) red = 0; + if (red > 255) red = 255; + if (green < 0) green = 0; + if (green > 255) green = 255; + if (blue < 0) blue = 0; + if (blue > 255) blue = 255; + return {static_cast(red), static_cast(green), static_cast(blue)}; +} + +LedStripControl::LedStripControl(CircularStrip* led_strip) + : Thing("LedStripControl", "LED 灯带控制,一共有8个灯珠"), led_strip_(led_strip) { + // 从设置中读取亮度等级 + Settings settings("led_strip"); + brightness_level_ = settings.GetInt("brightness", 4); // 默认等级4 + led_strip_->SetBrightness(LevelToBrightness(brightness_level_), 4); + + // 定义设备的属性 + properties_.AddNumberProperty("brightness", "对话时的亮度等级(0-8)", [this]() -> int { + return brightness_level_; + }); + + // 定义设备可以被远程执行的指令 + methods_.AddMethod("SetBrightness", "设置对话时的亮度等级", ParameterList({ + Parameter("level", "亮度等级(0-8)", kValueTypeNumber, true) + }), [this](const ParameterList& parameters) { + int level = static_cast(parameters["level"].number()); + ESP_LOGI(TAG, "Set LedStrip brightness level to %d", level); + + if (level < 0) level = 0; + if (level > 8) level = 8; + + brightness_level_ = level; + led_strip_->SetBrightness(LevelToBrightness(brightness_level_), 4); + + // 保存设置 + Settings settings("led_strip", true); + settings.SetInt("brightness", brightness_level_); + }); + + methods_.AddMethod("SetSingleColor", "设置单个灯颜色", ParameterList({ + Parameter("index", "灯珠索引(0-7)", kValueTypeNumber, true), + Parameter("red", "红色(0-255)", kValueTypeNumber, true), + Parameter("green", "绿色(0-255)", kValueTypeNumber, true), + Parameter("blue", "蓝色(0-255)", kValueTypeNumber, true) + }), [this](const ParameterList& parameters) { + int index = parameters["index"].number(); + StripColor color = RGBToColor( + parameters["red"].number(), + parameters["green"].number(), + parameters["blue"].number() + ); + ESP_LOGI(TAG, "Set led strip single color %d to %d, %d, %d", + index, color.red, color.green, color.blue); + led_strip_->SetSingleColor(index, color); + }); + + methods_.AddMethod("SetAllColor", "设置所有灯颜色", ParameterList({ + Parameter("red", "红色(0-255)", kValueTypeNumber, true), + Parameter("green", "绿色(0-255)", kValueTypeNumber, true), + Parameter("blue", "蓝色(0-255)", kValueTypeNumber, true) + }), [this](const ParameterList& parameters) { + StripColor color = RGBToColor( + parameters["red"].number(), + parameters["green"].number(), + parameters["blue"].number() + ); + ESP_LOGI(TAG, "Set led strip color to %d, %d, %d", + color.red, color.green, color.blue + ); + led_strip_->SetAllColor(color); + }); + + methods_.AddMethod("Blink", "闪烁动画", ParameterList({ + Parameter("red", "红色(0-255)", kValueTypeNumber, true), + Parameter("green", "绿色(0-255)", kValueTypeNumber, true), + Parameter("blue", "蓝色(0-255)", kValueTypeNumber, true), + Parameter("interval", "间隔(ms)", kValueTypeNumber, true) + }), [this](const ParameterList& parameters) { + int interval = parameters["interval"].number(); + StripColor color = RGBToColor( + parameters["red"].number(), + parameters["green"].number(), + parameters["blue"].number() + ); + ESP_LOGI(TAG, "Blink led strip with color %d, %d, %d, interval %dms", + color.red, color.green, color.blue, interval); + led_strip_->Blink(color, interval); + }); + + methods_.AddMethod("Scroll", "跑马灯动画", ParameterList({ + Parameter("red", "红色(0-255)", kValueTypeNumber, true), + Parameter("green", "绿色(0-255)", kValueTypeNumber, true), + Parameter("blue", "蓝色(0-255)", kValueTypeNumber, true), + Parameter("length", "滚动条长度(1-7)", kValueTypeNumber, true), + Parameter("interval", "间隔(ms)", kValueTypeNumber, true) + }), [this](const ParameterList& parameters) { + int interval = parameters["interval"].number(); + int length = parameters["length"].number(); + StripColor low = RGBToColor(4, 4, 4); + StripColor high = RGBToColor( + parameters["red"].number(), + parameters["green"].number(), + parameters["blue"].number() + ); + ESP_LOGI(TAG, "Scroll led strip with color %d, %d, %d, length %d, interval %dms", + high.red, high.green, high.blue, length, interval); + led_strip_->Scroll(low, high, length, interval); + }); +} diff --git a/main/boards/kevin-c3/led_strip_control.h b/main/boards/kevin-c3/led_strip_control.h new file mode 100644 index 0000000..d8cf832 --- /dev/null +++ b/main/boards/kevin-c3/led_strip_control.h @@ -0,0 +1,21 @@ +#ifndef LED_STRIP_CONTROL_H +#define LED_STRIP_CONTROL_H + +#include "iot/thing.h" +#include "led/circular_strip.h" + +using namespace iot; + +class LedStripControl : public Thing { +private: + CircularStrip* led_strip_; + int brightness_level_; // 亮度等级 (0-8) + + int LevelToBrightness(int level) const; // 将等级转换为实际亮度值 + StripColor RGBToColor(int red, int green, int blue); + +public: + explicit LedStripControl(CircularStrip* led_strip); +}; + +#endif // LED_STRIP_CONTROL_H diff --git a/main/led/circular_strip.cc b/main/led/circular_strip.cc index 53eafa9..936a328 100644 --- a/main/led/circular_strip.cc +++ b/main/led/circular_strip.cc @@ -4,10 +4,6 @@ #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) { @@ -52,7 +48,7 @@ CircularStrip::~CircularStrip() { } -void CircularStrip::StaticColor(StripColor color) { +void CircularStrip::SetAllColor(StripColor color) { std::lock_guard lock(mutex_); esp_timer_stop(strip_timer_); for (int i = 0; i < max_leds_; i++) { @@ -62,6 +58,14 @@ void CircularStrip::StaticColor(StripColor color) { led_strip_refresh(led_strip_); } +void CircularStrip::SetSingleColor(uint8_t index, StripColor color) { + std::lock_guard lock(mutex_); + esp_timer_stop(strip_timer_); + colors_[index] = color; + led_strip_set_pixel(led_strip_, index, 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; @@ -172,6 +176,11 @@ void CircularStrip::StartStripTask(int interval_ms, std::function cb) { esp_timer_start_periodic(strip_timer_, interval_ms * 1000); } +void CircularStrip::SetBrightness(uint8_t default_brightness, uint8_t low_brightness) { + default_brightness_ = default_brightness; + low_brightness_ = low_brightness; + OnStateChanged(); +} void CircularStrip::OnStateChanged() { auto& app = Application::GetInstance(); @@ -179,12 +188,12 @@ void CircularStrip::OnStateChanged() { switch (device_state) { case kDeviceStateStarting: { StripColor low = { 0, 0, 0 }; - StripColor high = { LOW_BRIGHTNESS, LOW_BRIGHTNESS, DEFAULT_BRIGHTNESS }; + StripColor high = { low_brightness_, low_brightness_, default_brightness_ }; Scroll(low, high, 3, 100); break; } case kDeviceStateWifiConfiguring: { - StripColor color = { LOW_BRIGHTNESS, LOW_BRIGHTNESS, DEFAULT_BRIGHTNESS }; + StripColor color = { low_brightness_, low_brightness_, default_brightness_ }; Blink(color, 500); break; } @@ -192,27 +201,27 @@ void CircularStrip::OnStateChanged() { FadeOut(50); break; case kDeviceStateConnecting: { - StripColor color = { LOW_BRIGHTNESS, LOW_BRIGHTNESS, DEFAULT_BRIGHTNESS }; - StaticColor(color); + StripColor color = { low_brightness_, low_brightness_, default_brightness_ }; + SetAllColor(color); break; } case kDeviceStateListening: { - StripColor color = { DEFAULT_BRIGHTNESS, LOW_BRIGHTNESS, LOW_BRIGHTNESS }; - StaticColor(color); + StripColor color = { default_brightness_, low_brightness_, low_brightness_ }; + SetAllColor(color); break; } case kDeviceStateSpeaking: { - StripColor color = { LOW_BRIGHTNESS, DEFAULT_BRIGHTNESS, LOW_BRIGHTNESS }; - StaticColor(color); + StripColor color = { low_brightness_, default_brightness_, low_brightness_ }; + SetAllColor(color); break; } case kDeviceStateUpgrading: { - StripColor color = { LOW_BRIGHTNESS, DEFAULT_BRIGHTNESS, LOW_BRIGHTNESS }; + StripColor color = { low_brightness_, default_brightness_, low_brightness_ }; Blink(color, 100); break; } case kDeviceStateActivating: { - StripColor color = { LOW_BRIGHTNESS, DEFAULT_BRIGHTNESS, LOW_BRIGHTNESS }; + StripColor color = { low_brightness_, default_brightness_, low_brightness_ }; Blink(color, 500); break; } diff --git a/main/led/circular_strip.h b/main/led/circular_strip.h index 5c684dd..d5d6c22 100644 --- a/main/led/circular_strip.h +++ b/main/led/circular_strip.h @@ -9,6 +9,9 @@ #include #include +#define DEFAULT_BRIGHTNESS 32 +#define LOW_BRIGHTNESS 4 + struct StripColor { uint8_t red = 0, green = 0, blue = 0; }; @@ -19,6 +22,12 @@ public: virtual ~CircularStrip(); void OnStateChanged() override; + void SetBrightness(uint8_t default_brightness, uint8_t low_brightness); + void SetAllColor(StripColor color); + void SetSingleColor(uint8_t index, StripColor color); + void Blink(StripColor color, int interval_ms); + void Breathe(StripColor low, StripColor high, int interval_ms); + void Scroll(StripColor low, StripColor high, int length, int interval_ms); private: std::mutex mutex_; @@ -31,13 +40,11 @@ private: esp_timer_handle_t strip_timer_ = nullptr; std::function strip_callback_ = nullptr; - void StartStripTask(int interval_ms, std::function cb); + uint8_t default_brightness_ = DEFAULT_BRIGHTNESS; + uint8_t low_brightness_ = LOW_BRIGHTNESS; - void StaticColor(StripColor color); - void Blink(StripColor color, int interval_ms); - void Breathe(StripColor low, StripColor high, int interval_ms); + void StartStripTask(int interval_ms, std::function cb); 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); };