LV meter animated set new values

Description

Indicator is on some possition and new set require animate to new possition with defined path.
I have only new value. I try this but isnt perfect

void lv_meter_set_anim_value(void * indic, int32_t v)
{
  if(indic == indicDBR) {
      lv_anim_set_values(&aDBR, indicDBR->end_value, v);
      lv_anim_start(&aDBR);
  }
  else {
      lv_anim_set_values(&aDBL, indicDBL->end_value, v);
      lv_anim_start(&aDBL);
  }
}

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

ESP32S3

What LVGL version are you using?

8.3.7

@kisvegabor when i use this code and overshot path, my meter overshot only on one side. How i can solve this?

Please send a larger code snippet to see the whole configuration of the meter.

static lv_obj_t *meterDB,*meterDB2;
lv_meter_indicator_t *indicDBR,*indicDBL;
lv_anim_t aDBR,aDBL;

//    lv_meter_set_indicator_value(meterDB, indic, v);
static void set_valueDB(void * indic, int32_t v)
{
   if(indic == indicDBR) lv_meter_set_indicator_value(meterDB, indic, v);
   else lv_meter_set_indicator_value(meterDB2, indic, v);
}

/**
 * A simple meter
 */
void lv_meter_LR(void)
{
     meterDB = lv_meter_create(ui_Screen2);
    lv_obj_center(meterDB);
     meterDB2 = lv_meter_create(ui_Screen2);
    lv_obj_center(meterDB2);
    lv_obj_set_style_bg_opa(meterDB, 0, LV_PART_MAIN| LV_STATE_DEFAULT);
    lv_obj_set_style_border_width(meterDB, 0, LV_PART_MAIN| LV_STATE_DEFAULT);

lv_obj_set_size(meterDB, 240, 240);

lv_obj_set_size(meterDB2, 240, 240);
lv_obj_set_style_pad_left(meterDB2, 0, LV_PART_MAIN| LV_STATE_DEFAULT);
lv_obj_set_style_pad_right(meterDB2, 0, LV_PART_MAIN| LV_STATE_DEFAULT);
lv_obj_set_style_pad_top(meterDB2, 0, LV_PART_MAIN| LV_STATE_DEFAULT);
lv_obj_set_style_pad_bottom(meterDB2, 0, LV_PART_MAIN| LV_STATE_DEFAULT); 
lv_obj_set_style_pad_left(meterDB, 0, LV_PART_MAIN| LV_STATE_DEFAULT);
lv_obj_set_style_pad_right(meterDB, 0, LV_PART_MAIN| LV_STATE_DEFAULT);
lv_obj_set_style_pad_top(meterDB, 0, LV_PART_MAIN| LV_STATE_DEFAULT);
lv_obj_set_style_pad_bottom(meterDB, 0, LV_PART_MAIN| LV_STATE_DEFAULT); 
lv_obj_add_flag( meterDB, LV_OBJ_FLAG_ADV_HITTEST | LV_OBJ_FLAG_EVENT_BUBBLE );
lv_obj_add_flag( meterDB2, LV_OBJ_FLAG_ADV_HITTEST | LV_OBJ_FLAG_EVENT_BUBBLE );
    lv_obj_set_style_bg_opa(meterDB2, 0, LV_PART_MAIN| LV_STATE_DEFAULT);
    lv_obj_set_style_border_width(meterDB2, 0, LV_PART_MAIN| LV_STATE_DEFAULT);
    lv_meter_scale_t * scale2 = lv_meter_add_scale(meterDB2);
    lv_meter_set_scale_range(meterDB2, scale2, +6, -54, 80, -6);
    lv_meter_set_scale_ticks(meterDB2, scale2, 25, 2, 10, lv_palette_main(LV_PALETTE_GREY));
    lv_meter_set_scale_major_ticks(meterDB2, scale2, 8, 4, 15, lv_palette_main(LV_PALETTE_GREY), 10);

    /*Add a scale first*/
    lv_meter_scale_t * scale = lv_meter_add_scale(meterDB);
    lv_meter_set_scale_range(meterDB, scale, -54, +6, 80, 106);
    lv_meter_set_scale_ticks(meterDB, scale, 25, 2, 10, lv_palette_main(LV_PALETTE_GREY));
    lv_meter_set_scale_major_ticks(meterDB, scale, 8, 4, 15, lv_palette_main(LV_PALETTE_GREY), 10);

    lv_meter_indicator_t * indic;

    /*Make the tick lines blue at the start of the scale*/
    indic = lv_meter_add_scale_lines(meterDB, scale, lv_palette_main(LV_PALETTE_BLUE), lv_palette_main(LV_PALETTE_BLUE), false, 0);
    lv_meter_set_indicator_start_value(meterDB, indic, -54);
    lv_meter_set_indicator_end_value(meterDB, indic, -40);
    indic = lv_meter_add_scale_lines(meterDB2, scale2, lv_palette_main(LV_PALETTE_BLUE), lv_palette_main(LV_PALETTE_BLUE), false, 0);
    lv_meter_set_indicator_start_value(meterDB2, indic, -54);
    lv_meter_set_indicator_end_value(meterDB2, indic, -40);

    /*Make the tick lines red at the end of the scale*/
    indic = lv_meter_add_scale_lines(meterDB, scale, lv_palette_main(LV_PALETTE_RED), lv_palette_main(LV_PALETTE_RED), false, 0);
    lv_meter_set_indicator_start_value(meterDB, indic, -6);
    lv_meter_set_indicator_end_value(meterDB, indic, +6);
    indic = lv_meter_add_scale_lines(meterDB2, scale2, lv_palette_main(LV_PALETTE_RED), lv_palette_main(LV_PALETTE_RED), false, 0);
    lv_meter_set_indicator_start_value(meterDB2, indic, -6);
    lv_meter_set_indicator_end_value(meterDB2, indic, 6);

    /*Add a needle line indicator*/
    indicDBR = lv_meter_add_needle_line(meterDB, scale, 3, lv_palette_main(LV_PALETTE_CYAN), -10);
    indicDBL = lv_meter_add_needle_line(meterDB2, scale2, 3, lv_palette_main(LV_PALETTE_YELLOW), -10);

    lv_anim_init(&aDBR);
    lv_anim_set_exec_cb(&aDBR, set_valueDB);
    lv_anim_set_var(&aDBR, indicDBR);
    lv_anim_set_time(&aDBR, 60);
    lv_anim_set_path_cb(&aDBR, lv_anim_path_overshoot);
    lv_anim_init(&aDBL);
    lv_anim_set_exec_cb(&aDBL, set_valueDB);
    lv_anim_set_var(&aDBL, indicDBL);
    lv_anim_set_time(&aDBL, 60);
    lv_anim_set_path_cb(&aDBL, lv_anim_path_overshoot);
}

