ESP32 Touchscreen

And specify the screen dimensions.

There is thread converting this very device within the last day. Esphome TFT displays question

Not required for ili9341, it has default dimensions, which you will see in the log. Unless also setting transform.

Interesting, in the other thread I pointed to, setting the dimensions seemed to fix it. But I bow to your superior knowledge.

Defining the CS pin got the entire screen to turn on instead of just the bit shown in the picture. But still no Hello World.
(seems this should be a Required parameter in the ILI9341 component definition)

Added the CS pin definition and got the whole screen to turn on.
Tried adding the dimensions as shown in the linked thread but still no Hello World.

No, it’s only required on your specific board. Other boards might have the CS pin hardwired. Same with the reset pin.

try show_test_card: true in the display config rather than the lambda.

Then maybe an Optional mention?

the other thread I pointed to, setting the dimensions seemed to fix it.

It depends what “it” was. Specifying the dimensions may be required to get a particular desired outcome, but not doing so won’t stop the display from working completely, for the pre-defined models including ili9341.

But I bow to your superior knowledge.

Deference not required. We’re all on a learning curve of some kind.

Good catch - it should be listed in the config options and is not - just mentioned once in an example.

The test card looked like what I’d expect a display test to look like.

Put the lambda back in and now I see the Hello World but it just blinks on the screen for a couple hundred mS then off and keeps repeating at about a 1Hz rate.

Probably quite normal with a 1Hz update rate and auto-clear, and using 8 bit colour. Without PSRAM you can’t have a proper 16 bit screen-size buffer so the update performance is miserable. Use LVGL and set buffer_size to 25% and it should be sweet.

Thanks for pointing to the LVGL component. Plan to dig into that today to see if I can get this thing working. Seems it would be helpful to also have a mention of LVGL in the various Display components.

Anyway, your mention of the auto_clear_enabled: property seemed like that might be a good short term workaround as this device is just going to be displaying some environmental values (temp, humidity, pressure, air quality…) that just don’t change that fast so an update rate of 1 second (60 seconds would be fine). So I added the property and set it to false and now the text doesn’t show at all again. So I changed it to true (which is the default) and the text still does not show. I have to remove the property to get the text back but of course it’s still blinking.

Also a little confused on the auto_clear_enabled: definition. It’s True by default which would force the display to clear after each write and indeed, that seems to be what’s happening. Setting it False it states, “keep the existing display content (must overwrite explicitly, e.g., only on data change)”. The way this is worded it seems to be saying that it will only update the display if the data to display has changed since the last update. And this makes sense as it would reduce the load on the device not needing to do a write operation when not needed. But as I stated, that’s not what I’m seeing. I would think it would write once after bootup then not clear the screen and not need to do any more writes because the data hasn’t changed.

Are we possibly seeing just difference in the device itself or is there possibly a bug in this component that’s causing this behavior?

First attempt with LVGL is at least encouraging. Need to figure out the orientation and then work out the lambdas.

Thanks for assistance :beers:

There are plenty of examples in the forum.

Can you please share the yaml that you now have?
This would be a good starting point for me…

This should print the current time and date in the center of the screen in landscape mode. The backlight should turn on after bootup and dim after 30 secs and then off in another 10 secs.

If you want Portrait mode. Change the ‘dimensions’ and ‘transform’ sections in ‘display’ as follows:

dimensions: 
      width: 240
      height: 320
    transform:
      swap_xy: false
      mirror_x: true
      mirror_y: false
substitutions:
  name: "ESP32-2432S028-display"
  friendly_name: ESP32-2432S028-display
  devicename: "ESP32-2432S028 Display"

esphome:
  name: ${name}
  friendly_name: ${friendly_name}
  min_version: 2024.6.0
  name_add_mac_suffix: false
  project:
    name: esphome.web
    version: dev
  on_boot:
    priority: -100
    then:
      - script.execute: backlight_timer

esp32:
  board: esp32dev
  framework:
    type: arduino

# Enable logging
logger:
  logs:
    component: ERROR

# Enable Home Assistant API
api:
  encryption: 
    key: !secret haapi_key

