Label text sometimes does not update on display

Description

Two labels within a panel in a tabview are used to display accumulated volume and flow information. The values are float variables converted to strings (*char) via sprintf. This normally works perfectly fine, however sometimes the updated value is not displayed, and the label doesn’t change until the next change of value.
This behavior occurs on both labels but not at the same time, and is seemingly random, occurring between every 4th update to every 20th or so update.

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

Processor is an RP2040 on a custom board, using Arduino core, TFT_eSPI as display driver.

What LVGL version are you using?

8.4.0

What do you want to achieve?

I need to understand how to correct this issue so that updates to the label displayed values are consistent.

What have you tried so far?

Debugging over USB serial, by writing the float value, the converted string and then the read back value from the lv_label object to confirm the data is there. When the screen “misses” a value update, I can see in the debug message that the value did update to the label object - for some reason it is not displaying the new value. A spinner is also running on the display which confirms that the screen update is working.

Code to reproduce

  float volume = 12.29;
  float flow = 0.326;
  // Update volume and flow values to screen
  char buf[20];
  sprintf(buf, "%0.2f", volume);
  lv_label_set_text(ui_labelVolumeValue, buf);
  // Debug ----->
  Serial.printf("Volume: %0.2fmL, buf text: %s, label text: %s\n", volume, buf, lv_label_get_text(ui_labelVolumeValue));
  // <-----
  if (flow > 1) sprintf(buf, "%0.2f", flow);
  else sprintf(buf, "%0.3f", flow);
  lv_label_set_text(ui_labelFlowValue, buf);
  // Debug ----->
  Serial.printf("Flow: %0.2fmL, buf text: %s, label text: %s\n", flow, buf, lv_label_get_text(ui_labelFlowValue));
  // <-----

try

lv_label_set_text_fmt(ui_labelVolumeValue, "%0.2f", volume);

Thanks for your reply! Doing this results in just “f” being printed to the label on screen - I think this is why I originally when to sprintf. Also tried lv_label_set_text_fmt(ui_labelVolumeValue, “%f”, volume); which gives the same result - maybe the text_fmt function doesn’t handle floats?

Realised I had #define LV_SPRINTF_USE_FLOAT 0 in lv_conf.h, switching that on allowed floats to work with lv_label_set_text_fmt(), but the result is still the same as when using sprintf (or snprintf) - every so often the label fails to update.

In my version 8.3 it still works fine, try using my code

void test_float_value(void) {
	lv_obj_t *obj = lv_obj_create(lv_scr_act());
	lv_obj_set_size(obj, 480, 272);// full size
//	lv_obj_set_style_bg_opa(input_obj, 0, 0);
	lv_obj_set_style_border_opa(obj, 0, 0);
	lv_obj_set_style_shadow_opa(obj, 0, 0);
	lv_obj_set_style_radius(obj, 0, LV_PART_MAIN);
	lv_obj_clear_flag(obj, LV_OBJ_FLAG_SCROLLABLE);// disable scroll

	 float volume = 12.29;
	 // Update volume and flow values to screen
	 lv_obj_t *label = lv_label_create(obj);
	 lv_label_set_text_fmt(label, "%0.2f", volume);
	 lv_obj_set_style_text_font(label, &lv_font_montserrat_14, LV_PART_MAIN);
	 lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);

}

in the lv_conf.h

#define LV_SPRINTF_CUSTOM 0
#if LV_SPRINTF_CUSTOM
    #define LV_SPRINTF_INCLUDE <stdio.h>
    #define lv_snprintf  snprintf
    #define lv_vsnprintf vsnprintf
#else   /*LV_SPRINTF_CUSTOM*/
    #define LV_SPRINTF_USE_FLOAT 1
#endif  /*LV_SPRINTF_CUSTOM*/

#define LV_USE_USER_DATA 1

Thanks, this works for me as well, but the problem appears occasionally when updating that value only. I will see if I can get any more insight into what is happening.

1 Like

Your reproduce code dont show how you run it. For me not update = not call or bad handled mutithread , lvgl isnt safe.

Ah that is a good point, it could well be a an issue with which core is executing which code. I will shift the handler to the core running the ui refresh and see if that solves it. Thanks!

Moving the label update function to the same core performing the ui refresh lv_timer_handler() fixed this problem, thanks for steering me in the right direction!
I did initially try using some flags to inhibit label updates while the ui was updating and visa versa, but this still showed the same issue so I’m guessing something in the lv_timer_handler() is maybe non-blocking and the flags are being cleared before the function is actually complete?

Operating system and interrupts — LVGL documentation

maybe check the heap size setting