Lvgl library and ESP32-P4 problems

I have just tried to use the lvgl library to paint a screen on an LCD touch screen driven by the latest version of ESP32 boards manager.All the widgets I need worked AOK. Except the checkbox and the switch widgets. The checkbox would never show the ‘tick’ in the box no matter what I tried so I abandoned it and tried the switch. I could get the switch to show the slider button either to the left or right when creating the switch in setup.

  static lv_style_t style_switch_checked;
  static lv_style_t style_switch_default;
  lv_style_init(&style_switch_checked);
  lv_style_set_bg_color(&style_switch_checked, lv_color_make(0x00, 0xFF, 0x00)); // Green for checked
  lv_style_init(&style_switch_default);
  lv_style_set_bg_color(&style_switch_default, lv_color_make(0x80, 0x80, 0x80)); // Grey for default
  sw_Clockwise = lv_switch_create(ST_panel);
  lv_obj_add_event_cb(sw_Clockwise, sw_event_cb, LV_EVENT_PRESSED, NULL);
  //lv_obj_add_state(sw_Clockwise, LV_STATE_CHECKED);//On
  lv_obj_add_style(sw_Clockwise, &style_switch_default, (int)LV_PART_MAIN | (int)LV_STATE_DEFAULT);
  lv_obj_add_style(sw_Clockwise, &style_switch_checked, (int)LV_PART_MAIN | (int)LV_STATE_CHECKED);
  lv_obj_set_pos(sw_Clockwise, 190, 200);
  lv_obj_t * lblsw_clck = lv_label_create(ST_panel);
  lv_label_set_text(lblsw_clck, "Clockwise");
  lv_obj_align_to(lblsw_clck, sw_Clockwise, LV_ALIGN_LEFT_MID , -100, 0);

But the button doesn’t toggle when I tap on the switch although the background does change colour.

This is my callback function:

static void sw_event_cb(lv_event_t * e)
{
  lv_event_code_t code = lv_event_get_code(e);
  lv_obj_t * sw = lv_event_get_target_obj(e);
  if(sw == sw_Clockwise)
  {
    if (lv_obj_has_state(sw, LV_STATE_CHECKED))
    {
      Serial.println("Was checked");
      //lv_obj_remove_state(sw, LV_STATE_CHECKED);
    }
    else
    {
      Serial.println("Was not checked");
      //lv_obj_add_state(sw, LV_STATE_CHECKED);
    }

    ST_dirn = !ST_dirn;
    Serial.printf("Clockwise = %i\r\n",ST_dirn);
  }   
}

If I un-comment the two state change commands the button will move to the right but never back again.

I have tried every combination I can think of to no avail. Has anyone used this library and successfully toggled the switch?

Hopefully someone will see the obvious stupid error I’ve searched for in vain.

Dicky.

First of all, please submit your code using the <code/> tag button.

how-to-use-code-tag


Have you tried running the checkbox example ? I recommend starting with the basics and then gradually adjusting it to your preferred style.

Both the checkbox and the switch change their state when the touch is released. I'm not sure how you're trying to behave your UI, but I would use the LV_EVENT_CLICKED event instead of LV_EVENT_PRESSED :

  sw_Clockwise = lv_switch_create(ST_panel);
  lv_obj_add_event_cb(sw_Clockwise, sw_event_cb, LV_EVENT_CLICKED, NULL);

Also, regarding the switch color, I think you meant LV_PART_INDICATOR instead of LV_PART_MAIN :

  lv_obj_add_style(sw_Clockwise, &style_switch_default, (int)LV_PART_INDICATOR | (int)LV_STATE_DEFAULT);
  lv_obj_add_style(sw_Clockwise, &style_switch_checked, (int)LV_PART_INDICATOR | (int)LV_STATE_CHECKED);

Here is the test code (base on your code) and results with my 240x320 LCD :

static lv_obj_t *sw_Clockwise;
static bool ST_dirn;
lv_obj_t *ST_label;

static void sw_event_cb(lv_event_t* e) {
  lv_event_code_t code = lv_event_get_code(e);
  lv_obj_t* sw = lv_event_get_target_obj(e);
  if (sw == sw_Clockwise) {
    if (lv_obj_has_state(sw, LV_STATE_CHECKED)) {
      Serial.println("Was checked");
      ST_dirn = true;
    } else {
      Serial.println("Was not checked");
      ST_dirn = false;
    }

    Serial.printf("Clockwise = %i\r\n", ST_dirn);
    lv_label_set_text_fmt(ST_label, "%s / Clockwise = %d", ST_dirn ? "Was checked" : "Was not checked", ST_dirn);
  }
}

