From 8ace1095e99bec962109b31de9a90a37652b0617 Mon Sep 17 00:00:00 2001 From: Terrence Date: Fri, 14 Feb 2025 01:15:10 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BD=BF=E7=94=A8=E5=AE=9A=E6=97=B6=E5=99=A8?= =?UTF-8?q?=E8=B0=83=E8=8A=82=E5=B1=8F=E5=B9=95=E4=BA=AE=E5=BA=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- main/display/display.cc | 11 ++++++++ main/display/display.h | 8 +++--- main/display/lcd_display.cc | 52 ++++++++++++++++++++++++++++++------ main/display/lcd_display.h | 11 +++++--- main/display/no_display.h | 4 +-- main/iot/things/blaklight.cc | 23 +++++----------- 6 files changed, 75 insertions(+), 34 deletions(-) diff --git a/main/display/display.cc b/main/display/display.cc index 27f6fd08..23070d21 100644 --- a/main/display/display.cc +++ b/main/display/display.cc @@ -8,10 +8,15 @@ #include "application.h" #include "font_awesome_symbols.h" #include "audio_codec.h" +#include "settings.h" #define TAG "Display" Display::Display() { + // Load brightness from settings + Settings settings("display"); + brightness_ = settings.GetInt("brightness", 100); + // Notification timer esp_timer_create_args_t notification_timer_args = { .callback = [](void *arg) { @@ -206,3 +211,9 @@ void Display::SetIcon(const char* icon) { void Display::SetChatMessage(const std::string &role, const std::string &content) { } + +void Display::SetBacklight(uint8_t brightness) { + Settings settings("display", true); + settings.SetInt("brightness", brightness); + brightness_ = brightness; +} diff --git a/main/display/display.h b/main/display/display.h index 2f7c7f7c..effe679b 100644 --- a/main/display/display.h +++ b/main/display/display.h @@ -23,14 +23,16 @@ public: virtual void SetEmotion(const std::string &emotion); virtual void SetChatMessage(const std::string &role, const std::string &content); virtual void SetIcon(const char* icon); - virtual void SetBacklight(uint8_t brightness) = 0; + virtual void SetBacklight(uint8_t brightness); - int width() const { return width_; } - int height() const { return height_; } + inline int width() const { return width_; } + inline int height() const { return height_; } + inline uint8_t brightness() const { return brightness_; } protected: int width_ = 0; int height_ = 0; + uint8_t brightness_ = 0; lv_display_t *display_ = nullptr; diff --git a/main/display/lcd_display.cc b/main/display/lcd_display.cc index 8b06f750..0279a3ac 100644 --- a/main/display/lcd_display.cc +++ b/main/display/lcd_display.cc @@ -6,6 +6,8 @@ #include #include #include +#include + #include "board.h" #define TAG "LcdDisplay" @@ -13,7 +15,6 @@ LV_FONT_DECLARE(font_awesome_30_4); - LcdDisplay::LcdDisplay(esp_lcd_panel_io_handle_t panel_io, esp_lcd_panel_handle_t panel, gpio_num_t backlight_pin, bool backlight_output_invert, int width, int height, int offset_x, int offset_y, bool mirror_x, bool mirror_y, bool swap_xy, @@ -23,6 +24,18 @@ LcdDisplay::LcdDisplay(esp_lcd_panel_io_handle_t panel_io, esp_lcd_panel_handle_ width_ = width; height_ = height; + // 创建背光渐变定时器 + const esp_timer_create_args_t timer_args = { + .callback = [](void* arg) { + LcdDisplay* display = static_cast(arg); + display->OnBacklightTimer(); + }, + .arg = this, + .dispatch_method = ESP_TIMER_TASK, + .name = "backlight_timer", + .skip_unhandled_events = true, + }; + ESP_ERROR_CHECK(esp_timer_create(&timer_args, &backlight_timer_)); InitializeBacklight(backlight_pin); // draw white @@ -79,12 +92,16 @@ LcdDisplay::LcdDisplay(esp_lcd_panel_io_handle_t panel_io, esp_lcd_panel_handle_ lv_display_set_offset(display_, offset_x, offset_y); } - SetBacklight(100); - SetupUI(); + + SetBacklight(brightness_); } LcdDisplay::~LcdDisplay() { + if (backlight_timer_ != nullptr) { + esp_timer_stop(backlight_timer_); + esp_timer_delete(backlight_timer_); + } // 然后再清理 LVGL 对象 if (content_ != nullptr) { lv_obj_del(content_); @@ -132,7 +149,7 @@ void LcdDisplay::InitializeBacklight(gpio_num_t backlight_pin) { .speed_mode = LEDC_LOW_SPEED_MODE, .duty_resolution = LEDC_TIMER_10_BIT, .timer_num = LEDC_TIMER_0, - .freq_hz = 20000,//背光pwm频率需要高一点,防止电感啸叫 + .freq_hz = 20000, //背光pwm频率需要高一点,防止电感啸叫 .clk_cfg = LEDC_AUTO_CLK, .deconfigure = false }; @@ -141,6 +158,23 @@ void LcdDisplay::InitializeBacklight(gpio_num_t backlight_pin) { ESP_ERROR_CHECK(ledc_channel_config(&backlight_channel)); } +void LcdDisplay::OnBacklightTimer() { + if (current_brightness_ < brightness_) { + current_brightness_++; + } else if (current_brightness_ > brightness_) { + current_brightness_--; + } + + // LEDC resolution set to 10bits, thus: 100% = 1023 + uint32_t duty_cycle = (1023 * current_brightness_) / 100; + ledc_set_duty(LEDC_LOW_SPEED_MODE, LCD_LEDC_CH, duty_cycle); + ledc_update_duty(LEDC_LOW_SPEED_MODE, LCD_LEDC_CH); + + if (current_brightness_ == brightness_) { + esp_timer_stop(backlight_timer_); + } +} + void LcdDisplay::SetBacklight(uint8_t brightness) { if (backlight_pin_ == GPIO_NUM_NC) { return; @@ -151,10 +185,12 @@ void LcdDisplay::SetBacklight(uint8_t brightness) { } ESP_LOGI(TAG, "Setting LCD backlight: %d%%", brightness); - // LEDC resolution set to 10bits, thus: 100% = 1023 - uint32_t duty_cycle = (1023 * brightness) / 100; - ESP_ERROR_CHECK(ledc_set_duty(LEDC_LOW_SPEED_MODE, LCD_LEDC_CH, duty_cycle)); - ESP_ERROR_CHECK(ledc_update_duty(LEDC_LOW_SPEED_MODE, LCD_LEDC_CH)); + // 停止现有的定时器(如果正在运行) + esp_timer_stop(backlight_timer_); + + Display::SetBacklight(brightness); + // 启动定时器,每 5ms 更新一次 + ESP_ERROR_CHECK(esp_timer_start_periodic(backlight_timer_, 5 * 1000)); } bool LcdDisplay::Lock(int timeout_ms) { diff --git a/main/display/lcd_display.h b/main/display/lcd_display.h index db322884..dc72d1c9 100644 --- a/main/display/lcd_display.h +++ b/main/display/lcd_display.h @@ -30,6 +30,9 @@ protected: DisplayFonts fonts_; + esp_timer_handle_t backlight_timer_ = nullptr; + uint8_t current_brightness_ = 0; + void OnBacklightTimer(); void InitializeBacklight(gpio_num_t backlight_pin); virtual void SetupUI(); @@ -43,10 +46,10 @@ public: DisplayFonts fonts); ~LcdDisplay(); - void SetChatMessage(const std::string &role, const std::string &content) override; - void SetEmotion(const std::string &emotion) override; - void SetIcon(const char* icon) override; - void SetBacklight(uint8_t brightness); + virtual void SetChatMessage(const std::string &role, const std::string &content) override; + virtual void SetEmotion(const std::string &emotion) override; + virtual void SetIcon(const char* icon) override; + virtual void SetBacklight(uint8_t brightness) override; }; #endif // LCD_DISPLAY_H diff --git a/main/display/no_display.h b/main/display/no_display.h index f8714d09..e9d4eefe 100644 --- a/main/display/no_display.h +++ b/main/display/no_display.h @@ -7,9 +7,7 @@ class NoDisplay : public Display { private: virtual bool Lock(int timeout_ms = 0) override; virtual void Unlock() override; - virtual void SetBacklight(uint8_t brightness) override { - // 空实现,因为这是一个无显示设备 - } + public: NoDisplay(); ~NoDisplay(); diff --git a/main/iot/things/blaklight.cc b/main/iot/things/blaklight.cc index 81aafede..f0829125 100644 --- a/main/iot/things/blaklight.cc +++ b/main/iot/things/blaklight.cc @@ -13,30 +13,21 @@ class Backlight : public Thing { public: Backlight() : Thing("Backlight", "当前 AI 机器人屏幕的亮度") { // 定义设备的属性 - properties_.AddNumberProperty("light", "当前亮度值", [this]() -> int { + properties_.AddNumberProperty("brightness", "当前亮度值", [this]() -> int { // 这里可以添加获取当前亮度的逻辑 - return current_brightness_; + auto display = Board::GetInstance().GetDisplay(); + return display->brightness(); }); // 定义设备可以被远程执行的指令 - methods_.AddMethod("SetLight", "设置亮度", ParameterList({ - Parameter("light", "0到100之间的整数", kValueTypeNumber, true) + methods_.AddMethod("SetBrightness", "设置亮度", ParameterList({ + Parameter("brightness", "0到100之间的整数", kValueTypeNumber, true) }), [this](const ParameterList& parameters) { auto display = Board::GetInstance().GetDisplay(); - uint8_t target_brightness = static_cast(parameters["light"].number()); - int step = (target_brightness > current_brightness_) ? 1 : -1; - for (int brightness = current_brightness_; brightness != target_brightness; brightness += step) { - display->SetBacklight(static_cast(brightness)); - // 可以根据需要调整渐变速度,这里假设每次调整间隔 10 毫秒 - vTaskDelay(pdMS_TO_TICKS(10)); - } - display->SetBacklight(target_brightness); - current_brightness_ = target_brightness; // 保存当前亮度值 + uint8_t brightness = static_cast(parameters["brightness"].number()); + display->SetBacklight(brightness); }); } - -private: - int current_brightness_ = 100; // 保存当前亮度值 }; } // namespace iot