How to update a text of a label with user data

Important: unclear posts may not receive useful answers.

Before posting

  • Get familiar with Markdown to format and structure your post
  • Be sure to update lvgl from the latest version from the master branch.
  • Be sure you have checked the FAQ and read the relevant part of the documentation.
  • If applicable use the Simulator to eliminate hardware related issues.

Delete this section if you read and applied the mentioned points.

Description

Can you explain how I can change the text on a simple label?

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

ESP 32 with 240*320 TFT (CYD)

What LVGL version are you using?

8.3.

What do you want to achieve?

I would like to learn how I can update a label text with user data via bare minimum explanation / code.

What have you tried so far?

I have checked tha available discussions about the topic, but I was not able to understand that.
I have tried to find a bare simple explanation how I can change the text of a label with user data.
I know this is a completely newbie quiestion, but I completely lost into the details.
What I have right now.
I have a working code with 3 button, and I can control the 3color LED on the panel with that buttons.
I have a working code to read DHT11 sensor and write to the serial port.
My plan is to update the label with sensorsā€™ data.
I am on arduino (becuse this is the easiest all that I tried up to know. (Platformio - sucks, ESP-IDF- sucks)

I tried to several way to update the text on the label. The best what I could achieve some ā€œblablaā€ is not scope - error.

So my question is.

Where I need to set the lv_timer_t * timer? As global , as setup, or in loop?
How I can give the user data to the calback function?

Any help is appreciated.

Ferenc

https://docs.lvgl.io/master/widgets/label.html#set-text

use lv_label_set_text(my_button_label, "my new text") replacing of course the label name and text.

Have you read the docs? Itā€™s a good idea to check the docs of the specific widget type you are looking for help with. Setting text is the first thing there. Itā€™s also the first thing in the examples - setting text on a label.

https://docs.lvgl.io/master/get-started/quick-overview.html#a-very-simple-hello-world-label

Is there some part of the puzzle weā€™re missing here? Are you stuck moreso trying to get user data, or some external input, and then passing that along, rather than literally setting label text?

The second example does just that, creates a button with a label, and creates a callback (an action taken when the button is pressed) which sets a new label text.

https://docs.lvgl.io/master/get-started/quick-overview.html#a-button-with-a-label-and-react-on-click-event

since you have a code that writes the data in the sreial port, just replace serial port output with lv_label_set_text()/lv_label_set_text_fmt(). to reduce the number of label updates you can compare text of label with new text and update label only if they donā€™t match - use lv_label_get_text() to get curently installed text.

Hello Theelous3!

Yes, I am reading the docs into the last 6 monthā€¦
The docs are C, and the arduino is little bit different, so I am running on error, but I do not know I made a mistake, or just simply a missed something to transfer the code to arduino.
Before lvgl8 therew was some task create function. (And many result of my internet search is explains that way. I had a difficult week just to realize that my case with lvgl8 is different.)

There is a very sort sentences, without explanation:
" You can set the text on a label at runtime with lv_label_set_text(label, ā€œNew textā€)."

What does that runtime mean in arduino? Setup? Loop?

  1. The very simple hello-world-label is very simple, so I can make buttons, labelsā€¦etc. without problem.

  2. the button with a label andā€¦ sample self explanatory. My problem is that how I can ā€œgiveā€ user data to the callback from ā€œoutsideā€. It is not clear to me the mechanism of LVGL.

Thank you for your time

Ferenc

Hello Glory-man

I have inserted the following line right after the serial message sending:

lv_label_set_text(label1,String(newValues.temperature));

And I am here :frowning: :
Compilation error: ā€˜label1ā€™ was not declared in this scope/

Any help is appreciated

Ferenc

itā€™s dificult to find a bug in code without code :slight_smile:
I can assume that label1 is declared as a local variable or is in another program module. if it local - made it global

as you can see in arduino exmple
lv_obj_t * label
declared as local in setup(). so just move label declaration outside of function.

What does that runtime mean in arduino? Setup? Loop?

Runtime means during the execution of the program. Compile time is your ā€œbuildā€, and when the program starts actually running, thatā€™s runtime.

My problem is that how I can ā€œgiveā€ user data to the callback from ā€œoutsideā€. It is not clear to me the mechanism of LVGL.

You get data from ā€œoutsideā€ by using whatever arduino functions you normally use. For example, if you want a label to display if a gpio pin is high or low - you use the digitalRead function to capture the state of the pin, and you set the label with that data:

pin_state = digitalRead(myPin);
String label_text = String("Low");

if (pin_state == 1) {
    label_text = String("High")
}
lv_label_set_text(my_label, label_text.c_str());

Something like this. To be perfectly honest it sounds like you need to do a programming tutorial before trying to deal with lvgl or programming in general. There are a lot of concepts to understand before working with a library like this.

Hi glory-man

Hi here is the latest version of my codeā€¦


// DHT prep
#include "DHTesp.h" 
#include <Ticker.h>

#include <lvgl.h>
#include <TFT_eSPI.h>
#include "CST820.h"
#include <demos/lv_demos.h>

/*ę›“ę”¹å±å¹•åˆ†č¾ØēŽ‡*/
static const uint16_t screenWidth = 240;
static const uint16_t screenHeight = 320;

/*å®šä¹‰č§¦ę‘øå±å¼•č„š*/
#define I2C_SDA 33
#define I2C_SCL 32
#define TP_RST 25
#define TP_INT 21

#define LED_BLUE 17 // GPIO17 - PIN28 LED LOW is lighting is on LED HIGH is lighting off
#define LED_RED 4 //GPIO04 - PIN26
#define LED_GREEN 16 //GPIO16 - PIN27


#define TFT_Backlight 27 // GPIO27 - PIN 12 - this is used as Backlight Control Pin TFTe_SPI User_Setup.h !!!




static lv_disp_draw_buf_t draw_buf;
static lv_color_t *buf1;
static lv_color_t *buf2;

void tempTask(void *pvParameters);
bool getTemperature();
void triggerGetTemp();


DHTesp dht;
TFT_eSPI tft = TFT_eSPI();                      /* TFT实例 */
CST820 touch(I2C_SDA, I2C_SCL, TP_RST, TP_INT); /* 触ę‘ø实例 */


/** Task handle for the light value read task */
TaskHandle_t tempTaskHandle = NULL;
/** Ticker for temperature reading */
Ticker tempTicker;
/** Comfort profile */
ComfortState cf;                               
/** Flag if task should run */
bool tasksEnabled = false;
/** Pin number for DHT11 data pin */
//int dhtPin = 4;
int dhtPin = 22; // Sunton CYD P3 Yellow wire


/**
 * initTemp
 * Setup DHT library
 * Setup task and timer for repeated measurement
 * @return bool
 *    true if task and timer are started
 *    false if task or timer couldn't be started
 */
bool initTemp() {
  byte resultValue = 0;
  // Initialize temperature sensor
	dht.setup(dhtPin, DHTesp::DHT11);
	Serial.println("DHT initiated");

  // Start task to get temperature
	xTaskCreatePinnedToCore(
			tempTask,                       /* Function to implement the task */
			"tempTask ",                    /* Name of the task */
			4000,                           /* Stack size in words */
			NULL,                           /* Task input parameter */
			5,                              /* Priority of the task */
			&tempTaskHandle,                /* Task handle. */
			1);                             /* Core where the task should run */

  if (tempTaskHandle == NULL) {
    Serial.println("Failed to start task for temperature update");
    return false;
  } else {
    // Start update of environment data every 2 seconds
    tempTicker.attach(2, triggerGetTemp);
  }
  return true;
}

/**
 * triggerGetTemp
 * Sets flag dhtUpdated to true for handling in loop()
 * called by Ticker getTempTimer
 */
void triggerGetTemp() {
  if (tempTaskHandle != NULL) {
	   xTaskResumeFromISR(tempTaskHandle);
  }
}

/**
 * Task to reads temperature from DHT11 sensor
 * @param pvParameters
 *    pointer to task parameters
 */
void tempTask(void *pvParameters) {
	Serial.println("tempTask loop started");
	while (1) // tempTask loop
  {
    if (tasksEnabled) {
      // Get temperature values
			getTemperature();
      digitalWrite(LED_BLUE, HIGH);
      digitalWrite(LED_BLUE, LOW);
      digitalWrite(LED_BLUE, HIGH);


		}
    // Got sleep again
		vTaskSuspend(NULL);
	}
}

/**
 * getTemperature
 * Reads temperature from DHT11 sensor
 * @return bool
 *    true if temperature could be aquired
 *    false if aquisition failed
*/
bool getTemperature() {
	// Reading temperature for humidity takes about 250 milliseconds!
	// Sensor readings may also be up to 2 seconds 'old' (it's a very slow sensor)
  TempAndHumidity newValues = dht.getTempAndHumidity();
	// Check if any reads failed and exit early (to try again).
	if (dht.getStatus() != 0) {
		Serial.println("DHT11 error status: " + String(dht.getStatusString()));
		return false;
	}

	float heatIndex = dht.computeHeatIndex(newValues.temperature, newValues.humidity);
  float dewPoint = dht.computeDewPoint(newValues.temperature, newValues.humidity);
  float cr = dht.getComfortRatio(cf, newValues.temperature, newValues.humidity);

  String comfortStatus;
  switch(cf) {
    case Comfort_OK:
      comfortStatus = "Comfort_OK";
      break;
    case Comfort_TooHot:
      comfortStatus = "Comfort_TooHot";
      break;
    case Comfort_TooCold:
      comfortStatus = "Comfort_TooCold";
      break;
    case Comfort_TooDry:
      comfortStatus = "Comfort_TooDry";
      break;
    case Comfort_TooHumid:
      comfortStatus = "Comfort_TooHumid";
      break;
    case Comfort_HotAndHumid:
      comfortStatus = "Comfort_HotAndHumid";
      break;
    case Comfort_HotAndDry:
      comfortStatus = "Comfort_HotAndDry";
      break;
    case Comfort_ColdAndHumid:
      comfortStatus = "Comfort_ColdAndHumid";
      break;
    case Comfort_ColdAndDry:
      comfortStatus = "Comfort_ColdAndDry";
      break;
    default:
      comfortStatus = "Unknown:";
      break;
  };

  Serial.println(" T:" + String(newValues.temperature) + " H:" + String(newValues.humidity) + " I:" + String(heatIndex) + " D:" + String(dewPoint) + " " + comfortStatus);
	return true;
  lv_label_set_text(label1,String(newValues.temperature));


}





#if LV_USE_LOG != 0
/* äø²č”Œč°ƒčƕ */
void my_print(const char *buf)
{
    Serial.printf(buf);
    Serial.flush();
}
#endif
//_



static void btnBLUE_event_cb(lv_event_t * e)
{
    lv_event_code_t code = lv_event_get_code(e);
    lv_obj_t * btn = lv_event_get_target(e);
    if(code == LV_EVENT_CLICKED) {
        //static uint8_t cnt = 0;
        digitalWrite(LED_BLUE, !digitalRead(LED_BLUE));
        /*Get the first child of the button which is the label and change its text*/
        lv_obj_t * label = lv_obj_get_child(btn, 0);
        lv_label_set_text_fmt(label, "BLUE");
    }


}
static void btnRED_event_cb(lv_event_t * e)
{
    lv_event_code_t code = lv_event_get_code(e);
    lv_obj_t * btn = lv_event_get_target(e);
    if(code == LV_EVENT_CLICKED) {
        //static uint8_t cnt = 0;
        digitalWrite(LED_RED, !digitalRead(LED_RED));
        /*Get the first child of the button which is the label and change its text*/
        lv_obj_t * label = lv_obj_get_child(btn, 0);
        lv_label_set_text_fmt(label, "RED");
    }
}

static void btnGREEN_event_cb(lv_event_t * e)
{
    lv_event_code_t code = lv_event_get_code(e);
    lv_obj_t * btn = lv_event_get_target(e);
    if(code == LV_EVENT_CLICKED) {
        //static uint8_t cnt = 0;
        digitalWrite(LED_GREEN, !digitalRead(LED_GREEN));
        /*Get the first child of the button which is the label and change its text*/
        lv_obj_t * label = lv_obj_get_child(btn, 0);
        lv_label_set_text_fmt(label, "GREEN");
    }


}


void lv_example_btn(void)
{


    lv_timer_t * timer = lv_timer_create( * label_refresher_task, 1000,  NULL);

//  BLUE button
    lv_obj_t * blue_btn = lv_btn_create(lv_scr_act());     /*Add a button the current screen*/
    //lv_obj_set_pos(blue_btn, 60, 10);                            /*Set its position*/
    lv_obj_set_size(blue_btn, 120, 50);                          /*Set its size*/
    lv_obj_add_event_cb(blue_btn, btnBLUE_event_cb, LV_EVENT_ALL, NULL);           /*Assign a callback to the button*/
    lv_obj_align(blue_btn, LV_ALIGN_CENTER, 0, -100);

    lv_obj_t * blue_label = lv_label_create(blue_btn);          /*Add a label to the button*/
    lv_label_set_text(blue_label, "BLUE");                     /*Set the labels text*/
    lv_obj_center(blue_label);
//  RED button
    lv_obj_t * red_btn = lv_btn_create(lv_scr_act());     /*Add a button the current screen*/
    //lv_obj_set_pos(red_btn, 60, 110);                            /*Set its position*/
    lv_obj_set_size(red_btn, 120, 50);                          /*Set its size*/
    lv_obj_add_event_cb(red_btn, btnRED_event_cb, LV_EVENT_ALL, NULL);           /*Assign a callback to the button*/
    lv_obj_align(red_btn, LV_ALIGN_CENTER, 0, 0);

    lv_obj_t * red_label = lv_label_create(red_btn);          /*Add a label to the button*/
    lv_label_set_text(red_label, "RED");                     /*Set the labels text*/
    lv_obj_center(red_label);

//  GREEN button
    lv_obj_t * green_btn = lv_btn_create(lv_scr_act());     /*Add a button the current screen*/
    //lv_obj_set_pos(green_btn, 60, 230);                            /*Set its position*/
    lv_obj_set_size(green_btn, 120, 50);                          /*Set its size*/
    lv_obj_add_event_cb(green_btn, btnGREEN_event_cb, LV_EVENT_ALL, NULL);
    lv_obj_align(green_btn, LV_ALIGN_CENTER, 0, +100);           /*Assign a callback to the button*/

    lv_obj_t * green_label = lv_label_create(green_btn);          /*Add a label to the button*/
    lv_label_set_text(green_label, "GREEN");                     /*Set the labels text*/
    lv_obj_center(green_label);

    lv_obj_t * label1 = lv_label_create(lv_scr_act());          /*Add a label to the button*/
    lv_label_set_text(label1, "LABEL1");                     /*Set the labels text*/
    lv_obj_align(label1, LV_ALIGN_CENTER, 0, +50 );




}
//_______________________
/* Monitor frissƭtƩs */
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);

    //tft.startWrite();
    tft.pushImageDMA(area->x1, area->y1, w, h, (uint16_t *)color_p);
    //tft.endWrite();

    lv_disp_flush_ready(disp);
}