void lv_meter_set_anim_value(void * indic, int32_t v)
{
  if(indic == indicDBR) {
      lv_anim_set_values(&aDBR, indicDBR->end_value, v);
      if(indicDBR->end_value != v) lv_anim_start(&aDBR);
//      LV_LOG_USER("Indic st %d en %d vl %d",indicDBR->start_value,indicDBR->end_value, v);
  }
  else {
      lv_anim_set_values(&aDBL, indicDBL->end_value, v);
      if(indicDBL->end_value != v) lv_anim_start(&aDBL);
  }
}

and in loop test

bool vutesting = true;
if (vutesting & (looper5 % 195) == 7) {
  static int step;
  static bool smer=false;
  step+=smer ? +10 : -10;
  if(step==-50) smer=true;
  if(step==0) smer=false;
  rdb=ldb=0.0+step;

  lv_meter_set_anim_value(indicDBR, (int32_t)rdb);
  lv_meter_set_anim_value(indicDBL, (int32_t)ldb);
  }
  else if(!vutesting){
  lv_meter_set_anim_value(indicDBR, (int32_t)rdb);
  lv_meter_set_anim_value(indicDBL, (int32_t)ldb);
  }

Ah, it seems it’s rounding error: Please modify this line: https://github.com/lvgl/lvgl/blob/release/v8.3/src/misc/lv_anim.c#L277

Like this:

  new_value = (new_value + 512) >> LV_BEZIER_VAL_SHIFT;

Does it work on your end too?

Yes now see both side overshot work.