How to solve the problem that animation is too fast?

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

Hey here.
I truly believe that I got some problems confusing me.I’ve tried using multi-threads recently,yet I’m not the person mastering of multi-threads.And the dilmma of the kind fast animation beyond expectation confused me so much.
As my following code,I changed animation duration time according to definite ratio of tick time and handler sleep time(though,I dont know whether it is right).
I hope someone can help me solve this issue.Thanks so much!!

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

I guess it doesn’t matter.

What LVGL version are you using?

released 8.3.0

What do you want to achieve?

Correct,normal animation show and speed in multi-threads situation.

What have you tried so far?

Change tick time and enhance duration of animation and so on,but failed.
And I’ve looked up many references about this situation for answer,but it didn’t work.

Code to reproduce

Add a code snippet which can run in the simulator. It should contain only the relevant code that compiles without errors when separated from your main code base.

The code block(s) should be formatted like:

/* Thread of tick */

pthread_mutex_t my_lvgl_mutex  = PTHREAD_MUTEX_INITIALIZER;
pthread_t pthread_id_tick = 0;

void my_lvgl_lock()
{
	pthread_mutex_lock(&my_lvgl_mutex );
}

void my_lvgl_unlock()
{
	pthread_mutex_unlock(&my_lvgl_mutex );
}

...

/* Some macros */ 

#define TICK_INC_TIME 7
#define HANDLE_THREAD_SLEEP_TIME 1000
#define TICK_THREAD_SLEEP_TIME 1000
#define ANIM_LACK_TIMES ((TICK_INC_TIME * 1000 / TICK_THREAD_SLEEP_TIME))
#define ANIM_HALF_1_SEC (500 * ANIM_LACK_TIMES)
#define ANIM_1_SEC (1000 * ANIM_LACK_TIMES)

void *my_tick(void *arg)
{
    pthread_detach(pthread_self());
    while (1)
    {
       my_lvgl_lock();
        lv_tick_inc(TICK_INC_TIME); // TICK_INC_TIME = 7
        my_lvgl_unlock();
        usleep(TICK_THREAD_SLEEP_TIME); // TICK_THREAD_SLEEP_TIME = 1000
    }
    return ((void *)0);
}

void tick_thread()
{
    pthread_create(&pthread_id_tick , NULL, my_tick, NULL);
}

int main(int argc, char *argv[])
{
    lv_init();
    lv_wayland_init();
    lv_wayland_create_window(240, 240, "poweroff", NULL);
    my_tick_thread();
    while (1)
    {
        my_lvgl_lock();
        lv_task_handler();
        my_lvgl_unlock();
        usleep(HANDLE_THREAD_SLEEP_TIME); // HANDLE_THREAD_SLEEP_TIME = 1000
    }

    return 0;
}

/* Test code */

static void loading_set_angle(void *loading_img, int32_t rotate_angle)
{
    lv_img_set_angle((lv_obj_t *)loading_img, rotate_angle);
}

void gen_loading_animation(lv_obj_t *obj, uint expect_delay, uint expect_duration)
{
    lv_anim_t animation;

    if (!obj)
    {
        return;
    }

    if (expect_delay > 0)
    {
        lv_anim_set_delay(animation, expect_delay * ANIM_1_SEC / 1000);
    }
    else
    {
        lv_anim_set_delay(animation, ANIM_1_SEC);
    }

    if (expect_duration > 0)
    {
        lv_anim_set_time(animation, expect_duration * ANIM_1_SEC / 1000);
    }
    else
    {
        lv_anim_set_time(animation, ANIM_1_SEC);
    }

    lv_anim_init(&animation);
    lv_anim_set_var(&animation, obj);
    lv_anim_set_values(&animation, 0, 3600);
    lv_anim_speed_to_time(1, 0, 3600);
    lv_anim_set_repeat_count(&animation, LV_ANIM_REPEAT_INFINITE);
    lv_anim_set_exec_cb(&animation, loading_set_angle);
    lv_anim_start(&animation);
}

void test_loading_anim()
{
    lv_obj_t *scr = lv_scr_act();
    lv_obj_t *img = lv_img_create(scr);
    lv_obj_set_size(scr, 240, 240);
    lv_obj_clear_flag(scr, LV_OBJ_FLAG_SCROLLABLE);
   // new_icon_loading is a icon of the kind loading circles
    lv_obj_set_size(img, new_icon_loading.header.w, new_icon_loading.header.h);
    lv_obj_center(img);
    lv_img_set_src(img, &new_icon_loading);

    gen_loading_animation(img, 2000, 5000);
}

Screenshot and/or video

If possible, add screenshots and/or videos about the current state.

  1. No need to lock for “lv_tick_inc(TICK_INC_TIME); // TICK_INC_TIME = 7”
  2. please usleep 7000 if lv_tick_inc 7.

Woo,u reply so soon!!
I’ll change code to this,see whether it works.

Unfortunately,I changed code to following,but still too fast.


void *dragonfly_tick(void *arg)
{
    pthread_detach(pthread_self());
    while (1)
    {
        lv_tick_inc(TICK_INC_TIME);
        usleep(TICK_INC_TIME * 1000);
    }

    return ((void *)0);
}

Maybe your animation parameters are not correct. You can reference the lv_example_img_3(), only use the basic parameters to see the rotation speed.

Hey bro,I think I figured it out,my calculated ratio is right,but I set animation delay and animation time too early even before animation was not initialized.Anyway,thinks for your in-time help!!