/*Az Ć©rintőpadot olvasĆ³ funkciĆ³*/
void my_touchpad_read(lv_indev_drv_t *indev_driver, lv_indev_data_t *data)
{

    bool touched;
    uint8_t gesture;
    uint16_t touchX, touchY;

    touched = touch.getTouch(&touchX, &touchY, &gesture);

    if (!touched)
    {
        data->state = LV_INDEV_STATE_REL;
    }
    else
    {
        data->state = LV_INDEV_STATE_PR;

        /*Set the coordinates*/
        data->point.x = touchX;
        data->point.y = touchY;
    }
}


void setup()
{
    Serial.begin(115200); /*初始化äø²å£*/

    String LVGL_Arduino = "Hello Arduino! ";
    LVGL_Arduino += String('V') + lv_version_major() + "." + lv_version_minor() + "." + lv_version_patch();

    Serial.println(LVGL_Arduino);
    Serial.println("I am LVGL_Arduino");

    Serial.println();
    Serial.println("DHT ESP32 example with tasks");
    initTemp();
    // Signal end of setup() to tasks
    tasksEnabled = true;





    lv_init();

#if LV_USE_LOG != 0
    lv_log_register_print_cb(my_print); /* ē”ØäŗŽč°ƒčƕēš„ę³Øå†Œę‰“å°åŠŸčƒ½ */
#endif
    pinMode(LED_BLUE, OUTPUT);//TTH
    pinMode(LED_RED, OUTPUT);//TTH
    pinMode(LED_GREEN, OUTPUT);//TTH
    digitalWrite(LED_BLUE, HIGH);
    digitalWrite(LED_RED, HIGH);
    digitalWrite(LED_GREEN, HIGH);
    delay(500);
    digitalWrite(LED_BLUE, LOW);
    delay(500);
    digitalWrite(LED_BLUE, HIGH);
    delay(500);
    digitalWrite(LED_RED, LOW);
    delay(500);
    digitalWrite(LED_RED, HIGH);
    delay(500);
    digitalWrite(LED_GREEN, LOW);
    delay(500);
    digitalWrite(LED_GREEN, HIGH);


    pinMode(TFT_Backlight, OUTPUT);
    digitalWrite(TFT_Backlight, LOW);



    tft.begin();        /*初始化*/
    tft.setRotation(0); /* ę—‹č½¬ */
    tft.initDMA();      /* 初始化DMA */

    touch.begin(); /*åˆå§‹åŒ–č§¦ę‘øęæ*/
    //digitalWrite(LED3, HIGH);
    digitalWrite(TFT_Backlight, HIGH);

    tft.fillScreen(TFT_RED);
    delay(500);
    tft.fillScreen(TFT_GREEN);
    delay(500);
    tft.fillScreen(TFT_BLUE);
    delay(500);
    tft.fillScreen(TFT_BLACK);
    delay(500);

    buf1 = (lv_color_t *)heap_caps_malloc(sizeof(lv_color_t) * screenWidth * 200 , MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL);//screenWidth * screenHeight/2
    buf2 = (lv_color_t *)heap_caps_malloc(sizeof(lv_color_t) * screenWidth * 200 , MALLOC_CAP_DMA | MALLOC_CAP_INTERNAL);

    lv_disp_draw_buf_init(&draw_buf, buf1, buf2, screenWidth * 200);

    /*Kijelző inicializĆ”lĆ”sa*/
    static lv_disp_drv_t disp_drv;
    lv_disp_drv_init(&disp_drv);
    /*KijelzőfelbontĆ”s beĆ”llĆ­tĆ”sa*/
    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);

    /*InicializĆ”lja a (virtuĆ”lis) beviteli eszkƶz illesztőprogramjĆ”t*/
    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);

   
    lv_example_btn();

    Serial.println("Setup done");
    tft.startWrite();
}

