Display an LVGL splash (Welcome) screen and jump automatically to Main screen after 3 seconds

Description

Cannot display a splash (Welcome) screen and jump automatically to Main screen after 3 seconds.

What MCU/Processor/Board and compiler are you using?

ESP32 Dev Module

What LVGL version are you using?

9.2.0

What do you want to achieve?

I want to create at least 2 screens (Welcome and Main) where the Welcome screen will be displayed for 3 seconds and then automatically display the Main screen.

What have you tried so far?

I tried several options in setup() section, but none of them have worked:

  1. Creating all screens at once and then trying to display the Welcome screen, but the last screen created (Main) is displayed instead. Welcome screen is not displayed; it displays only the Main screen.
// Create all UI screens
ui_ScreenWelcome_screen_init();  //Welcome screen first
ui_ScreenMain_screen_init();
lv_scr_load(ui_ScreenWelcome);  // Display Welcome screen
delay(3000);
lv_scr_load(ui_ScreenMain);     // Display Main screen
  1. Creating all screens at once in reverse order (Welcome screen at last) and then trying to display the Welcome screen, but Welcome screen is not displayed; it displays only the Main screen.
// Create all UI screens
ui_ScreenMain_screen_init();
ui_ScreenWelcome_screen_init();  //Welcome screen at last
lv_scr_load(ui_ScreenWelcome);  // Display Welcome screen
delay(3000);
lv_scr_load(ui_ScreenMain);     // Display Main screen
  1. Creating the Welcome screen and then display it and then create the Main screen and display it. Welcome screen is not displayed; it displays only the Main screen.
ui_ScreenWelcome_screen_init();  //Create Welcome screen
lv_scr_load(ui_ScreenWelcome);  // Display Welcome screen
delay(3000);
ui_ScreenMain_screen_init();  //Create Main screen
lv_scr_load(ui_ScreenMain);     // Display Main screen

Code to reproduce

#include <lvgl.h>
#include <TFT_eSPI.h>  // TFT 3.2 Display (240x320)

// UI variables
// Welcome screen
lv_obj_t * ui_ScreenWelcome;
lv_obj_t * ui_Label1;

// Main screen
lv_obj_t * ui_ScreenMain;
lv_obj_t * ui_ScreenMain_TextArea1;

#define SCREEN_WIDTH  240
#define SCREEN_HEIGHT 320

TFT_eSPI tft = TFT_eSPI();  // Create TFT LCD variable for 3.2" TFT with ILI9341

/*LVGL draw into this buffer, 1/10 screen size usually works well. The size is in bytes*/
#define DRAW_BUF_SIZE (SCREEN_WIDTH * SCREEN_HEIGHT / 10 * (LV_COLOR_DEPTH / 8))
uint32_t draw_buf[DRAW_BUF_SIZE / 4];

// Set screen rotation
#define TFT_ROTATION         1
#define LVGL_ROTATION        LV_DISPLAY_ROTATION_270

//  Colors definition
#define COLOR_TEXT 0x059f  //0x8E5E
lv_color_t COLOR_TEXT_LVGL = lv_color_hex(0xFFFFFF);

void setup() {
Serial.begin(115200);

lv_init();  // Initialize LVGL

tft.setRotation(TFT_ROTATION);

lv_display_t * disp;
// Initialize the TFT display using the TFT_eSPI library
disp = lv_tft_espi_create(SCREEN_WIDTH, SCREEN_HEIGHT, draw_buf, sizeof(draw_buf));
lv_display_set_rotation(disp, LVGL_ROTATION);

// Create all UI screens
ui_ScreenWelcome_screen_init();
//ui_ScreenMain_screen_init();

lv_scr_load(ui_ScreenWelcome);  // Display Welcome screen

/*
lv_task_t *pMytask = lv_task_create_basic();
lv_task_set_period(pMytask, 2000ms);
lv_task_once(pMytask);
*/
/*
lv_timer_t * timer = lv_timer_create(NULL, 3000, NULL);
lv_timer_ready(timer);
*/
delay(3000);
ui_ScreenMain_screen_init();
lv_scr_load(ui_ScreenMain);     // Display Main screen

}

//------------------------------------------------------------------------
void loop() {
lv_task_handler();  // let the GUI do its work
lv_tick_inc(5);     // tell LVGL how much time has passed
delay(5);           // let this time pass
}

