玩转树莓派屏幕之六:定期息屏
- 树莓派
- 5天前
- 30热度
- 0评论
前言
由于屏幕一直显示,尤其是在晚上,特别刺眼。需要增加个息屏,从MHS35 LCD屏幕引脚中没有发现控制LCD背光的引脚,不能通过硬件实现息屏,只能通过软件了。
解题思路
给最上层的窗口中增加一个矩阵,能够覆盖整个屏幕,矩阵背景设置成黑色,通过透明度控制是否息屏。息屏是不透明,正常工作全透明。
软件实现:
实现部分:
- 创建全局矩阵,父层级为lv_layer_sys,lv_layer_sys为整个屏幕的最上层,就算是右下角的监控部分也能遮盖。
- 创建事件,屏幕有触摸时,刷新显示和延迟等待时间
- while循环控制,定期去算延迟等待时间,满足后就直接continue,并且设置为不透明
还没有研究到LVGL中定时器的用法,所以定时任务没有使用定时器
这样就可以实现了屏幕显示5分钟后,自动息屏。点击屏幕后,又能重新亮起。
// 全局变量:亮度控制层
static lv_obj_t * brightness_cover = NULL;
static uint32_t time_wait_loop = 0;
void set_screen_brightness(int8_t level);
// 全局变量:亮度控制层
void event_handler(lv_event_t* e)
{
lv_event_code_t code = lv_event_get_code(e);
if (code == LV_EVENT_CLICKED)
{
time_wait_loop = 0;
set_screen_brightness(100);
}
}
// 初始化亮度控制层
void init_brightness_control(void) {
// 创建一个覆盖整个屏幕的矩形
brightness_cover = lv_obj_create(lv_layer_sys());
// 设置大小为全屏
lv_obj_set_size(brightness_cover, 480, 320);
lv_obj_add_event_cb(brightness_cover, event_handler, LV_EVENT_ALL, NULL);
// 移动到最顶层
lv_obj_move_foreground(brightness_cover);
// 设置背景颜色为黑色
// lv_obj_set_style_local_bg_color(brightness_cover, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, lv_color_black());
lv_obj_set_style_bg_color(brightness_cover, lv_color_black(), LV_PART_MAIN|LV_STATE_DEFAULT);
// 默认亮度:100%(即覆盖层完全透明,不影响显示)
// lv_obj_set_style_bg_opa(brightness_cover, LV_OBJ_PART_MAIN, LV_STATE_DEFAULT, LV_OPA_0);
lv_obj_set_style_bg_opa(brightness_cover, LV_OPA_0, LV_PART_MAIN|LV_STATE_DEFAULT);
lv_obj_set_style_border_width(brightness_cover, 0, LV_PART_MAIN);
lv_obj_set_style_shadow_width(brightness_cover, 0, LV_PART_MAIN);
}
// 设置亮度 (0-100),0=最暗,100=最亮
void set_screen_brightness(int8_t level) {
if (brightness_cover == NULL) return;
// 将亮度值 (0-100) 转换为 LVGL 的不透明度 (0-255)
// 注意:这里反向映射,因为透明度越高,屏幕越暗
uint8_t opa = (100 - level) * 255 / 100; // 100% 亮度 -> 0 透明度;0% 亮度 -> 255 透明度
// 限制范围
if (opa > 255) opa = 255;
// 设置覆盖层的不透明度
lv_obj_set_style_bg_opa(brightness_cover, opa, LV_PART_MAIN | LV_STATE_DEFAULT);
}
int main()
{
// Timer_Init();
// 初始化LVGL
lv_init();
lv_display_t* disp = lv_linux_fbdev_create();
lv_linux_fbdev_set_file(disp, "/dev/fb0");
tsdev_init();
lv_indev_t * indev = lv_indev_create();
lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER);
lv_indev_set_read_cb(indev, tsdev_read);
lv_indev_set_display(indev, disp);
// lv_example_btn_1();
setup_ui(&guider_ui);
UpdateScreen();
uint32_t last_update = 0;
init_brightness_control();
while (true)
{
uint32_t start_tick = lv_tick_get();
usleep(LVGL_TICK); /*Sleep for 5 millisecond*/
lv_task_handler();
lv_tick_inc(LVGL_TICK); /*Tell LVGL that 5 milliseconds were elapsed*/
if (start_tick - last_update >= 1000) {
last_update = start_tick;
time_wait_loop ++;
if (time_wait_loop > 300) {
set_screen_brightness(0);
continue;
}
// 其他逻辑
UpdateScreen();
}
}
}