void label_refresher_task(void * p)
{
    //static uint32_t prev_value = 0;

    //if(prev_value != adc_value) {

        if(lv_obj_get_screen(label1) == lv_scr_act()) {
            //char buf[32];
            //snprintf(buf, 32, "Voltage: %d", adc_value);
            lv_label_set_text(label1, "MMMM");
        }
        //prev_value = adc_value;
    //}
}


void loop()
{
    lv_timer_handler(); /* 让GUIå®Œęˆå®ƒēš„å·„作 */
    delay(5);

  if (!tasksEnabled) {
    // Wait 2 seconds to let system settle down
    delay(2000);
    // Enable task that will read values from the DHT sensor
    tasksEnabled = true;
    if (tempTaskHandle != NULL) {
			vTaskResume(tempTaskHandle);
		}
  }
  yield();

}
type or paste code here

This is the latest version. (gives error)
I know it is messy becuse I merged together several examplesā€¦
(by the way any advise is appreciated to rearrange the code.)

Just little bit about programming tutorialā€¦ I am older than 50 yearsā€¦ I started with basic. Mean programming languageā€¦ I keep alive with programming little java, matlab, octave, openCV, pythonā€¦ nothing special, just only basicsā€¦
I am doing some C course right now: (200hour) You are right I do not know some basics, because I had no chance to learn when I was into the perfect ageā€¦
BUTā€¦ what I have learn that 99% of the tutorials to the teachers, not to a studentā€¦
ā€¦ this is why I appreciate any HUMAN advice except advice from TEACHERSā€¦
I have taught many people life meaning profession during my life, but my lessons is about the student, not about myselfā€¦
:slight_smile:

Ferenc

Hi glory-man!

That example is LVGL9, I am on 8.3 because I have somehow working codes on this version. (working touch, displayā€¦ etc)
That example gives me endless error messagesā€¦ I no hope to debug themā€¦

By the way your idea was the first to tryā€¦ but I missed something, because it was not workingā€¦

Ferenc

the example i gave is from the documentation for the v8 branch so i think it should work :wink:
what about your code. as i said label1 in your code is local variable - declared in lv_example_btn() - it is outside the scope of getTemperature() function where you try to update the label. so simpliest way to remove this error is move label1 from lv_example_btn()
something like this:

static lv_disp_draw_buf_t draw_buf;
static lv_color_t *buf1;
static lv_color_t *buf2;
static lv_obj_t * label1;
...
void lv_example_btn(void)
{
...
    label1 = lv_label_create(lv_scr_act());          /*Add a label to the button*/
    lv_label_set_text(label1, "LABEL1");                     /*Set the labels text*/
    lv_obj_align(label1, LV_ALIGN_CENTER, 0, +50 );

}

UPD:
in btnGREEN_event_cb() you use lv_label_set_text_fmt() without formating - in lv_label_set_text() mode - so just use lv_label_set_text(). here example how to use it

Hi Glory-man,

I have made the changesā€¦
The result isā€¦

