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.

1 Like

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