void ui_ScreenWelcome_screen_init(void)
{
ui_ScreenWelcome = lv_obj_create(NULL);
lv_obj_clear_flag(ui_ScreenWelcome, LV_OBJ_FLAG_SCROLLABLE);      /// Flags
lv_obj_set_style_bg_color(ui_ScreenWelcome, lv_color_hex(0x000000), LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_bg_opa(ui_ScreenWelcome, 255, LV_PART_MAIN | LV_STATE_DEFAULT);

ui_Label1 = lv_label_create(ui_ScreenWelcome);
lv_obj_set_width(ui_Label1, LV_SIZE_CONTENT);   /// 1
lv_obj_set_height(ui_Label1, LV_SIZE_CONTENT);    /// 1
lv_obj_set_x(ui_Label1, lv_pct(0));
lv_obj_set_y(ui_Label1, lv_pct(-35));
lv_obj_set_align(ui_Label1, LV_ALIGN_CENTER);
lv_label_set_text(ui_Label1, "Welcome screen");
lv_obj_set_style_text_color(ui_Label1, COLOR_TEXT_LVGL, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_text_opa(ui_Label1, 255, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_text_font(ui_Label1, &lv_font_montserrat_42, LV_PART_MAIN | LV_STATE_DEFAULT);
}  // ui_ScreenWelcome_screen_init

//------------------------------------------------------------------------
void ui_ScreenMain_screen_init(void)
{
ui_ScreenMain = lv_obj_create(NULL);
lv_obj_clear_flag(ui_ScreenMain, LV_OBJ_FLAG_SCROLLABLE);      /// Flags
lv_obj_set_style_bg_color(ui_ScreenMain, lv_color_hex(0x000000), LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_bg_opa(ui_ScreenMain, 255, LV_PART_MAIN | LV_STATE_DEFAULT);

ui_ScreenMain_TextArea1 = lv_textarea_create(ui_ScreenMain);
lv_obj_set_width(ui_ScreenMain_TextArea1, 188);
lv_obj_set_height(ui_ScreenMain_TextArea1, 32);
lv_obj_set_x(ui_ScreenMain_TextArea1, 0);
lv_obj_set_y(ui_ScreenMain_TextArea1, 2);
lv_obj_set_align(ui_ScreenMain_TextArea1, LV_ALIGN_CENTER);
lv_textarea_set_text(ui_ScreenMain_TextArea1, "Main screen");
lv_obj_set_style_text_align(ui_ScreenMain_TextArea1, LV_TEXT_ALIGN_CENTER, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_text_font(ui_ScreenMain_TextArea1, &lv_font_montserrat_18, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_border_color(ui_ScreenMain_TextArea1, lv_color_hex(0xFFFFFF), LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_border_opa(ui_ScreenMain_TextArea1, 255, LV_PART_MAIN | LV_STATE_DEFAULT);
}  // ui_ScreenMain_screen_init

Add LV_EVENT_SCREEN_LOADED event callback to the welcome screen then load main screen from this callback after 3000ms.

void ui_ScreenWelcome_loaded_cb(lv_event_t *e)
{
    /* load main screen after 3000ms */
    lv_screen_load_anim(ui_ScreenMain, LV_SCR_LOAD_ANIM_FADE_ON, 500, 3000, false);
}

void ui_ScreenWelcome_screen_init(void)
{
    /*
    * your previous code here
    */

    lv_obj_add_event_cb(ui_ScreenWelcome, ui_ScreenWelcome_loaded_cb, LV_EVENT_SCREEN_LOADED, NULL);
}


void setup()
{
    /*
    * your previous code here
    */

    // Create all UI screens
    ui_ScreenWelcome_screen_init();
    ui_ScreenMain_screen_init();

    /* Load only welcome screen */
    lv_scr_load(ui_ScreenWelcome);  // Display Welcome screen

    /**
     * Remove rest of code below. Not necessary anymore
     * delay(3000);
     * ui_ScreenMain_screen_init();
     * lv_scr_load(ui_ScreenMain);     // Display Main screen
     */
}

Thanks fbiego, it works perfectly. It displays Welcome screen for 3 seconds and then fades out and displays Main screen.

I just don’t understand why I don’t have to call the following line to display Main screen:

lv_scr_load(ui_ScreenMain);

How come the Main screen is displayed if I didn’t call it to be displayed?

lv_screen_load_anim(ui_ScreenMain, LV_SCR_LOAD_ANIM_FADE_ON, 500, 3000, false); can display main screen

Thanks * lizhaoming634*. I just realized that the line of code you mentioned is executed as part of the call back function that runs when the Welcome screen is loaded.

Hello @fbiego,
Thank you for your solution, but I have a quick question for you ; If I add “ui_ScreenWelcome_loaded_cb” and “ui_ScreenWelcome_screen_init” functions directly in the main.cpp I can compile but I got a kernel panic in the start after uploading, I can get it work only if I add the two functions in ScreenWelcome.c UI file, given I use SquareLine Studio, this file is overriden each time when I make a changes in the UI.
What do you think the problem is ?

Thank you

@Kanzll you can add this flow directly in squareline studio.
In your bootScreen add an event as below.

You can also write the line to run the callback function in the setup portion right after creating (init) the screen:

void ui_ScreenWelcome_loaded_cb(lv_event_t *e)
{
    /* load main screen after 3000ms */
    lv_screen_load_anim(ui_ScreenMain, LV_SCR_LOAD_ANIM_FADE_ON, 500, 3000, false);
}

void ui_ScreenWelcome_screen_init(void)
{
    /*
    * your code to create the screen, but do not call the callback function
    */
}


void setup()
{
    /*
    * your previous code here
    */

    // Create all UI screens
    ui_ScreenWelcome_screen_init();
    ui_ScreenMain_screen_init();

    // Run the callback function after creating (init) the screens
    lv_obj_add_event_cb(ui_ScreenWelcome, ui_ScreenWelcome_loaded_cb, LV_EVENT_SCREEN_LOADED, NULL);

    /* Load only welcome screen */
    lv_scr_load(ui_ScreenWelcome);  // Display Welcome screen

    /**
     * Remove rest of code below. Not necessary anymore
     * delay(3000);
     * ui_ScreenMain_screen_init();
     * lv_scr_load(ui_ScreenMain);     // Display Main screen
     */
}
1 Like