ProblemesIssue with Background Switching in LVGL Using ESPHome

Hi Guys,

I am currently working on a project where I use ESPHome with an ESP32 to dynamically change the background of my LVGL display based on a select module. However, I’m facing an issue: while the input is recognized and the ESP32 attempts to switch the background image, the display briefly flickers but then goes blank.

My Setup:

I have defined several background images in the image section of my YAML configuration, all resized to 850x550 and using the RGB565 format.
Here’s a snippet of my image setup:

image:
  - file: "Media/doorbell/bg_fullsize.jpg"
    id: darkmode
    type: RGB565
    resize: 850x550
  - file: "Media/doorbell/bg_light.jpg"
    id: lightmode
    resize: 850x550
    type: RGB565
  - file: "Media/doorbell/mountains.jpg"
    id: mountains
    resize: 850x550
    type: RGB565
  - file: "Media/doorbell/fluids.jpg"
    id: fluids
    resize: 850x550
    type: RGB565
  - file: "Media/doorbell/layers.jpg"
    id: layers
    resize: 850x550
    type: RGB565
  - file: "Media/doorbell/mountainsae.jpg"
    id: mountainsae
    resize: 850x550
    type: RGB565

I also configured a select module with options corresponding to these images. The logic for updating the background is implemented in the on_value section, using the lvgl.update action.

select:
  - platform: template
    name: select_bg
    id: select_bg
    optimistic: True
    initial_option: Darkmode-Standard
    options: 
      - Darkmode-Standard
      - Lightmode-Standard
      - Mountains
      - Darkmode-Fluids
      - Layers
      - Mountains-Aesthetics
    on_value:
      then:
      - logger.log:
          format: "Background: %s (index %d)"
          args: ["x.c_str()", "i"]
      - if:
          condition:
            lambda: |-
              return (id(select_bg).active_index() == 0);
          then:
          - logger.log: "Darkmode-Standard"
          - lvgl.update:
              disp_bg_image: darkmode

      - if:
          condition:
            lambda: |-
              return (id(select_bg).active_index() == 1);
          then:
          - logger.log: "Lightmode-Standard"
          - lvgl.update:
              disp_bg_image: lightmode

      - if:
          condition:
            lambda: |-
              return (id(select_bg).active_index() == 2);
          then:
          - logger.log: "Mountains"
          - lvgl.update:
              disp_bg_image: mountains
      - if:
          condition:
            lambda: |-
              return (id(select_bg).active_index() == 3);
          then:
          - logger.log: "Darkmode-Fluids"
          - lvgl.update:
              disp_bg_image: fluids
      - if:
          condition:
            lambda: |-
              return (id(select_bg).active_index() == 4);
          then:
          - logger.log: "Layers"
          - lvgl.update:
             disp_bg_image: layers
      - if:
          condition:
            lambda: |-
              return (id(select_bg).active_index() == 5);
          then:
          - logger.log: "Montains-Aesthetics"
          - lvgl.update:
              disp_bg_image: mountainsae

The Problem:

When I select a new background using the select module, the ESP32 logs the selection correctly, and the lvgl.update command is executed. However, the display only flickers briefly before going blank. No image is shown on the screen.

What I’ve Tried:

  • Ensured all images are in RGB565 format and resized appropriately.
  • Verified that the image IDs are correctly referenced in the lvgl.update command.
  • Checked the ESPHome logs, which confirm that the select input is received and processed.

Questions:

  1. Has anyone successfully implemented dynamic background switching with LVGL in ESPHome?
  2. Could the issue be related to buffer size, image format, or display compatibility?
  3. Are there additional debugging steps or configurations I should consider?
image:
  - file: "Media/doorbell/bg_fullsize.jpg"
    id: darkmode
    type: RGB565
    resize: 850x550
  - file: "Media/doorbell/bg_light.jpg"
    id: lightmode
    resize: 850x550
    type: RGB565
  - file: "Media/doorbell/mountains.jpg"
    id: mountains
    resize: 850x550
    type: RGB565
  - file: "Media/doorbell/fluids.jpg"
    id: fluids
    resize: 850x550
    type: RGB565
  - file: "Media/doorbell/layers.jpg"
    id: layers
    resize: 850x550
    type: RGB565
  - file: "Media/doorbell/mountainsae.jpg"
    id: mountainsae
    resize: 850x550
    type: RGB565