void setup() {
  // some initialization code
  ...;

  // build switch UI
  lv_obj_t *ST_panel = lv_screen_active();

  static lv_style_t style_switch_checked;
  static lv_style_t style_switch_default;

  lv_style_init(&style_switch_checked);
  lv_style_set_bg_color(&style_switch_checked, lv_color_make(0x00, 0xFF, 0x00));  // Green for checked

  lv_style_init(&style_switch_default);
  lv_style_set_bg_color(&style_switch_default, lv_color_make(0x80, 0x80, 0x80));  // Grey for default

  sw_Clockwise = lv_switch_create(ST_panel);
  lv_obj_add_event_cb(sw_Clockwise, sw_event_cb, LV_EVENT_CLICKED, NULL);

  lv_obj_add_style(sw_Clockwise, &style_switch_default, (int)LV_PART_INDICATOR | (int)LV_STATE_DEFAULT);
  lv_obj_add_style(sw_Clockwise, &style_switch_checked, (int)LV_PART_INDICATOR | (int)LV_STATE_CHECKED);
  lv_obj_align(sw_Clockwise, LV_ALIGN_CENTER, 50, 0);

  lv_obj_t* lblsw_clck = lv_label_create(ST_panel);
  lv_label_set_text(lblsw_clck, "Clockwise");
  lv_obj_align_to(lblsw_clck, sw_Clockwise, LV_ALIGN_LEFT_MID, -100, 0);

  ST_label = lv_label_create(lv_screen_active());
  lv_obj_align(ST_label, LV_ALIGN_BOTTOM_MID, 0, -10);
  lv_obj_send_event(sw_Clockwise, LV_EVENT_CLICKED, NULL);
}

