Unable to move slider with encoder (LVGL 9.1)

Hello there :slight_smile: ,

What do you want to achieve?

I’m trying to move a slider with an “ENCODER” type driver

Description

Using the same logic as button, I’m adding my slider to a group, and add the indev_driver to it. But the slider doesn’t move at all. I think I am missing something.

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

Board : Custom ESP32 board
IDE : platformIO

What LVGL version are you using?

LVGL 9.1

What have you tried so far?

I succeeded to control a group of 3 buttons (navigate between them , and press one). So I think my lv_indev is working right.

Code to reproduce

Declaring my indev driver in main.cpp :

    btn_drv = lv_indev_create();
    lv_indev_set_type(btn_drv, LV_INDEV_TYPE_ENCODER); /*Touchpad should have POINTER type*/
    lv_indev_set_read_cb(btn_drv, bouton_read);

My callback function (may need to improve it) in main.cpp :

void bouton_read(lv_indev_t * drv, lv_indev_data_t* data) {
    static uint32_t last_button_state = 0;

    // Lecture de l'état actuel des boutons
    uint32_t current_button_state = 0;

    if (digitalRead(BTN_ENTER_PIN))
    {
      Serial.println("BTN ENTER PRESSED");
    }
    if (digitalRead(BTN_BACK_PIN))
    {
      Serial.println("BTN BACK PRESSED");
    }    
    if (digitalRead(BTN_LEFT_PIN))
    {
      Serial.println("BTN LEFT PRESSED");
    }
    if (digitalRead(BTN_RIGHT_PIN))
    {
      Serial.println("BTN RIGHT PRESSED");
    }

    current_button_state |= digitalRead(BTN_ENTER_PIN) ? LV_KEY_ENTER : 0;
    current_button_state |= digitalRead(BTN_BACK_PIN) ? LV_KEY_BACKSPACE : 0;
    current_button_state |= digitalRead(BTN_LEFT_PIN) ? LV_KEY_LEFT : 0;
    current_button_state |= digitalRead(BTN_RIGHT_PIN) ? LV_KEY_RIGHT : 0;

    // Déterminer les touches enfoncées et relâchées depuis la dernière lecture
    uint32_t diff = current_button_state ^ last_button_state;
    last_button_state = current_button_state;

    // Mettre à jour l'état des touches pour LVGL
    data->state = diff ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL;
    data->key = diff ? current_button_state : 0;
}

Slider declaration in screen_cfg_cq.cpp :

/*************************************/
  /**  Create first slider_score      **/
  /*************************************/
  /*Create a slider_score in the center of the display*/
  slider_score = lv_slider_create(scr_cfg_cq);
  lv_obj_center(slider_score);
  lv_slider_set_range(slider_score,MIN_SCORE,MAX_SCORE);
  lv_slider_set_value(slider_score, DEFAULT_SCORE,LV_ANIM_OFF);
  lv_obj_add_event_cb(slider_score, slider_score_event_cb, LV_EVENT_ALL, NULL);
  sliderGroup = lv_group_create();
  lv_group_add_obj(sliderGroup, slider_score);

Callback from a button to switch screen and set the lv_indev to the slider group :

static void btn_conq_cb(lv_event_t * e)
{
    lv_event_code_t code = lv_event_get_code(e);
    if(code == LV_EVENT_PRESSED) {

      // Screen transition
      lv_screen_load_anim(scr_cfg_cq, LV_SCR_LOAD_ANIM_OUT_LEFT, 800, 500, true);

      // Set the drive to the right group

      //lv_group_remove_obj(btn_conquest);
      lv_indev_set_group(btn_drv, sliderGroup);
    }
}

Screenshot and/or video

Slider displaying OK

Thanks,
Thomas.

Look at the code of this example and the function “slider_event_cb”

https://docs.lvgl.io/master/widgets/slider.html#simple-slider

Hello Stippa889,

Thanks for your feedback.
I have already looked a that code example.
Thanks to this code, I have created my slider and the callback function associated.

If I remember well, there was an error compiling this example. So I made modifications to the code.
I will share the error when I will be back at home.