Compilation error: invalid conversion from ā€˜void ()(void)ā€™ to ā€˜lv_timer_cb_tā€™ {aka ā€˜void ()(_lv_timer_t)ā€™} [-fpermissive]

:frowning:

this is the line:
lv_timer_t * timer = lv_timer_create( label_refresher_task, 1000, NULL);

In regards the documentation 8.3
lv_timer_t *lv_timer_create(lv_timer_cb_t timer_xcb, uint32_t period, void *user_data)

I canot see any problem hereā€¦ by the way the user data is not clear to me? Where can I find some explanation?

I have commented out that line, and it complied without errorā€¦ But the label does not change from defaultā€¦

This is all for todayā€¦

:frowning:

Any idea?
Thank you in advance: Ferenc

the problem is not in user_data. as yo can see in example timer_cb should have following declaration void (lv_timer_t *) but in your case

void label_refresher_task(void * p)
.....
lv_timer_t * timer = lv_timer_create( * label_refresher_task, 1000,  NULL);

which should be

void label_refresher_task(lv_timer_t * p)
.....
lv_timer_t * timer = lv_timer_create( label_refresher_task, 1000,  NULL);

Hi Glory-man,

I am progressing a bit with your advicesā€¦

I have tried to implement the example codeā€¦

  1. I have created a global variableā€¦
