Esp32 lvgl high cpu usage problem

Description

esp32 lvgl high cpu usage problem

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

esp32 s3

What LVGL version are you using?

v8.0

What do you want to achieve?

The code block(s) should be formatted like:

  lv_obj_t *textbox = lv_textarea_create(lv_scr_act());
	lv_obj_align(textbox, NULL, x, y);
	lv_obj_set_style_radius(textbox, 0, 0);
        lv_obj_set_size(textbox, sizex, sizey);
	lv_obj_set_style_bg_color(textbox, lv_color_make(255, 255, 255), LV_PART_MAIN);
	lv_textarea_set_text(textbox, "");    /*Set an initial text*/
	lv_textarea_set_align(textbox, LV_TEXT_ALIGN_LEFT); 
	lv_obj_set_style_border_opa(textbox,LV_STATE_DEFAULT, 0);
	

and my update textbox task

lv_textarea_set_text(textbox , str); 

3 textobx and update cpu %50 usage is this normal ?

Screenshot and/or video

1 Like

Hi @bitcoin ,

I am not at all sure about your systems performance and whether this will help in your particular situation, but personally I have found to keep CPU usage to a minimum, I only update LVGL objects when something changes. In my own projects I keep a copy of the last value of the variable and compare it to the current value then only update the objects when something changes. This I do for all types of objects to avoid unnecessary formatting and rendering operations.

If we take your example screenshot

Say the first text area is showing room temperature, the second is outside temperature and the third is system temperature.

The code would be something like this:

void update_screen1( void ) {
	
	static double last_room_temperature=0, last_outside_temperature=0, last_system_temperature=0, temp;
	
	temp = get_room_temperature();
	if( last_room_temperature != temp ) {
		lv_textarea_set_text_fmt(textbox1 , "%5.1f", temp);
		last_room_temperature = temp;
	}
	temp = get_outside_temperature();
	if( last_outside_temperature != temp ) {
		lv_textarea_set_text_fmt(textbox2 , "%5.1f", temp);
		last_outside_temperature = temp;
	}
	temp = get_system_temperature();
	if( last_system_temperature !=  ) {
		lv_textarea_set_text_fmt(textbox3 , "%5.1f", temp);
		last_system_temperature = temp;
	}
}

Also if the you have a multi-threaded environment I would execute the temperature getting functions in a thread at a lower priority than the LVGL timer handler thread and store them in global variables. Then in the update function I would reference the global copies of the temperature so the GUI is not blocked by the hardware fetching the temperatures from the the sensors keeping the screen responsive.

I hope that makes sense.

Kind Regards,

Pete

problem is here.
if i increase refresh time cpu usage drops.

Hi @bitcoin ,

Assuming you have a touch screen this suggests there may be something in the touch driver eating CPU time… There are many development environment options for ESP devices which are you using? I would suggest checking the touch driver code for your device first…

Kind Regards,

Pete

touch screen not active .
i develope lvgl on esp32 idf

freertos tickrate 1000hz
il9341
cfg.freq_write = 79000000;
cfg.freq_read = 39000000;

Hi @bitcoin ,

Which type of input device do you have please, if not touch? :smiley:

Kind Regards,

Pete

1 Like

touch is not active. for now i’m just dealing with textbox update…

Hi @bitcoin ,

Sorry have I misread the situation here, are you altering the Default display refresh period (ms) not the highlighted Input device read period [ms].? :smiley:

Kind Regards,

Pete

how to disable input device read period ?
i dont use this option

Hi @bitcoin ,

To use input devices you must call lv_indev_drv_init() function to register them, so if you are not doing this anywhere there should be no input devices defined and the LVGL library will just return with no processing so shouldn’t cause high load…

Please can you answer my previous question?

Kind Regards,

Pete

i changed Default display refresh period

Hi @bitcoin ,

Okay sorry so the indev thing can be ignored :smiley: because the indev timer was highlighted I assumed it was that timer…

So back to the original question if you just set the text areas to some value and disable the update function does the CPU load remain high?

Kind Regards,

Pete

if i dont use update task cpu usage just %3-6

Hi @bitcoin ,

Okay so it sounds like your platform is not responsible for the CPU load and can be eliminated. :smiley:

Can you now please post your entire update function/task for your example so I can see how it’s coded please?

Kind Regards,

Pete

			lvgl_acquire();
	
			int r = getcolorR(background);
			int g = getcolorG(background);
			int b = getcolorB(background);
			
			
			int textr = getcolorR(textcolor);
			int textg = getcolorG(textcolor);
			int textb = getcolorB(textcolor);
	
			

					
			lv_obj_align(objectname,NULL,x,y);
			lv_obj_set_size(objectname,sizew,sizeh);
			lv_textarea_set_text(objectname, updatestring); 
			lv_obj_set_style_bg_color(objectname, lv_color_make(r, g, b), LV_PART_MAIN);
			lv_obj_set_style_text_color(objectname, lv_color_make(textr, textg, textb), 0);
			if(transparent == 1){
					
					lv_obj_set_style_bg_opa(objectname, 0, LV_PART_MAIN);
			}
			else{
				lv_obj_set_style_bg_opa(objectname, 255, LV_PART_MAIN);
				
			}
		
				
			
		
			lvgl_release();

my while loop

i m using this library

Hi @bitcoin ,

I have no idea of your level of expertise and if I am teaching you stuff you already know please feel free to ignore me… :smiling_face:

There is a number potential issues with this approach, and I would recommend restructuring you code.

If I am understanding things correctly you are initialising all the properties of the object every time it is updated which is going create an enormous unnecessary load for your CPU.

I would suggest creating a separate GUI initialisation function to create, place and initialise your objects which is called once at the beginning of your application.

Then I would just update the values in the text areas (and any other objects types later) when necessary using some method similar to that which I posted above.

If you are executing a while loop task for the update, you must have delay in that loop if you haven’t already, as a tight loop with no delay will cause high CPU load and starve other threads of CPU time causing system issues.

So your update loop would be:

void update_gui_task( ) {

	while( 1 ) {
		// Do your updates
		vTaskDelay( 200 ); // This can be what ever you want but I would keep it above 100mS the longer the better for best performance. 
    }
}

Does that make sense?

Kind Regards,

Pete

I define an image in the background at the beginning and it doesn’t update
cpu usage %83 i dont use now while loop

	lcd.init();        // Initialize LovyanGFX
    lv_init();         // Initialize lvgl
    if (lv_display_init() != ESP_OK) // Configure LVGL
    {
        ESP_LOGE(TAG, "LVGL setup failed!!!");
    }
	
	lvgl_acquire();
	home_page= lv_img_create(lv_scr_act());
	lv_img_set_src(home_page, "A:tiger.bin");
    lv_obj_align(home_page,NULL,0,0);
	lv_obj_set_style_radius(home_page, 0, 0);
	lv_obj_set_size(home_page, 240, 320);
	lv_obj_set_style_bg_color(home_page, lv_color_make(90, 90, 90), LV_PART_MAIN);
	lvgl_release();

Hi,

Please try out this:

  1. have only an empty screen
  2. do this:
  while(1) {
	  lv_obj_set_style_bg_color(lv_scr_act(), lv_color_hex3(0xf00), 0);
	  lv_refr_now(NULL);
	  lv_obj_set_style_bg_color(lv_scr_act(), lv_color_hex3(0x00f), 0);
	  lv_refr_now(NULL);
  }
  1. take a video about the result

It will help us to see how fast your system is in the practice.