ESP32-S3 4.3inch Capacitive Touch Display from - waveshare

Oh, Holy Cow!

I’ve been working with the waveshare 7" panel and ESPHome for days. Thanks to you, I’ve managed to get what I want, little by little. The goal is partly operation without Home Assistant, on-site modbus reading. I’ve made it this far today.

1 Like

Per the wiki (linked to above), “You cannot dim the screen but only turn on/off the backlight”

Backlight on the waveshare is controlled using the ch422g port expander chip, which, I believe, is not yet supported by ESPHOME. Support for this chip was added to esp-arduino-libs on 2024-05-07 and a component request has been submitted for subsequent ESPHOME support (Support for WCH(Jiangsu Qin Heng) CH422G I/O Expander · Issue #2671 · esphome/feature-requests · GitHub).

3 Likes

Has anyone had any luck working with the CAN Bus interface? I have a Waveshare USB CAN dongle but I’m getting transmit errors when trying to send to the LCD device.

And how can i add image for background? I follow the guide, but compile failed.

[canned response]
Not enough information. If you provide:

  • a complete, minimal and self-contained YAML demonstrating the problem;
  • a copy of the output with the error messages;
  • a description of your environment (i.e. Windows/MacOS/Linux, how ESPHome is installed etc.)

Then you will probably get a useful response quite quickly.
[/canned response]

1 Like

And how can i add image for background? I follow the guide, but compile failed.

clean build files?
https://community.home-assistant.io/t/compile-work-with-images

in this page has a sample:

image:

Compiling in Synology Nas/ova VM/Home Assistant 2024.7.3 + ESPHome 2024.7.1

Don’t attach screenshots (especially truncated ones!), copy and paste the text. What you added there is no help, since it doesn’t show where you’re trying to use the image.

1 Like

I think the screenshot says more. I don’t want to share the whole yaml, it’s still under development, it might confuse others. Here, too, the image component is clearly visible, which is inserted according to the rules.
I’m going step by step. do you mean that the error could also be because the image is just inserted, but not used anywhere?

Your picture of the compile error discussion looks almost exactly like the picture that was shown in the posting that I linked to above. So, just to verify, did you follow that link and did you “Clean Build Files”?

Also, in order for Clyde to help you (its amazing that he is doing all of this work on the code and taking time to help us as well!), he needs code that shows your issue but has all of the extra stuff that no one wants to see (esp_modus, abb_ev, etc) removed so that it only focuses on the problem. For example, below is working code that will compile and shows a picture of a cat (assuming the picture is in you esphome folder) but nothing else (as for why the cat is drawn in black and white on the display… heck if I know).

esphome:
  name: largedisplay
  friendly_name: Largedisplay
  platformio_options:
    build_flags: "-DBOARD_HAS_PSRAM"
    board_build.arduino.memory_type: qio_opi
    board_build.flash_mode: dio
    board_upload.maximum_ram_size: 524288

esp32:
  board: esp32-s3-devkitc-1
  variant: esp32s3
  framework:
    type: esp-idf
    sdkconfig_options:
      CONFIG_ESP32S3_DEFAULT_CPU_FREQ_240: y
      CONFIG_ESP32S3_DATA_CACHE_64KB: y
      CONFIG_SPIRAM_FETCH_INSTRUCTIONS: y
      CONFIG_SPIRAM_RODATA: y

external_components:
  - source: github://pr#6363
    refresh: 0min
    components: [lvgl]

psram:
  mode: octal
  speed: 80MHz

# Enable logging
logger:
  level: DEBUG

i2c:
  sda: GPIO08
  scl: GPIO09
  scan: True
  id: bus_a

display:
  - platform: rpi_dpi_rgb
    id: my_display
    auto_clear_enabled: false
    update_interval: never
    color_order: RGB
    pclk_frequency: 14MHz
    dimensions:
      width: 800
      height: 480
    de_pin:
      number: 5
    hsync_pin:
      number: 46
      ignore_strapping_warning: true
    vsync_pin:
      number: 3
      ignore_strapping_warning: true
    pclk_pin: 7
    pclk_inverted: false
    hsync_back_porch: 10 #30
    hsync_front_porch: 20 #210 
    hsync_pulse_width: 10 #30
    vsync_back_porch: 10 #4
    vsync_front_porch: 10 #4
    vsync_pulse_width: 10 #4
    data_pins:
      red:
        - 1         #r3
        - 2         #r4
        - 42        #r5
        - 41        #r6
        - 40        #r7
      blue:
        - 14        #b3
        - 38        #b4
        - 18        #b5
        - 17        #b6
        - 10        #b7
      green:
        - 39        #g2
        - 0         #g3
        - 45        #g4
        - 48        #g5
        - 47        #g6
        - 21        #g7

font:
  - file: "gfonts://Roboto"
    id: chu_nano
    size: 12

image:
  - file: "test.jpg"
    id: my_test_image
    resize: 480x480

  - file: "cat.png"
    id: my_cat_image
    resize: 69x86

  - file: https://esphome.io/_images/logo.png
    id: esphome_logo
    resize: 200x162

  
touchscreen:
  platform: gt911
  id: my_touchscreen
  interrupt_pin: GPIO4
  on_touch:
    - lambda: |-
          ESP_LOGI("cal", "x=%d, y=%d, x_raw=%d, y_raw=%0d",
              touch.x,
              touch.y,
              touch.x_raw,
              touch.y_raw
              );

lvgl:
  displays:
    - display_id: my_display
  buffer_size: 25%
  
  touchscreens:
    - touchscreen_id: my_touchscreen

  pages:
    - id: image_page
      widgets:
        - img:
            align: CENTER
            src: my_cat_image
            id: img_id
            radius: 11
            clip_corner: true

# Enable Home Assistant API
api:
  encryption:
    key: "<redacted>"

ota:
- platform: esphome
  password: "<redacted>"

wifi:
  ssid: !secret wifi_ssid
  password: !secret wifi_password

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "<redacted>"
    password: "<redacted>"

captive_portal:
    
1 Like

The default image type is binary, I.e. monochrome. type: RGB565 will get you colours.

1 Like

Now the code compoled. But the image not visible. The midea4.png is next to e.yaml in esphome folder

substitutions:
  lightbulb:     "\U000F0335"
  ceiling_light: "\U000F0769"
  floor_lamp:    "\U000F08DD"
  string_lights: "\U000F12BA"

esphome:
  name: home-display
  friendly_name: Home Display
  platformio_options:
    build_flags: "-DBOARD_HAS_PSRAM"
    board_build.arduino.memory_type: qio_opi
    board_build.flash_mode: dio
    board_upload.maximum_ram_size: 524288

esp32:
  board: esp32-s3-devkitc-1
  variant: esp32s3
  framework:
    type: esp-idf
    sdkconfig_options:
      CONFIG_ESP32S3_DEFAULT_CPU_FREQ_240: y
      CONFIG_ESP32S3_DATA_CACHE_64KB: y
      CONFIG_SPIRAM_FETCH_INSTRUCTIONS: y
      CONFIG_SPIRAM_RODATA: y

api:

ota:
  - platform: esphome

wifi:
  networks:
  - ssid: !secret wifi_ssid
    password: !secret wifi_password

web_server:
  port: 80   

external_components:
  - source:
      type: git
      url: https://github.com/clydebarrow/esphome
      ref: 82264dc2440981873b8400d613e0cc32d229daa3 #previous commit - wont be needed in the future
    components: [lvgl]

psram:
  mode: octal
  speed: 80MHz

logger:
  level: DEBUG

i2c:
  sda: GPIO08
  scl: GPIO09
  scan: True
  id: bus_a

uart:
  - id: mod_bus
    tx_pin: GPIO16
    rx_pin: GPIO15
    baud_rate: 9600
    parity: EVEN
    stop_bits: 1
    data_bits: 8

modbus:
  id: heatpump_modbus
  uart_id: mod_bus

modbus_controller:
  - id: "esp_modbus"
    address: 0x1
    modbus_id: heatpump_modbus
    setup_priority: -10
    update_interval: 10s

  - id: "abb_ev"
    address: 0x1
    modbus_id: heatpump_modbus
    setup_priority: -10
    update_interval: 10s

image:
  - file: "midea4.png"
    id: midea_logo
    resize: 400x600

display:
  - platform: rpi_dpi_rgb
    id: my_display
    auto_clear_enabled: false
    update_interval: never
    color_order: RGB
    pclk_frequency: 14MHz
    dimensions:
      width: 800
      height: 480
    de_pin:
      number: 5
    hsync_pin:
      number: 46
      ignore_strapping_warning: true
    vsync_pin:
      number: 3
      ignore_strapping_warning: true
    pclk_pin: 7
    pclk_inverted: false
    hsync_back_porch: 10
    hsync_front_porch: 20
    hsync_pulse_width: 10
    vsync_back_porch: 10
    vsync_front_porch: 10
    vsync_pulse_width: 10
    data_pins:
      red:
        - 1
        - 2
        - 42
        - 41
        - 40
      blue:
        - 14
        - 38
        - 18
        - 17
        - 10
      green:
        - 39
        - 0
        - 45
        - 48
        - 47
        - 21


font:
  - file: "gfonts://Roboto"
    id: roboto24
    size: 24
    bpp: 4
    extras:
      - file: 'fonts/materialdesignicons-webfont.ttf' # http://materialdesignicons.com/cdn/7.4.47/ 
        glyphs: [
          "\U000F004B",
          "\U0000f0ed",
          "\U000F006E",
          "\U000F012C",
          "\U000F179B",
          "\U000F0748",
          "\U000F1A1B",
          "\U000F02DC",
          "\U000F0A02",
          "\U000F035F",
          "\U000F0156",
          "\U000F0C5F", 
          "\U000f0084",
          "\U000f0091",
          "\U000F0335",
          ]
  - file: 'fonts/materialdesignicons-webfont.ttf' # http://materialdesignicons.com/cdn/7.4.47/ 
    id: weather70
    size: 70
    bpp: 4
    glyphs: &mdi-weather-glyphs
      - "\U000F0590" # mdi-weather-cloudy
      - "\U000F0F2F" # mdi-weather-cloudy-alert
      - "\U000F0E6E" # mdi-weather-cloudy-arrow-right
      - "\U000F0591" # mdi-weather-fog
      - "\U000F0592" # mdi-weather-hail
      - "\U000F0F30" # mdi-weather-hazy
      - "\U000F0898" # mdi-weather-hurricane
      - "\U000F0593" # mdi-weather-lightning
      - "\U000F067E" # mdi-weather-lightning-rainy
      - "\U000F0594" # mdi-weather-clear-night
      - "\U000F0F31" # mdi-weather-night-partly-cloudy
      - "\U000F0595" # mdi-weather-partly-cloudy
      - "\U000F0F32" # mdi-weather-partly-lightning
      - "\U000F0F33" # mdi-weather-partly-rainy
      - "\U000F0F34" # mdi-weather-partly-snowy
      - "\U000F0F35" # mdi-weather-partly-snowy-rainy
      - "\U000F0596" # mdi-weather-pouring
      - "\U000F0597" # mdi-weather-rainy
      - "\U000F0598" # mdi-weather-snowy
      - "\U000F0F36" # mdi-weather-snowy-heavy
      - "\U000F067F" # mdi-weather-snowy-rainy
      - "\U000F0599" # mdi-weather-sunny
      - "\U000F0F37" # mdi-weather-sunny-alert
      - "\U000F14E4" # mdi-weather-sunny-off
      - "\U000F059A" # mdi-weather-sunset
      - "\U000F059B" # mdi-weather-sunset-down
      - "\U000F059C" # mdi-weather-sunset-up
      - "\U000F0F38" # mdi-weather-tornado
      - "\U000F059D" # mdi-weather-windy
      - "\U000F059E" # mdi-weather-windy-variant

  - file: 'fonts/materialdesignicons-webfont.ttf' # http://materialdesignicons.com/cdn/7.4.47/ 
    id: light32
    size: 32
    bpp: 4
    glyphs: [
      "\U000F0335", # mdi-lightbulb
      "\U000F0769", # mdi-ceiling-light
      "\U000F08DD", # mdi-floor-lamp
      "\U000F12BA", # mdi-string-lights
      ]          
      
  - file: "gfonts://Roboto"
    id: roboto10
    size: 10
    bpp: 4
   


touchscreen:
  platform: gt911
  id: my_touch
  interrupt_pin: GPIO4
  on_touch:
    - lambda: |-
          ESP_LOGI("cal", "x=%d, y=%d, x_raw=%d, y_raw=%0d",
              touch.x,
              touch.y,
              touch.x_raw,
              touch.y_raw
              );

sensor:
  - platform: wifi_signal
    name: "WiFi Signal"
    id: wifi_signal_db
    update_interval: 60s
    entity_category: diagnostic
    internal: true

  - platform: copy
    source_id: wifi_signal_db
    name: "WiFi Strength"
    filters:
      - lambda: return min(max(2 * (x + 100.0), 0.0), 100.0);
    unit_of_measurement: "%"
    entity_category: diagnostic

  - platform: modbus_controller
    modbus_controller_id: "abb_ev"
    name: "ABB Import energy total"
    id: abb_import_energy_total
    address: 0x5000
    register_type: holding
    value_type: U_QWORD
    device_class: "energy"
    unit_of_measurement: "kWh"
    accuracy_decimals: 4
    state_class: "total_increasing"
    filters:
      - multiply: 0.0001
  - platform: modbus_controller
    modbus_controller_id: abb_ev
    name: "ABB Voltage L1-N"
    id: abb_voltage_l1_n
    address: 0x5B00
    register_type: holding
    value_type: U_DWORD
    accuracy_decimals: 1
    device_class: voltage
    unit_of_measurement: "V"
    filters:
      - multiply: 0.1      
  - platform: modbus_controller
    modbus_controller_id: "abb_ev"
    name: "ABB Power total"
    id: abb_power_total
    address: 0x5B14
    register_type: holding
    value_type: S_DWORD
    accuracy_decimals: 2
    device_class: power
    unit_of_measurement: "W"
    filters:
      - multiply: 0.01


text_sensor:
  - platform: wifi_info
    ip_address:
      name: "IP Address"
      entity_category: diagnostic
    ssid:
      name: "Connected SSID"
      entity_category: diagnostic
    mac_address:
      name: "Mac Address"
      entity_category: diagnostic

#-------------------------------------------
# LVGL Buttons
#-------------------------------------------
lvgl:
  displays:
    - display_id: my_display
  touchscreens:
    - touchscreen_id: my_touch
  on_idle:
    - timeout: 10s
      then:
        - logger.log: idle timeout
        - if:
            condition:
              lvgl.is_idle:
                timeout: 5s
            then:
              - logger.log: LVGL is idle
    - timeout: 15s
      then:
        - logger.log: idle 15s timeout

  style_definitions:
    - id: style_line
      line_color: 0x0000FF
      line_width: 8
      line_rounded: true
    - id: date_style
      text_font: roboto24
      align: center
      text_color: 0x333333
      bg_opa: cover
      radius: 4
      pad_all: 2

  theme:
    btn:
      text_font: roboto24
      scroll_on_focus: true
      group: general
      radius: 25
      width: 150
      height: 109
      pad_left: 10px
      pad_top: 10px
      pad_bottom: 10px
      pad_right: 10px
      shadow_width: 0
      bg_color: 0x313131
      text_color: 0xB6B6B6
      checked:
        bg_color: 0xCC5E14
        text_color: 0xB6B6B6

  page_wrap: true
  pages:
    - id: main_page
      skip: true
      layout:
        type: flex
        flex_flow: column_wrap
      width: 100%
      bg_color: 0x000000
      bg_opa: cover
      pad_all: 5
      widgets:
        - btn:
            height: 223
            checkable: true
            id: lv_button_1      
            widgets:
              - label:
                  text_font: roboto24
                  align: top_left
                  text: $lightbulb
                  id: lv_button_1_icon
              - label:
                  align: bottom_left
                  text: "Kitchen"
                  long_mode: dot
        - btn:
            checkable: true
            id: lv_button_2
            widgets:
              - label:
                  text_font: roboto24
                  align: top_left
                  text: $lightbulb
                  id: lv_button_2_icon
              - label:
                  align: bottom_left
                  text: "Outdoor"
                  long_mode: dot              
        - btn:
            checkable: true
            id: lv_button_3
            widgets:
              - label:
                  text_font: roboto24
                  align: top_left
                  text: $floor_lamp
                  id: lv_button_3_icon
              - label:
                  align: bottom_left
                  text: "Living Room"
                  long_mode: dot
        - btn:
            checkable: true
            id: lv_button_4
            widgets:
              - label:
                  text_font: roboto24
                  align: top_left
                  text: $lightbulb
                  id: lv_button_4_icon
              - label:
                  align: bottom_left
                  text: "Accent"
                  long_mode: dot
        - btn:
            checkable: true
            id: lv_button_5
            widgets:
              - label:
                  text_font: roboto24
                  align: top_left
                  text: $lightbulb
                  id: lv_button_5_icon
              - label:
                  align: bottom_left
                  text: "Bed Room"
                  long_mode: dot              
        - btn:
            checkable: true
            id: lv_button_6
            widgets:
              - label:
                  text_font: roboto24
                  align: top_left
                  text: $lightbulb
                  id: lv_button_6_icon
              - label:
                  id: display_time
                  align: bottom_left
                  text: "00:00am"
                  long_mode: dot
        - btn:
            checkable: true
            id: lv_button_7
            widgets:
              - label:
                  text_font: roboto24
                  align: top_left
                  text: $lightbulb
                  id: lv_button_7_icon
              - label:
                  align: bottom_left
                  text: "Fan"
                  long_mode: dot
        - btn:
            checkable: true
            id: lv_button_8
            widgets:
              - label:
                  text_font: roboto24
                  align: top_left
                  text: $lightbulb
                  id: lv_button_8_icon
              - label:
                  align: bottom_left
                  text: "Timer"
                  long_mode: dot              
        - btn:
            checkable: true
            id: lv_button_9
            widgets:
              - label:
                  text_font: roboto24
                  align: top_left
                  text: $lightbulb
                  id: lv_button_9_icon
              - label:
                  align: bottom_left
                  text: "Lamp"
                  long_mode: dot
        - btn:
            checkable: true
            id: lv_button_10
            widgets:
              - label:
                  text_font: roboto24
                  align: top_left
                  text: $lightbulb
                  id: lv_button_10_icon
              - label:
                  align: bottom_left
                  text: "Wall Spot"
                  long_mode: dot
        - btn:
            checkable: true
            id: lv_button_11
            widgets:
              - label:
                  text_font: roboto24
                  align: top_left
                  text: $lightbulb
                  id: lv_button_11_icon
              - label:
                  align: bottom_left
                  text: "Driveway"
                  long_mode: dot
        - btn:
            id: switch_to_page2
            widgets:
              - label:
                  align: center
                  text: "Go to Page 2"
            on_click:
              then:
                - lvgl.page.show: page2
        - btn:
            id: switch_to_page3
            widgets:
              - label:
                  align: center
                  text: "Go to Page 3"
            on_click:
              then:
                - lvgl.page.show: page3


    - id: page2
      skip: true
      layout:
        type: flex
        flex_flow: column_wrap
      width: 100%
      bg_color: 0x000000
      bg_opa: cover
      pad_all: 5
      widgets:
        - btn:
            id: switch_to_main_page
            widgets:
              - label:
                  align: center
                  text: "Go to Main Page"
                  text_font: roboto10
            on_click:
              then:
                - lvgl.page.show: main_page
        - label:
            id: abb_import_energy_label
            text: "ABB Import Energy: 0 kWh"
            text_font: roboto24
            text_color: 0xFFFFFF
            align: top_right
        - label:
            id: abb_voltage_l1_n_label
            text: "ABB Voltage L1-N"
            text_font: roboto24
            text_color: 0xFFFFFF            
            align: top_right
       
        - meter:
            id: abb_power_meter
            align: center
            scales:
              - range_from: 0
                range_to: 10000
                angle_range: 240
                rotation: 150
                ticks:
                  count: 11
                  length: 10
                  major:
                    stride: 1000
                    length: 13
                    label_gap: 13
                indicators:
                  - line:
                      id: abb_power_needle
                      width: 2
                      color: 0xFF0000
                      r_mod: -4
                  - tick_style:
                      start_value: 0
                      end_value: 5000
                      color_start: 0x0000bd
                      color_end: 0xbd0000
    - id: page3
      skip: true
      layout:
        type: flex
        flex_flow: column_wrap
      width: 100%
      bg_color: 0x000000
      bg_opa: cover
      pad_all: 5
      widgets:
        - img:
            align: CENTER
            src: midea_logo
            id: img_id
            radius: 11
            clip_corner: true
        - btn:
            id: switch_to_main_page2
            widgets:
              - label:
                  align: center
                  text: "Go to Main Page"
                  text_font: roboto10
            on_click:
              then:
                - lvgl.page.show: main_page
#        - label:
#            id: abb_import_energy_label2
#            text: "ABB Import Energy: 0 kWh"
#            text_font: roboto24
#            text_color: 0xFFFFFF
#            align: top_right
#        - label:
#            id: abb_voltage_l1_n_label2
#            text: "ABB Voltage L1-N"
#            text_font: roboto24
#            text_color: 0xFFFFFF            
#            align: top_right
#       
#        - meter:
#            id: abb_power_meter2
#            align: center
#            scales:
#              - range_from: 0
#                range_to: 10000
#                angle_range: 240
#                rotation: 150
#                ticks:
#                  count: 11
#                  length: 10
#                  major:
#                    stride: 1000
#                    length: 13
#                    label_gap: 13
#                indicators:
#                  - line:
#                      id: abb_power_needle2
#                      width: 2
#                      color: 0xFF0000
#                      r_mod: -4
#                  - tick_style:
#                      start_value: 0
#                      end_value: 5000
#                      color_start: 0x0000bd
#                      color_end: 0xbd0000





interval:
  - interval: 20s
    then:
      - lambda: |-
          char buffer_energy[64];
          snprintf(buffer_energy, sizeof(buffer_energy), "ABB Import Energy: %.4f kWh", id(abb_import_energy_total).state);
          lv_label_set_text(id(abb_import_energy_label), buffer_energy);
          
          char buffer_voltage[64];
          snprintf(buffer_voltage, sizeof(buffer_voltage), "ABB Voltage L1-N: %.1f V", id(abb_voltage_l1_n).state);
          lv_label_set_text(id(abb_voltage_l1_n_label), buffer_voltage);

You Cleaned the build files, didn’t you :wink:

Clyde answered that one already (Thank you BTW!).
I had the same issue as you with the logo image below not being visible until I followed Clyde’s comment above and included type: RGB565

  - file: https://esphome.io/_images/logo.png
    id: esphome_logo
    resize: 200x162

Now, for your specific issue, change

image:
  - file: "midea4.png"
    id: midea_logo
    resize: 400x600

to the following and it should work.

image:
  - file: "midea4.png"
    id: midea_logo
    resize: 400x600
    type: RGB565

From the display component page:

type (Optional): Specifies how to encode image internally. Defaults to BINARY for local images and TRANSPARENT_BINARY for MDIs.

  • BINARY: Two colors, suitable for 1 color displays or 2 color image in color displays. Uses 1 bit per pixel, 8 pixels per byte.

  • TRANSPARENT_BINARY: One color, any pixel that is fully transparent will not be drawn, and any other pixel will be the on color. Uses 1 bit per pixel, 8 pixels per byte.

  • GRAYSCALE: Full scale grey. Uses 8 bits per pixel, 1 pixel per byte.

  • RGB565: Lossy RGB color stored. Uses 2 bytes per pixel.

  • RGB24: Full RGB color stored. Uses 3 bytes per pixel.

  • RGBA: Full RGB color stored. Uses 4 bytes per pixel. Any pixel with an alpha value < 127 will not be drawn.

1 Like

Oh, I get it!

Thank you! You can see that I struggle a lot with the language barrier, but I managed.

the disp_bg_image: is use the ismage all pages?
If i need background only one page, it is possible?

Yes you can set that on a per page basis.

1 Like

can you show me a sample for this? I have not been successful so far.

Is there any way to show percent battery left? I can’t find any information about a GPIO being dedicated to the battery input.

Anyone have any luck getting deepsleep to work with touch screen wake?

I too would like to know this.