2 screen LVGL UI code with EEZ
How to use EEZ generated code in Lilygo
First Steps
We’ll begin like any other ESP-IDF project: select the microcontroller type, choose the template, and so on.
The next step is to add the LVGL component from Espressif’s component registry page:

However, make sure to pick an older release within the 8.x series. You can do this by directly editing the add-dependency command, or by switching to the Versions tab and selecting your desired version to reach an identical page configured for that release.
In the same way, add the other drivers required by the LilyGo board:
esp_lcd_touchesp_lcd_touch_cst816s
Next, you’ll need the specific driver for the LilyGo. I adapted the code from this GitHub repository: https://github.com/krupis/T-Display-S3-esp-idf
Component Configuration
Before using any components—both LVGL and the board driver—you must update the CMakeLists.txt files so that they recognize and include those components.
Main CMakeLists
This file only has general purpose components
idf_component_register(
SRCS
"main.c"
INCLUDE_DIRS
"."
REQUIRES
lvgl_setup
nvs_flash
spi_flash
)
Driver CMakeLists
Since this component is designed to manage LVGL together with the display, it must be familiar with LVGL itself as well as the drivers for the display, both the LCD and the touchscreen.
idf_component_register(
SRCS
"lvgl_setup.c"
"eez_studio/images.c"
"eez_studio/screens.c"
"eez_studio/styles.c"
"eez_studio/ui.c"
"eez_studio/actions.c"
"eez_studio/eez-flow.cpp"
INCLUDE_DIRS
"."
"eez_studio"
REQUIRES
lvgl esp_lcd esp_timer heap driver esp_lcd_touch_cst816s
)
All files in
eez_studiowill be covered delow in another section
Menuconfig
Part of the component configuration involves adjusting them from the menuconfig. This menu can be opened either from the SDK configuration editor tool or by running idf.py menuconfig from an ESP-IDF terminal.
In either case, you will need to adjust a series of parameters, or rather, make sure that they are those parameters, as they may already be selected by default
| Parameter | Value |
|---|---|
| Color depth | 16 RGB565 |
| Swap the 2 bytes of RGB565 * | ? |
The case of swap the 2 bytes may depend on your setup. Basically, you will have to activate it if, when you upload the code, the colors do not match those you have defined in the program. In my case with EEZ, I had to activate it
Files generated by EEZ
As we mentioned in the post dedicated to creating UI from EEZ and as we mentioned in main CMakeLists.txt, the software generates a series of files that we do not touch, and whose content is essentially irrelevant to us, except for two files (one created by the program and the other by us).
I am referring to actions.h (already generated) and actions.c (which we must generate ourselves). The first contains the names of the custom handlers we have defined in EEZ, and the second is where we will implement the logic.
actions.h
#ifndef EEZ_LVGL_UI_EVENTS_H
#define EEZ_LVGL_UI_EVENTS_H
#include <lvgl.h>
#ifdef __cplusplus
extern "C" {
#endif
extern void action_hello_text(lv_event_t * e);
#ifdef __cplusplus
}
#endif
#endif /*EEZ_LVGL_UI_EVENTS_H*/
actions.c
#include "actions.h"
#include "esp_log.h"
extern void action_hello_text(lv_event_t * e){
ESP_LOGI("EEZ", "Hello from action_hello_text!");
}
Driver and LVGL
The main file contains a series of functions for handling touch and other things, but the important part is understanding how to deal with the preset files, as all of this will depend on how you have implemented the driver.
The main function, which will carry out all the necessary initializations and function executions, is lvgl_setup, and in it, the key point is the execution of the ui_init function, which is in the eez file ui.c.
This function is responsible for loading the first of the UI screens, which by default, regardless of the eez name, will be the first one created in eez; the one with the original name Main, but if we have changed the name, it will not matter.
Main
In the main, we only need to define a task for LVGL and then make a call to initialize LVGL.
#include <stdio.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "esp_timer.h"
#include "esp_lcd_panel_io.h"
#include "esp_lcd_panel_vendor.h"
#include "esp_lcd_panel_ops.h"
#include "nvs_flash.h"
#include "esp_chip_info.h"
#include "esp_flash.h"
#include "esp_err.h"
#include "esp_log.h"
#include "lvgl.h"
#include "lvgl_setup.h" // Driver
void lvgl_task(void *pvParameter){
while (1) {
// Manejar los temporizadores de LVGL
lv_timer_handler();
vTaskDelay(pdMS_TO_TICKS(10)); // Ajusta el retardo según sea necesario
}
}
void app_main(void){
// Driver
lvgl_setup();
// Task handler
xTaskCreatePinnedToCore(lvgl_task, "lvgl_task", 4096, NULL, 5, NULL, 1);
}