But there is no explanation on how to control it with a lv_indev (“ENCODER”).
By the way, the callback is never called.

Thomas.

See the compilation error :

Hey there,

I’m still struggling with this problem.

Furthermore, I have 3 sliders to control on the same screen.
They are in the same group but not moving at all.

Maybe i should post this issue on the github.

Thomas.

Have your encoder push button press implemented? For control you require it or other button to toggle edit mode…

Hey Marian,

Thank you for your answer.

As you can see in my callback, I have bound the “LV_KEY_ENTER” to a button.
When I hit this button, the focused slider should switch to edit mode right ?
How can I check if the slider is in edit mode ?

Thomas.

I dont use 9.1 and you dont show relevant code part. But in 8.3. i use

  //Create Group for encoder
  g1 = lv_group_create();
  lv_indev_set_group(encoder_indev, g1);

  lv_group_add_obj(g1, ui_ArcdB); //change this to your slider
  lv_group_set_wrap(g1, true);
  lv_group_set_editing(g1, true);
  lv_group_focus_freeze(g1, true);

this lock one object to control with encoder, for change require unfreeze …

Hello Marian,

Thanks a lot ! It’s now working like a charm. :grin:

One more question, what does this function do?

lv_group_set_wrap(g1, true);

Thomas.

Simply in g1 you can have more as one object , then in edit mode false encoder switch to next prev… and on last stop or with wrap jump to first… To mark objects on focus you require add styles with state …

Hey Marian,

You have helped me a lot, thank you.

Any suggestion if I have multiple sliders in the same group ?

So I need to switch between navigation and editing mode.

I have tried to switch mode in my button callback, but this not working because the callback is called multiple time (like 3 to 4 time). I’m not sure why because I’m using a debounce function on my button. I think it’s more software issue.

The flag : u8_flag_slider_scr indicate that the screen with sliders is loaded.

void bouton_read(lv_indev_t * drv, lv_indev_data_t* data) {
    static uint32_t last_button_state = 0;

    // Current state of hardware button
    uint32_t current_button_state = 0;

    if (((u8_current_pin_state>>0)&1) == 1) {

      Serial.println("BTN ENTER PRESSED");
      current_button_state |= LV_KEY_ENTER;
      if (u8_flag_slider_scr == 1){
          static uint8_t u8_focus = 0;
          u8_focus = !u8_focus;
          lv_group_set_editing(sliderGroup, u8_focus);
          lv_group_focus_freeze(sliderGroup, u8_focus);
      }
    } 
    else {
      current_button_state |= 0;
    }

    if (((u8_current_pin_state>>1)&1) == 1){

      Serial.println("BTN LEFT PRESSED");
      current_button_state |= LV_KEY_LEFT;
    }
    else {
      current_button_state |= 0;
    }

    if (((u8_current_pin_state>>2)&1) == 1){

      Serial.println("BTN RIGHT PRESSED");
      current_button_state |= LV_KEY_RIGHT;
    }
    else {

      current_button_state |= 0;
    }  
    if (((u8_current_pin_state>>3)&1) == 1){

      Serial.println("BTN BACK PRESSED");
      current_button_state |= LV_KEY_BACKSPACE;
    }
    else {
      current_button_state |= 0;
    }
    // Déterminer les touches enfoncées et relâchées depuis la dernière lecture
    uint32_t diff = current_button_state ^ last_button_state;
    last_button_state = current_button_state;

    // Mettre à jour l'état des touches pour LVGL
    data->state = diff ? LV_INDEV_STATE_PR : LV_INDEV_STATE_REL;
    data->key = diff ? current_button_state : 0;
}

Thanks,
Thomas.

your code is little hard to read and for exaple this do nothing.

Normal when used more as one freezed , you dont use freeze and dont manage edit in handler. LVGL must handle it on objects. Your button handler require only right send press and release OK or ENTER …

Hey Marian,

You were right. I have fixed my callback function and everything is working fine.

I can navigated among all the slider and edit each one of them.

Many thanks,
Thomas.