Description
Hello everyone, i am developing a project using LVGL 9.2 and 4D-ESP32-GEN4-70-CLB from 4D-Systems. I am using a chart to visualize a signal. The chart is flickering very much.
i attached a video link.
What MCU/Processor/Board and compiler are you using?
What LVGL version are you using?
9.2
What do you want to achieve?
avoid/minimize flickering
What have you tried so far?
using one and/or two Buffers
reduced the LV_DEF_REFR_PERIOD to 10 and 20.
tried to use PSRAM, it minimized the flickering a little but its slowing down the other UI elements.
tried various sizes of draw_buf.
Code to reproduce
Add a code snippet which can run in the simulator. It should contain only the relevant code that compiles without errors when separated from your main code base.
The code block(s) should be formatted like:
#include <lvgl.h>
#include "gfx4desp32_gen4_ESP32_70CT_CLB.h"
#define TFT_HOR_RES 800
#define TFT_VER_RES 480
#define DRAW_BUF_SIZE (TFT_HOR_RES * TFT_VER_RES / 10 * (LV_COLOR_DEPTH / 8))
#define PI 3.14159265
uint32_t draw_buf[DRAW_BUF_SIZE / 4];
uint32_t draw_buf2[DRAW_BUF_SIZE / 4];
lv_display_t* display1;
lv_obj_t* chart;
lv_timer_t* chart_timer = NULL;
static lv_style_t style_chart_dark;
static lv_style_t style_chart_light;
gfx4desp32_gen4_ESP32_70CT_CLB gfx = gfx4desp32_gen4_ESP32_70CT_CLB();
void my_disp_flush_cb(lv_display_t* disp, const lv_area_t* area, uint8_t* color_p) {
uint32_t numPixels = lv_area_get_size(area);
//lv_draw_sw_rgb565_swap(color_p, (area->x2 - area->x1 + 1) * (area->y2 - area->y1 + 1)); /// color swap, very important!!!!
gfx.SetGRAM(area->x1, area->y1, area->x2, area->y2);
gfx.pushColors((uint16_t*)color_p, numPixels);
lv_display_flush_ready(disp);
}
static uint32_t my_tick(void) {
return millis();
}
static void add_data1(lv_timer_t* t) {
static float phase = 0.0;
static float freq = 0.2;
lv_obj_t* chart = (lv_obj_t*)lv_timer_get_user_data(t);
lv_chart_series_t* ser = lv_chart_get_series_next(chart, NULL);
float raw = sin(2 * PI * phase);
int32_t value = (int32_t)(raw * 35 + 50); // Ergebnis in Bereich 15–85
lv_chart_set_next_value(chart, ser, value); // Skaliert auf sichtbare Werte
phase += freq;
if (phase >= 1.0) phase -= 1.0;
lv_chart_refresh(chart);
}
void createDisplay() {
display1 = lv_display_create(TFT_HOR_RES, TFT_VER_RES);
lv_display_set_buffers(display1, draw_buf, draw_buf2, DRAW_BUF_SIZE, LV_DISPLAY_RENDER_MODE_PARTIAL);
lv_display_set_default(display1);
lv_display_set_flush_cb(display1, my_disp_flush_cb);
lv_obj_set_style_bg_color(lv_screen_active(), lv_color_hex(0xff101010), LV_PART_MAIN | LV_STATE_DEFAULT);
}
void createChart() {
chart = lv_chart_create(lv_screen_active());
lv_chart_set_update_mode(chart, LV_CHART_UPDATE_MODE_SHIFT);
lv_obj_set_pos(chart, 10, 8);
lv_obj_set_size(chart, 780, 341);
lv_obj_set_style_bg_color(chart, lv_color_hex(0xff000000), LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_line_width(chart, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_size(chart, 0, 0, LV_PART_INDICATOR);
lv_obj_set_style_border_color(chart, lv_color_hex(0xff631212), LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_radius(chart, 120, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_border_width(chart, 5, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_shadow_opa(chart, 255, LV_PART_INDICATOR | LV_STATE_DEFAULT);
lv_obj_set_style_clip_corner(chart, true, LV_PART_MAIN | LV_STATE_DEFAULT);
uint32_t i;
lv_chart_set_point_count(chart, 60);
lv_chart_series_t* ser = lv_chart_add_series(chart, lv_palette_main(LV_PALETTE_RED), LV_CHART_AXIS_PRIMARY_Y);
for (i = 0; i < 80; i++) {
lv_chart_set_next_value(chart, ser, (int32_t)lv_rand(10, 90));
}
}
static void event_cb(lv_event_t* e) {
Serial.println("clicked");
LV_LOG_USER("Button %s clicked", lv_label_get_text(label));
}
void touch_read(lv_indev_t* indev, lv_indev_data_t* data) {
gfx.touch_Update();
bool touched = gfx.touch_GetPen();
if (touched == TOUCH_PRESSED) {
data->state = LV_INDEV_STATE_PRESSED;
data->point.x = gfx.touch_GetX();
data->point.y = gfx.touch_GetY();
} else {
data->state = LV_INDEV_STATE_RELEASED;
}
}
void createinputDevice() {
lv_indev_t* indev = lv_indev_create(); /* Create input device connected to Default Display. */
lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER); /* Touch pad is a pointer-like device. */
lv_indev_set_read_cb(indev, touch_read);
}
void createRoller() {
lv_obj_t* roller = lv_roller_create(lv_screen_active());
lv_obj_set_pos(roller, 327, 357);
lv_obj_set_size(roller, 130, 110);
lv_roller_set_options(roller, "Option 1\nOption 2\nOption 3", LV_ROLLER_MODE_NORMAL);
lv_obj_set_style_bg_color(roller, lv_color_hex(0xffdd3636), LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_text_color(roller, lv_color_hex(0xffffffff), LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_border_opa(roller, 0, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_radius(roller, 20, LV_PART_MAIN | LV_STATE_DEFAULT);
lv_obj_set_style_bg_color(roller, lv_color_hex(0xff28252a), LV_PART_SELECTED | LV_STATE_DEFAULT);
lv_obj_add_event_cb(roller, roller_event, LV_EVENT_ALL, NULL);
}
static void roller_event(lv_event_t* e) {
lv_event_code_t code = lv_event_get_code(e);
lv_obj_t* obj = lv_event_get_target_obj(e);
char buf[32];
lv_roller_get_selected_str(obj, buf, sizeof(buf));
if (code == LV_EVENT_VALUE_CHANGED) {
if (chart_timer != NULL) {
lv_timer_del(chart_timer);
chart_timer = NULL;
}
if (strcmp(buf, "Option 1") == 0) {
chart_timer = lv_timer_create(add_data1, 200, chart);
Serial.println("Option 1");
} else if (strcmp(buf, "Option 2") == 0) {
chart_timer = lv_timer_create(add_data1, 200, chart);
Serial.println("Option 2");
} else if (strcmp(buf, "Option 3") == 0) {
chart_timer = lv_timer_create(add_data1, 200, chart);
Serial.println("Option 3");
}
}
}
void setup() {
Serial.begin(115200);
lv_init();
gfx.begin();
gfx.touch_Set(TOUCH_ENABLE);
createDisplay();
lv_tick_set_cb(my_tick);
createChart();
createinputDevice();
createRoller();
lv_obj_t* toggle = lv_switch_create(lv_screen_active());
lv_obj_align(toggle, LV_ALIGN_BOTTOM_LEFT, 0, 0);
lv_obj_set_size(toggle, 200, 100);
lv_obj_add_state(toggle, LV_STATE_CHECKED);
}
void loop() {
lv_timer_handler();
}