Description
Hello, I have a problem with refreshing GUI, because sometimes appears some kind of glitch (mostly on bottom side of display but simetimes whole screen). The screen is a little bit moved to the right, and then come back to the correct position.
It’s happen more often when there is some animation.
I have no idea what can I change to fix this behavior. Do you have explanation of this ? How can I fix it ?
What MCU/Processor/Board and compiler are you using?
MCU: ESP32-S3 WROOM 1
GUI: ESP32-8048S070 SPI, 800x480
Arduino/Platformio
What LVGL version are you using?
8.2.0
What do you want to achieve?
Screen not moving to the right side periodactly.
What have you tried so far?
I was trying to increase buffers:
LV_MEM_SIZE
to 60 * 1024 (alsoLV_MEM_CUSTOM
form 0 to 1)LV_MEM_BUF_MAX_NUM
to 32LV_MEMCPY_MEMSET_STD
to 1lv_disp_draw_buf_init(.. , disp_draw_buf, ..)
to 256 kB (ESP has around 350).LV_DISP_DEF_REFR_PERIOD
to 40LV_INDEV_DEF_READ_PERIOD
to 40
Also I have tried moved lv_timer_handler()
to different RTOS task, but without result.
Code to reproduce
Here is a part of implementation
#define TFT_BL 2
Arduino_ESP32RGBPanel *bus = new Arduino_ESP32RGBPanel(
GFX_NOT_DEFINED /* CS */, GFX_NOT_DEFINED /* SCK */, GFX_NOT_DEFINED /* SDA */,
41 /* DE */, 40 /* VSYNC */, 39 /* HSYNC */, 42 /* PCLK */,
14 /* R0 */, 21 /* R1 */, 47 /* R2 */, 48 /* R3 */, 45 /* R4 */,
9 /* G0 */, 46 /* G1 */, 3 /* G2 */, 8 /* G3 */, 16 /* G4 */, 1 /* G5 */,
15 /* B0 */, 7 /* B1 */, 6 /* B2 */, 5 /* B3 */, 4 /* B4 */
);
Arduino_RPi_DPI_RGBPanel *gfx = new Arduino_RPi_DPI_RGBPanel(
bus,
800 /* width */, 0 /* hsync_polarity */, 210 /* hsync_front_porch */, 30 /* hsync_pulse_width */, 16 /* hsync_back_porch */,
480 /* height */, 0 /* vsync_polarity */, 22 /* vsync_front_porch */, 13 /* vsync_pulse_width */, 10 /* vsync_back_porch */,
1 /* pclk_active_neg */, 16000000 /* prefer_speed */, true /* auto_flush */);
#include "touch.h"
void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p)
{
uint32_t w = (area->x2 - area->x1 + 1);
uint32_t h = (area->y2 - area->y1 + 1);
#if (LV_COLOR_16_SWAP != 0)
gfx->draw16bitBeRGBBitmap(area->x1, area->y1, (uint16_t *)&color_p->full, w, h);
#else
gfx->draw16bitRGBBitmap(area->x1, area->y1, (uint16_t *)&color_p->full, w, h);
#endif
lv_disp_flush_ready(disp);
}
void my_touchpad_read(lv_indev_drv_t *indev_driver, lv_indev_data_t *data)
{
if (touch_has_signal())
{
if (touch_touched())
{
data->state = LV_INDEV_STATE_PR;
data->point.x = touch_last_x;
data->point.y = touch_last_y;
}
else if (touch_released())
{
data->state = LV_INDEV_STATE_REL;
}
}
else
{
data->state = LV_INDEV_STATE_REL;
}
}
void GUI::init()
{
gfx->begin();
#ifdef TFT_BL
pinMode(TFT_BL, OUTPUT);
digitalWrite(TFT_BL, HIGH);
ledcSetup(0, 300, 8);
ledcAttachPin(TFT_BL, 0);
setBrightness(DEFAULT_BRIGHTNESS_VALUE);
#endif
lv_init();
// Init touch device
pinMode(TOUCH_GT911_RST, OUTPUT);
digitalWrite(TOUCH_GT911_RST, LOW);
delay(10);
digitalWrite(TOUCH_GT911_RST, HIGH);
delay(10);
touch_init();
screenWidth = gfx->width();
screenHeight = gfx->height();
std::uint32_t targetDrawBuffSize = (screenWidth * screenHeight * sizeof(lv_color_t)) / 3;
disp_draw_buf = (lv_color_t *)heap_caps_malloc(targetDrawBuffSize, MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
if (!disp_draw_buf)
{
Serial.println("LVGL disp_draw_buf allocate failed!");
}
else
{
// lv_disp_draw_buf_init(&draw_buf, disp_draw_buf, disp_draw_buf2, (screenWidth * screenHeight) / 8);
lv_disp_draw_buf_init(&draw_buf, disp_draw_buf, NULL, targetDrawBuffSize / sizeof(lv_color_t));
/* Initialize the display */
lv_disp_drv_init(&disp_drv);
/* Change the following line to your display resolution */
disp_drv.hor_res = screenWidth;
disp_drv.ver_res = screenHeight;
disp_drv.flush_cb = my_disp_flush;
disp_drv.draw_buf = &draw_buf;
lv_disp_drv_register(&disp_drv);
/* Initialize the (dummy) input device driver */
static lv_indev_drv_t indev_drv;
lv_indev_drv_init(&indev_drv);
indev_drv.type = LV_INDEV_TYPE_POINTER;
indev_drv.read_cb = my_touchpad_read;
lv_indev_drv_register(&indev_drv);
ui_init();
Serial.println("Setup done");
}
// And code with RTOS
SERIALCONSOLE.println(xTaskCreatePinnedToCore(
refreshGuiTask,
"Refresh GUI Task",
4024,
NULL,
19,
NULL,
0));
}
And some implementation of GUI
void ui_screen_charts_init()
{
ui_ScreenCharts = lv_obj_create(NULL);
lv_obj_clear_flag(ui_ScreenCharts, LV_OBJ_FLAG_SCROLLABLE);
lv_obj_set_style_bg_img_src(ui_ScreenCharts, &ui_img_background_png, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_t *ui_buttonPrev = ui_ButtonPrev_create(ui_ScreenCharts);
lv_obj_align_to(ui_buttonPrev, ui_ScreenCharts, LV_ALIGN_BOTTOM_LEFT, 10, -10);
lv_obj_add_event_cb(ui_buttonPrev, ui_event_buttonGoToControl, LV_EVENT_ALL, NULL);
ui_cellsChart = lv_chart_create(ui_ScreenCharts);
lv_obj_clear_flag(ui_cellsChart, LV_OBJ_FLAG_SCROLLABLE);
lv_obj_set_width(ui_cellsChart, 690);
lv_obj_set_height(ui_cellsChart, 360);
lv_obj_set_align(ui_cellsChart, LV_ALIGN_CENTER);
lv_obj_align_to(ui_cellsChart, ui_ScreenCharts, LV_ALIGN_TOP_RIGHT, -10, 56);
...
lv_obj_add_event_cb(ui_cellsChart, chart_cell_series_event_cb, LV_EVENT_ALL, NULL);
ui_cellsChart2 = lv_chart_create(ui_ScreenCharts);
lv_obj_clear_flag(ui_cellsChart2, LV_OBJ_FLAG_SCROLLABLE);
lv_obj_set_width(ui_cellsChart2, 690);
lv_obj_set_height(ui_cellsChart2, 180);
lv_obj_align_to(ui_cellsChart2, ui_ScreenCharts, LV_ALIGN_BOTTOM_RIGHT, -10, -30);
...
lv_obj_add_flag(ui_cellsChart2, LV_OBJ_FLAG_HIDDEN);
lv_obj_add_event_cb(ui_cellsChart2, chart_cell_series_event_cb, LV_EVENT_ALL, NULL);
}
void ui_init(void)
{
LV_EVENT_GET_COMP_CHILD = lv_event_register_id();
lv_disp_t *dispp = lv_disp_get_default();
lv_theme_t *theme = lv_theme_default_init(dispp, lv_palette_main(LV_PALETTE_BLUE), lv_palette_main(LV_PALETTE_RED), true, LV_FONT_DEFAULT);
lv_disp_set_theme(dispp, theme);
ui_screen_charts_init();
ui____initial_actions0 = lv_obj_create(NULL);
lv_disp_load_scr(ui_ScreenHome);
ui_currentScreen = Home;
}
Screenshot and/or video
Example of glitch (it happens not only on charts, but in any case of content type)