Images as animation

I decided to try the 5.3 release, unfortunately it’s the same thing. There’s some tearing on the display.
It’s slower then freezes.
I like the default font on dev-6.0 I think I’ll revert back to that. And maybe I’ll just stick to the default
preloader. I’ll give it a rest for now, a bit late.

Thanks guys.

@mhel Please share our code, maybe there is small ltypo in it.

There’s really nothing to it. I think.

LV_IMG_DECLARE(img1)
LV_IMG_DECLARE(img2)
LV_IMG_DECLARE(img3)
LV_IMG_DECLARE(img4)
LV_IMG_DECLARE(img5)

static void img_looper(lv_task_t *param) {
		  
	(void)param;
	lv_img_dsc_t *const my_images[] = {
		&img1,
		&img2,
		&img3,
		&img4,
		&img5
	};
		  
	static int img_index = 0;
	lv_obj_t * img_loop = lv_img_create(lv_scr_act(), NULL); /*Create an image object*/
	lv_img_set_src(img_loop, my_images[img_index]); /* Set the next image */
	
	img_index++;
	if(img_index == 5)
         img_index = 0;	    
}

int main(void)
{
   /*LittlevGL init*/
    lv_init();
    
    /*Linux frame buffer device init*/
    fbdev_init();

	static lv_disp_buf_t disp_buf;
    static lv_color_t buf_1[LV_HOR_RES_MAX * LV_VER_RES_MAX];            /*A screen sized buffer*/
    static lv_color_t buf_2[LV_HOR_RES_MAX * LV_VER_RES_MAX];            /*An other screen sized buffer*/
    lv_disp_buf_init(&disp_buf, buf_1, buf_2, LV_HOR_RES_MAX * LV_VER_RES_MAX);   /*Initialize the display buffer*/

    lv_disp_drv_t disp_drv;
    lv_disp_drv_init(&disp_drv);
    
    /*Set the resolution of the display*/
    disp_drv.hor_res = 160;
    disp_drv.ver_res = 128;
    disp_drv.flush_cb = fbdev_flush;
 
    /*Set a display buffer*/
    disp_drv.buffer = &disp_buf;   
    
    lv_disp_drv_register(&disp_drv);
    
	lv_style_scr.body.main_color = LV_COLOR_BLACK;  
	lv_style_scr.body.grad_color = LV_COLOR_BLACK;    
    
	lv_task_create( coin_animate, 200, LV_TASK_PRIO_LOWEST, NULL );
	
    while(1) {

        lv_task_handler();

		usleep(5000);
    }

	fbdev_exit();
	
    return 0;
}

Oh and I had to learn pthread creation so could have the tick handler separated.

static void *thr_tick_inc(void * data)
{
  struct timespec sleep_tm = {0,5000000U};
	
    (void)data;

    while(1) {
        nanosleep( &sleep_tm, NULL );
        lv_tick_inc(5);
    }

    return NULL;
}

@mhel You can use usleep in the pthread instead, it’s a lot simpler. It’s deprecated but for your use case I don’t think it will have any problems.

Also please use Markdown for showing your code (i.e. prefix with “```c” and end with “````”, minus the quotes).

Ah, I see the problem. You are creating a new image object each time. Eventually you’ll run out of memory.

You needed to create the image object once, in the main function.

Thanks.
With dev-6.0 how can I pass the img object as a parameter?
In 5.3 I know how to pass a void pointer, but it’s not the same on 6.0.

BTW thanks for editing the code display I tried to edit it but didn’t know the code.

Create the task the same way you did in 5.3. Then in img_looper:

static void img_looper(lv_task_t *task)
{
    lv_obj_t *img = (lv_obj_t *)task->user_data;
}

should work.

Yey it works!
Thanks so much. It’s always good to learn something new everyday :slight_smile:

1 Like

Hopefully complete solution, for the benefit of others who may read this post:


#define NUM_IMAGES 5

LV_IMG_DECLARE(img1)
LV_IMG_DECLARE(img2)
LV_IMG_DECLARE(img3)
LV_IMG_DECLARE(img4)
LV_IMG_DECLARE(img5)
lv_img_dsc_t *const my_images[NUM_IMAGES] = {
    &img1,
    &img2,
    &img3,
    &img4,
    &img5
};

static lv_obj_t *img_loop; /*To be created in the main() function*/
static void img_looper(lv_task_t *param) {
		  
	(void)param;
	
	static int img_index = 0;
	lv_img_set_src(img_loop, my_images[img_index]); /* Set the next image */
	
	img_index++;
	if(img_index == 5)
         img_index = 0;	    
}

int main(void)
{
    . . .
    img_loop = lv_img_create(lv_scr_act(), NULL);
    lv_task_create( img_looper, 200, LV_TASK_PRIO_LOWEST, NULL );
}

You need to create the img_obj once somewhere else in the code.

2 Likes