| name | LVGL Display Development |
| description | Skill for LVGL (Light and Versatile Graphics Library) UI development on ESP32. Covers widgets, styles, layouts, animations, and display drivers. Use when working with LCD displays, UI components, or graphics. |
| triggers | ["lvgl","display","lcd","ui","widget","lv_","SetChatMessage","ShowNotification","SetStatus","SetEmotion"] |
LVGL Display Development Skill
Overview
LVGL is a free and open-source graphics library for embedded systems with easy-to-use graphical elements.
Version
LVGL 9.x (ESP Component Registry: lvgl/lvgl ^9.4.0)
Installation (ESP-IDF)
# CMakeLists.txt
idf_component_register(
SRCS "main.c"
INCLUDE_DIRS "."
REQUIRES lvgl esp_lcd
)
Core Concepts
1. Display Initialization
#include "lvgl.h"
#include "esp_lcd_panel_io.h"
#include "esp_lcd_panel_vendor.h"
lv_init();
static lv_display_t *disp = lv_display_create(width, height);
lv_display_set_flush_cb(disp, my_flush_cb);
static void my_flush_cb(lv_display_t *disp, const lv_area_t *area, uint8_t *px_map) {
esp_lcd_panel_draw_bitmap(panel, x1, y1, x2+1, y2+1, px_map);
lv_display_flush_ready(disp);
}
2. Basic Widgets
lv_obj_t *label = lv_label_create(lv_screen_active());
lv_label_set_text(label, "Hello World");
lv_obj_center(label);
lv_obj_t *btn = lv_button_create(lv_screen_active());
lv_obj_set_size(btn, 100, 40);
lv_obj_center(btn);
lv_obj_t *img = lv_image_create(lv_screen_active());
lv_image_set_src(img, &my_image);
3. Styling (v9 syntax)
static lv_style_t style;
lv_style_init(&style);
lv_style_set_bg_color(&style, lv_color_hex(0x2196F3));
lv_style_set_radius(&style, 10);
lv_style_set_text_color(&style, lv_color_white());
lv_style_set_text_font(&style, &lv_font_montserrat_16);
lv_obj_add_style(obj, &style, 0);
4. Layouts
lv_obj_set_flex_flow(parent, LV_FLEX_FLOW_ROW);
lv_obj_set_flex_align(parent, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER, LV_FLEX_ALIGN_CENTER);
static lv_coord_t col_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(1), LV_GRID_TEMPLATE_LAST};
static lv_coord_t row_dsc[] = {LV_GRID_FR(1), LV_GRID_FR(1), LV_GRID_TEMPLATE_LAST};
lv_obj_set_grid_dsc_array(parent, col_dsc, row_dsc);
5. Events
static void btn_event_cb(lv_event_t *e) {
lv_event_code_t code = lv_event_get_code(e);
if(code == LV_EVENT_CLICKED) {
ESP_LOGI(TAG, "Button clicked!");
}
}
lv_obj_add_event_cb(btn, btn_event_cb, LV_EVENT_CLICKED, NULL);
6. Animations
lv_anim_t a;
lv_anim_init(&a);
lv_anim_set_var(&a, obj);
lv_anim_set_values(&a, 0, 100);
lv_anim_set_duration(&a, 500);
lv_anim_set_exec_cb(&a, [](void *var, int32_t v) {
lv_obj_set_x((lv_obj_t*)var, v);
});
lv_anim_start(&a);
Xiaozhi Display Pattern
Display Interface
class Display {
public:
virtual void SetStatus(const char* status) = 0;
virtual void SetChatMessage(const char* role, const char* message) = 0;
virtual void ShowNotification(const char* text) = 0;
virtual void SetEmotion(const char* emotion) = 0;
virtual void ClearQRCode() = 0;
};
Usage Example
auto display = Board::GetInstance().GetDisplay();
display->SetStatus(Lang::Strings::STANDBY);
display->SetChatMessage("assistant", "Hello!");
display->SetEmotion("happy");
display->ShowNotification("Connected to WiFi");
Supported Display Drivers (ESP32)
- ILI9341 (2.8" TFT)
- ST7789 (1.3", 1.54", 2.0")
- SSD1306 (OLED)
- GC9A01 (Round display)
Memory Optimization
LV_ATTRIBUTE_MEM_ALIGN static uint8_t buf1[DISP_BUF_SIZE];
lv_display_set_buffers(disp, buf1, NULL, sizeof(buf1), LV_DISPLAY_RENDER_MODE_PARTIAL);
Resources