select:
  - platform: template
    name: select_bg
    id: select_bg
    optimistic: True
    initial_option: Darkmode-Standard
    options: 
      - Darkmode-Standard
      - Lightmode-Standard
      - Mountains
      - Darkmode-Fluids
      - Layers
      - Mountains-Aesthetics
    on_value:
      then:
      - logger.log:
          format: "Background: %s (index %d)"
          args: ["x.c_str()", "i"]
      - if:
          condition:
            lambda: |-
              return (id(select_bg).active_index() == 0);
          then:
          - logger.log: "Darkmode-Standard"
          - lvgl.update:
              disp_bg_image: darkmode

      - if:
          condition:
            lambda: |-
              return (id(select_bg).active_index() == 1);
          then:
          - logger.log: "Lightmode-Standard"
          - lvgl.update:
              disp_bg_image: lightmode

      - if:
          condition:
            lambda: |-
              return (id(select_bg).active_index() == 2);
          then:
          - logger.log: "Mountains"
          - lvgl.update:
              disp_bg_image: mountains
      - if:
          condition:
            lambda: |-
              return (id(select_bg).active_index() == 3);
          then:
          - logger.log: "Darkmode-Fluids"
          - lvgl.update:
              disp_bg_image: fluids
      - if:
          condition:
            lambda: |-
              return (id(select_bg).active_index() == 4);
          then:
          - logger.log: "Layers"
          - lvgl.update:
             disp_bg_image: layers
      - if:
          condition:
            lambda: |-
              return (id(select_bg).active_index() == 5);
          then:
          - logger.log: "Montains-Aesthetics"
          - lvgl.update:
              disp_bg_image: mountainsae


color:
  - id: my_red
    red: 100%
    green: 0%
    blue: 0%
  - id: my_orange
    red: 100%
    green: 50%
    blue: 0%
  - id: my_yellow
    red: 100%
    green: 100%
    blue: 0%
  - id: my_green
    red: 0%
    green: 100%
    blue: 0%
  - id: my_purple
    red: 45%
    green: 0%
    blue: 75%
  - id: my_teal
    red: 0%
    green: 100%
    blue: 100%
  - id: my_gray
    red: 70%
    green: 70%
    blue: 70%
  - id: my_blue
    red: 0%
    green: 0%
    blue: 70%
  - id: my_white
    red: 100%
    green: 100%
    blue: 100%
  - id: my_black
    red: 0%
    green: 0%
    blue: 0%
  - id: my_blackhex
    hex: 191919

lvgl:
  buffer_size: 100%
  log_level: INFO
  displays: 
    - my_display

  theme:
    button:
      bg_color: my_black
      bg_opa: 20%
      border_width: 5
      border_color: my_black
      radius: 10
      shadow_color: my_black
      shadow_opa: 100%
      shadow_width: 10
      text_color: my_white
      text_font: montserrat_36

  pages:
      - id: home
        widgets:
          - button:
                id: call_og_button
                align: CENTER
                y: -120
                width: 750
                height: 200
                checkable: false
                widgets:
                  - label:
                      align: CENTER
                      id: og_label
                      text: "K. Klaus"
                      text_font: montserrat_36
                on_click:
                  - lvgl.page.show:
                      id: pending_og
                      animation: FADE_OUT
                      time: 1000ms
                  - delay: 30s
                  - lvgl.page.show:
                      id: home
                      animation: FADE_OUT
                      time: 1000ms 

I’d really appreciate any insights or guidance on how to resolve this issue!

Thank you!

There’s a bug in current esphome version, it should be corrected in next release, but until then add this to your code:

external_components:
  - source: github://pr#8005
    components: [lvgl]
1 Like

yes, i have this EC already implmented and it worked with the BG image set, by the lvgl config.

so i guess it has to be another problem with this code…