static uint32_t user_data = 10; // to be on the safe side
  1. ā€¦ I have created a very simple callback functions:
void label_refresher_task(lv_timer_t * timer)
{
    uint32_t * user_data = timer->user_data;
    printf("my_timer called with user data: %d\n", *user_data);
}
  1. ā€¦ and I created the timer as:
lv_timer_t * timer = lv_timer_create(label_refresher_task, 1000, &label1_content);

But I finally got another error about ā€¦

invalid conversion from 'void*' to 'uint32_t*' {aka 'unsigned int*'} [-fpermissive]
     uint32_t * user_data = timer->user_data;

ā€¦ and I am getting lostā€¦

I have read the definition of lv_timer_create as:

lv_timer_t * lv_timer_create(lv_timer_cb_t timer_xcb, uint32_t period, void * user_data);

The type of the user data is void pointer it is clearā€¦

But how the example ā€œjumpsā€ over the conversion?
The example is not correct?

Another thing is not clear of that ā€œprototypingā€ staff ā€¦

A timer callback should have a void (*lv_timer_cb_t)(lv_timer_t *); prototype.

What I need to do with this? I put this line to the beginning a code, but I received another (not) funny error message:

ā€˜void (* lv_timer_cb_t)(lv_timer_t*)ā€™ redeclared as different kind of symbol
void (*lv_timer_cb_t)(lv_timer_t *);

Any help appreciatedā€¦

Ferenc

first of all it seems that you wanted create timer like

lv_timer_t * timer = lv_timer_create(label_refresher_task, 1000, &user_data);

what about type cast from 'void*' to 'uint32_t*' it depend from used compiler. try to use explicit cast

 uint32_t * user_data = (uint32_t *)timer->user_data;

you donā€™t have to do anything about it. this line of doc tells about first arg of lv_timer_create(). first arg have type lv_timer_cb_t. as described here lv_timer_cb_t defined as

typedef void (*lv_timer_cb_t)(struct _lv_timer_t*)
Timers execute this type of functions.

so your callback function should be defined as

void cb_function_name(struct _lv_timer_t*)
{
}

as it done in your code. you didnā€™t need to redefine already defined type. just remove this line void (*lv_timer_cb_t)(lv_timer_t *); from your user code. this typedef is described inside the library

1 Like

Hi Glory-man,

Thank you your explanation.
Finally I have a working code with refreshing label. (with a simple counter right now.)

Ferenc

:grinning:

Hi from long long light years distance from C knowledge. Then all your trouble is no right understanding * & and other part of C language basics.
Next bad practice use same name for local and global for example your user_dataā€¦ Hope next code work better.

1 Like