Code Blocks Simulator Hangs/ Gets Stuck when a particular label is recolored

Description

I’m facing problems recolouring label texts. Simulator hangs when a particular label’s, (and only that particular label’s), text is recoloured. Program terminates after a few seconds. It happens only for one label and I have commented it on the code.

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

I’m using LVGL Code blocks Simulator for windows (lv_sim_codeblocks_win-dev-7.0)

What LVGL version are you using?

7.11

What do you want to achieve?

I want to be able to recolour text on labels

What have you tried so far?

I tried commenting leaving the label as it was. Simulator does not hang. It hangs only when I try to recolour it.

Code to reproduce

#include <stdlib.h>
#include <unistd.h>
#include <stdio.h>
#include <time.h>

#include "lvgl/lvgl.h"
#include "lv_drivers/win_drv.h"
#include "lv_examples/src/lv_demo_widgets/lv_demo_widgets.h"
#include <windows.h>

static void hal_init(void);
static int tick_thread(void *data);

char curtime[20];
char curdate[20];
char hrte[11];
char botem[11];
char stps[11];

lv_obj_t * battery;
lv_obj_t * bt;
lv_obj_t * clocker;
lv_obj_t * dater;
lv_obj_t * heartrate;
lv_obj_t * btemp;
lv_obj_t * step;
lv_obj_t * homescr;

unsigned int count = 0;
unsigned int hrate = 0;
unsigned int bodytemp = 0;
unsigned int stpeno = 0;

int main(int argc, char** argv)
{
    /*Initialize LittlevGL*/
    lv_init();

    /*Initialize the HAL for LittlevGL*/
    hal_init();

    /*Check the themes too*/
    lv_disp_set_default(lv_windows_disp);

    /*Run the demo*/
    homescr = lv_scr_act();
    lv_obj_set_style_local_bg_color(homescr, LV_OBJ_PART_MAIN, 0, LV_COLOR_WHITE);

    battery = lv_label_create(homescr, NULL);
    lv_obj_align(battery, NULL, LV_ALIGN_IN_TOP_RIGHT, 5, 0);

    bt = lv_label_create(homescr, NULL);
    lv_obj_align(bt, NULL, LV_ALIGN_IN_TOP_RIGHT, -12, 0);
    lv_label_set_text(bt, LV_SYMBOL_BLUETOOTH);

    clocker = lv_label_create(homescr, NULL);
    lv_label_set_recolor(clocker, true);
    lv_obj_align(clocker, NULL, LV_ALIGN_CENTER, -10, -30);

    dater = lv_label_create(homescr, NULL);
    lv_obj_align(dater, NULL, LV_ALIGN_IN_TOP_LEFT, 0, 0);

    heartrate = lv_label_create(homescr, NULL);
	lv_label_set_recolor(heartrate, true);
	lv_obj_align(heartrate, NULL, LV_ALIGN_IN_BOTTOM_LEFT, 0, -60);

	btemp = lv_label_create(homescr, NULL);
	lv_label_set_recolor(btemp, true);
	lv_obj_align(btemp, NULL, LV_ALIGN_IN_BOTTOM_LEFT, 0, -40);

	step = lv_label_create(homescr, NULL);
	lv_label_set_recolor(step, true); // Simulator does not hang when I comment this line out. 
	lv_obj_align(step, NULL, LV_ALIGN_IN_BOTTOM_LEFT, 0, -20);

    while(1)
    {
        /* Periodically call the lv_task handler.
         * It could be done in a timer interrupt or an OS task too.*/
        time_t rawtime = time(NULL);
        struct tm *ptm = localtime(&rawtime);
        count = 1 + rand() % 10;
        bodytemp = 1 + rand() % 10;
        hrate = 1 + rand() % 10;
        stpeno = 1 + rand() % 10;
        blvl(count);
        sprintf(curtime, "#0008ff %02d:%02d:%02d", ptm->tm_hour, ptm->tm_min, ptm->tm_sec);
        sprintf(curdate, "%02d/%02d/%02d", ptm->tm_mday, ptm->tm_mon + 1, ptm->tm_year + 1900);
        lv_label_set_text(clocker, curtime);
        lv_label_set_text(dater, curdate);
        sprintf(hrte, "#ff0000 Heart Rate: %d BPM", hrate);
        lv_label_set_text(heartrate, hrte);
        sprintf(botem, "#ffdd00 Body Temp: %d 'C", bodytemp);
        lv_label_set_text(btemp, botem);
        sprintf(stps, "#008000 Steps: %d", stpeno); // Not able to re colour this label without the simulator getting stuck.
        lv_label_set_text(step, stps);
        lv_task_handler();
        usleep(1000);       /*Just to let the system breath*/
    }
    return 0;
}

void blvl (int x)
 {
     if (0 <= x && x <= 1)
     {
         lv_label_set_text(battery, LV_SYMBOL_BATTERY_EMPTY);
     }
     else if (2 <= x && x <= 3)
     {
         lv_label_set_text(battery, LV_SYMBOL_BATTERY_1);
     }
     else if (4 <= x && x <= 5)
     {
         lv_label_set_text(battery, LV_SYMBOL_BATTERY_2);
     }
     else if (6 <= x && x <= 7)
     {
         lv_label_set_text(battery, LV_SYMBOL_BATTERY_3);
     }
     else if (8 <= x && x <= 10)
     {
         lv_label_set_text(battery, LV_SYMBOL_BATTERY_FULL);
     }
     usleep(1000);
 }

static void hal_init(void)
{
#if !WIN32
    /* Add a display
     * Use the 'monitor' driver which creates window on PC's monitor to simulate a display*/
    monitor_init();
    lv_disp_drv_t disp_drv;
    lv_disp_drv_init(&disp_drv);            /*Basic initialization*/
    disp_drv.disp_flush = monitor_flush;
    disp_drv.disp_fill = monitor_fill;
    disp_drv.disp_map = monitor_map;
    lv_disp_drv_register(&disp_drv);

    /* Add the mouse (or touchpad) as input device
     * Use the 'mouse' driver which reads the PC's mouse*/
    mouse_init();
    lv_indev_drv_t indev_drv;
    lv_indev_drv_init(&indev_drv);          /*Basic initialization*/
    indev_drv.type = LV_INDEV_TYPE_POINTER;
    indev_drv.read = mouse_read;         /*This function will be called periodically (by the library) to get the mouse position and state*/
    lv_indev_drv_register(&indev_drv);

    /* Tick init.
     * You have to call 'lv_tick_handler()' in every milliseconds
     * Create an SDL thread to do this*/
    SDL_CreateThread(tick_thread, "tick", NULL);
#else
    /* This sets up some timers to handle everything. */
    windrv_init();
#endif
}

#if !WIN32
static int tick_thread(void *data)
{
    while(1) {
        lv_tick_inc(1);
        SDL_Delay(1);   /*Sleep for 1 millisecond*/
    }
    return 0;
}
#endif

Don’t you think, that the string buffer is a little too small?

char hrte[11];
char botem[11];
char stps[11];
 sprintf (hrte,   "#ff0000 Heart Rate: %d BPM", hrate);
 sprintf (botem,  "#ffdd00 Body Temp: %d 'C", bodytemp);
 sprintf (stps,   "#008000 Steps: %d", stpeno);

I would recommend to use snprintf and a appropriate define

There is also lv_label_set_text_fmt in v7, which is effectively printf but straight to the label. This avoids the need for the separate buffer and s(n)printf call.

1 Like

Sorry the string buffer was indeed too small :sweat_smile: My bad.

Thanks this works too