They did something to the forum engine so I ran into the same problem. Now you don’t need to close your '''

Now you need to type in gray rectangle :)))

Thank you embeddedkiddie for your reply. I did use the button and pasted my code but for some reason it came out double spaced :roll_eyes:

I made your change and this is the result:

Initial state on loading and selecting the Star tracker

After tapping the switch this is the result:

No button movement:

This is the Serial Monitor output.

rst:0x1 (POWERON),boot:0x10f (SPI_FAST_FLASH_BOOT)
SPI mode:DIO, clock div:1
load:0x4ff33ce0,len:0x11dc
load:0x4ff29ed0,len:0xc04
load:0x4ff2cbd0,len:0x3340
entry 0x4ff29ed0
ESP32P4 MIPI DSI LVGL
lv initialised OK
Touch started
Step Task Starting.
StepXtask created OK
Started periodic timer.
Stoped timer t1_Periodic.
setup complete
Was checked
Clockwise = 1
Was not checked
Clockwise = 0

Well, that paste seems to have work OK :upside_down_face:

Yes, my print of the sate reports the wrong way around and I’ve corrected the typo (stoped) in the setup reporting :grinning_face:

So no, for whatever reason LVGL seems to have some problem with my setup.

I’m running Windows 11 PRO latest version. Latest version of Arduino and all my libraries are up to date. Very frustrating.

Dicky.

Thanks Vvb333007, yes I tried all the examples to start with when I first installed lvgl. I’ve found most of the LVGL code snippets useless. They only give part of the code; many don’t even compile let alone work, not all the code you need is shown in many of the examples - particularly in the animation example.

The checkbox seems to have caused a lot of angst to many users. Google returned a host of people with the same problem. I cut and pasted a lot of the ‘working’ examples but none worked for me. After wasting two days I gave up and tried the switch. Now, a week later, the switch works well enough to make it clear what state it has which is all I really need - the button position is just eye candy.

I have a problem with the spinner too. I use it when various tasks are running on the other ESP32 processor. It appears and disappears at the right times but the animation freezes after a couple of spins. Clearly there is an issue in my anim code; when I get time I will try to get a better understanding of how it all fits together. Again only eye candy.

lvgl is certainly a very handy library. I will add a few Greek letters to the fonts though. µ and Pi are a must for me (The TT font used here shows Pi as Ò :grinning_face: ).

Dicky.

There seems to be some confusion about where to reply, but that's okay :wink:

Unfortunately, from the short program you posted, I can't find any reasons why the internal state seems to be LV_STATE_CHECKED while it appears to be LV_STATE_DEFAULT and the color of LV_PART_INDICATOR is green (by style_switch_checked).

I think the only differences between your and my execution environment are ESP32-P4 vs ESP32, and the LCD and touch panel drivers.

Therefore, if possible, I would like you to check the following two things.

  1. When you press and release the switch, does the switch knob animate to move to the right and then back to the left?

  2. Can you run just my code posted in #2? In this case, You need to make sure that only the single line lv_timer_handler(); is executed in loop().

If these two points prove to be a bug in LVGL, you can post this issue on LVGL issues to request a fix.

Yes I got a little confused with where the replies go.

I did cut and paste your code and got the same result. The button does not appear to move, or if it does it is too quick to see.

void loop() {
	lv_timer_handler();
	lv_indev_read(indev);
	lv_refr_now(NULL);
	delay(50);
}

I too am beginning to suspect it may be something to do with the display driver and touch events and/or the latest Esspresif board updates.

I will try to get up to speed with ESP IDF and see if that works any better. I’ve found It has a rather steep learning curve.

In the meantime I need to make up a pc board to connect the stepper drivers to the FPC connectors. FPC 0.5mm connectors are a bit fiddly. And I can’t find a 2.54 connector to solder into the 14 pin (two rows of seven pins) FPC break out board. I don’t like header pins that don’t lock when plugged in on a portable device. Although the JC1060P470 has formidable computing power and an impressive array of built in peripherals it requires a feat of engineering to mount it in a project box. If this device works well with boards and connectors everywhere. I will port the code to an ESP-P4 development board (which has a more friendly exposure of GPIO pins) and separate display.

The other lvgl and display code:

lv_indev_t* indev;

lv_obj_t * btn_ST_show;
lv_obj_t * btn_XY_show;
lv_obj_t * ST_panel;
lv_obj_t * XY_panel;
static lv_obj_t * lbl_XY;
static lv_obj_t * lbl_ST;
static lv_obj_t * btn_XY;
static lv_obj_t * btn_ST;
static lv_obj_t * btn_XY_origin;
static lv_obj_t * lblst;
static lv_obj_t * cbox;
static lv_obj_t * ta_x;
static lv_obj_t * ta_y;
static lv_obj_t * ta_usec;
static lv_obj_t * ta_Steps_mm;
static lv_obj_t * tabm;
//static lv_obj_t * sw_ST;
static lv_obj_t * sw_Clockwise;
static lv_obj_t * spinner;
static lv_style_t my_style;

static lv_style_t style_btn_red;
static lv_style_t style_btn_blue;

jd9165_lcd lcd = jd9165_lcd(LCD_RST);
gt911_touch touch = gt911_touch(TP_I2C_SDA, TP_I2C_SCL, TP_RST, TP_INT);

lv_display_t * disp_drv;
static uint32_t *buf;
static uint32_t *buf1;

void my_disp_flush( lv_display_t *disp, const lv_area_t *area, uint8_t * color_map)
{
  const int offsetx1 = area->x1;
  const int offsetx2 = area->x2;
  const int offsety1 = area->y1;
  const int offsety2 = area->y2;
  lcd.lcd_draw_bitmap(offsetx1, offsety1, offsetx2 + 1, offsety2 + 1, color_map);
  lv_display_flush_ready(disp);
}

void my_touchpad_read(lv_indev_t *indev_driver, lv_indev_data_t *data)
{
  bool touched;
  uint16_t touchX, touchY;

  touched = touch.getTouch(&touchX, &touchY);

  if (!touched)
  {
    data->state = LV_INDEV_STATE_REL;
   }
  else
  {
    data->state = LV_INDEV_STATE_PR;
    data->point.x = touchX;
    data->point.y = touchY;
    //Serial.printf("my_touchpad_read x=%d,y=%d \r\n",touchX,touchY);
  }
}

Dicky.

Yeah, ESP32-P4 runs super fast!

ESP32-P4 is relatively new to the MCU, so it seems like something that could actually happen.

Rather than spending too much time on this issue, it might be better to implement a simpler alternative.

For example, the following image displays some checkboxes in an lv_list, but instead of using an lv_checkbox widget, it displays an lv_button that can toggle between two images: check and uncheck.

Your code might be useful to someone looking to tackle the JC1060P470.

There's still a lot that needs to be done.
I hope you achieve your goal.