# Allow Over-The-Air updates
ota:
  - platform: esphome
    password: !secret ota_password

# Allow provisioning Wi-Fi via serial
#improv_serial:

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

  manual_ip:
    static_ip: 10.0.0.135
    gateway: 10.0.0.1
    subnet: 255.255.255.0
    dns1: 75.75.75.75
    dns2: 75.75.76.76
  
  fast_connect: off

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "ESP32-2432S028"
    password: !secret ap_password

# In combination with the `ap` this allows the user
# to provision wifi credentials to the device via WiFi AP.
# captive_portal:

dashboard_import:
  package_import_url: github://esphome/example-configs/esphome-web/esp32.yaml@main
  import_full_config: true

# Sets up Bluetooth LE (Only on ESP32) to allow the user
# to provision wifi credentials to the device.
# esp32_improv:
#  authorizer: none

# To have a "next url" for improv serial
web_server:

time:
  - platform: homeassistant
    id: esptime

spi:
  - id: lcd
    clk_pin: GPIO14
    mosi_pin: GPIO13
    miso_pin: GPIO12
  - id: touch
    clk_pin: GPIO25
    mosi_pin: GPIO32
    miso_pin: GPIO39

i2c:
  sda: GPIO27
  scl: GPIO22
  scan: true
  id: i2c_bus_a


display:
  - platform: ili9xxx
    model: ili9341
    spi_id: lcd
    dc_pin: GPIO2
    cs_pin: GPIO15
    id: display_1
    update_interval: never
    auto_clear_enabled: false
    show_test_card: false
    dimensions: 
      width: 320
      height: 240
    transform:
      swap_xy: true
      mirror_x: false
      mirror_y: false

lvgl:
  displays:
    - display_1
  touchscreens:
    - touchscreen_1
  buffer_size: 25%
  pages:
    - id: main_page
      widgets:
        - label:
            align: CENTER
            text:
              time_format: "%c"

# Define pins for backlight display and rear LED
output:
  - platform: ledc
    pin: GPIO21
    id: backlight
  - platform: ledc
    id: output_red
    pin: GPIO4
    inverted: true
  - platform: ledc
    id: output_green
    pin: GPIO16
    inverted: true
  - platform: ledc
    id: output_blue
    pin: GPIO17
    inverted: true
#  speaker P4
#  - platform: ledc
#    pin: GPIO26
#    id: rtttl_out

# Define a monochromatic, dimmable light for the backlight
light:
  - platform: monochromatic
    output: backlight
    name: "Display Backlight"
    id: back_light
    restore_mode: ALWAYS_OFF
  - platform: rgb
    name: LED
    red: output_red
    id: led
    green: output_green
    blue: output_blue
    restore_mode: ALWAYS_OFF

touchscreen:
  platform: xpt2046
  spi_id: touch
  cs_pin: GPIO33
  interrupt_pin: GPIO36
  update_interval: 50ms
  id: touchscreen_1
  # report_interval: 1s
  threshold: 400
  calibration:
    x_min: 300
    x_max: 3900
    y_min: 200
    y_max: 3700
  on_touch:
    - script.stop: backlight_timer
    - script.execute: backlight_timer
  #Uncomment for calibrations
#    - lambda: |-
#          ESP_LOGI("cal", "x=%d, y=%d, x_raw=%d, y_raw=%0d",
#              touch.x,
#              touch.y,
#              touch.x_raw,
#              touch.y_raw
#              );
  #Uncomment for calibrations

#This is the script for turn off the backlight after some seconds of inactivity
script:
  id: backlight_timer
  then:
  - light.turn_on:
      id: back_light
      brightness: 100%
  - delay: 30s
  - light.turn_on:
      id: back_light
      brightness: 50%
  - delay: 10s
  - light.turn_off: back_light

switch:
  - platform: restart
    name: "ESP32-2432S028 Display Restart"

Check out the new LVGL stuff. It’s easier then Lamdbas and you can do a lot more with it.

https://community.home-assistant.io/t/guition-4-480x480-esp32-s3-4848s040-smart-display-with-lvgl

2 Likes

Thank you,

This gives me a good starting point.
I now have a full screen image!!