Waveshare ESP32-S3-LCD-1.85

I’m venturing into using a display in ESPHome for the first time, but I’m having no luck. Any pointers are appreciated.

I am using this device:

I’ve tried using similar code as shared in this thread, since they share similar screens: GUITION 1.8” 360x360 ESP32-S3-JC3636W518 Smart Display

I did change out the pin definitions (except for the EXIO reset pin, which I’m not sure how to reference), and used the init sequence I found in the sample code (in esp_lcd_st77916.c).

My current yaml:

If I comment out the lvgl section and flash, the device is available and I can toggle the switch for the backlight, but with the backlight on the screen is just “snow” (I’m not sure if that’s normal). However, if I flash with the lvgl section the screen remains black and the device does not come online.

Any suggestions for what I’m missing?

1 Like

The LCD reset pin is on an expander so you need to add a component for that - pca9554 I think. Then specify the pin as per the expander docs.

1 Like

Thanks! That helps a bit, but alas I still get the same results.

I updated the gist, but the new bits I added:

i2c:
  sda: GPIO11
  scl: GPIO10
  scan: true

pca9554:
  - id: 'pca9554a_device'

...
    reset_pin: 
      pca9554: pca9554a_device
      number: 2

1 Like

Pin 1, not pin 2. They are 0-based in the config.

1 Like

Hrm, well I tried that, and it still is mostly the same. “Snow” without the display component; wIth the display component, just a dark screen. However, ESPHome shows it as online, and I can ping it. But I cannot connect to the web server and again, all I see is a black screen. So…could be progress?

I haven’t had time to confirm if this is indeed the fix, but try adding a psram section as in this example:

I just set the speed to 40MHz for the initial test, but I’m seeing “Hello World!” on my screen now.

2 Likes

Works! Nice!!!

Thanks much to both of you. I also updated my gist with the working code.

1 Like

No, thank you!

I’m hoping to get more of this configured, so I’ll update if/when I get more of it working.

Top priority is audio, which I have tried and failed so far, but I was using Arduino framework, and this is using esp-idf, so I’m hoping that makes a difference.

I also have the touchscreen version, and hop to get that working as well.

1 Like

Thanks, yes, I want to get more of it working as well, including the speakers and microphone at least. I’ll share when/if I have more working additions.

I got sidetracked yesterday playing with the screen. :slight_smile:

1 Like

Edit: I updated the example to include both mic and speaker that have been confirmed to work. It should also be a complete example with UDP send and receive code.

It’s a bit of a hack, using the microphone event to read and feed the speaker data, but it works.

I have been able to stream audio out of the microphone using this configuration:

i2s_audio:
  - id: i2s_in
    i2s_lrclk_pin: GPIO2
    i2s_bclk_pin: GPIO15
  - id: i2s_out
    i2s_lrclk_pin: GPIO38
    i2s_bclk_pin: GPIO48
    #i2s_mclk_pin: GPIO21

microphone:
  - platform: i2s_audio
    id: i2s_microphone
    i2s_audio_id: i2s_in
    i2s_din_pin: GPIO39
    adc_type: external
    pdm: false
    channel: right
    sample_rate: 16000
    bits_per_sample: 16bit
    on_data:
      - lambda: |-
          static std::vector<int16_t> send_buffer;
          static std::vector<uint8_t> recv_buffer(1024);
          static struct sockaddr_in destination = {
            .sin_family = AF_INET,
            .sin_port = htons(12345),
            .sin_addr = { .s_addr = inet_addr("192.168.1.165") }
          };
          static struct sockaddr_in source = {
            .sin_family = AF_INET,
            .sin_port = htons(12346),
            .sin_addr = { .s_addr = INADDR_ANY }
          };
          static int send_sock = ::socket(AF_INET, SOCK_DGRAM, 0);
          static int recv_sock = ::socket(AF_INET, SOCK_DGRAM, 0);
          static bool bound = false;
          if (!bound) {
            int flags = fcntl(recv_sock, F_GETFL, 0);
            fcntl(recv_sock, F_SETFL, flags | O_NONBLOCK);
            bind(recv_sock, (const sockaddr*)&source, sizeof(source));
            bound = true;
          }
          for (uint16_t byte : x) {
            send_buffer.push_back(byte);
          }
          int send_cnt = send_buffer.size();
          if(send_cnt >= 256) {
            ::sendto(send_sock, send_buffer.data(), send_cnt * 2, 0, reinterpret_cast<sockaddr*>(&destination), sizeof(destination));
            send_buffer.clear();
          }
          socklen_t fromlen = sizeof(source);
          int recv_cnt = ::recvfrom(recv_sock, recv_buffer.data(), recv_buffer.size(), 0, reinterpret_cast<sockaddr*>(&source), &fromlen);
          if (recv_cnt > 0) {
            id(i2s_speaker).play(recv_buffer.data(), recv_cnt, 0);
          }

button:
  - platform: template
    name: "Enable Microphone"
    on_press:
      - microphone.capture: i2s_microphone
      - delay: 10s
      - microphone.stop_capture: i2s_microphone
        
speaker:
  - platform: i2s_audio
    id: i2s_speaker
    i2s_audio_id: i2s_out
    i2s_dout_pin: GPIO47
    dac_type: external
    sample_rate: 16000
    bits_per_sample: 16bit
    channel: mono

I suspect the problem that I was having previously was not knowing that I needed to start capture, which is what the button is for.

I got most of this from here: Is there a way to stream audio from one ESPHome to another? - #9 by haforum

I’m currently trying to figure out how to do something similar for the speaker to test it.

1 Like

Nice. Works for me too, as does the voice assistant.

voice_assistant:
  id: va
  microphone: i2s_microphone
  speaker: i2s_speaker

binary_sensor:
  - platform: gpio
    pin: GPIO6
    name: "Power Button"
    on_press:
      - voice_assistant.start:
          silence_detection: false
    on_release:
      - voice_assistant.stop:                           
  - platform: gpio
    pin: GPIO0
    name: "Boot Button" 

Unfortunately it appears media player isn’t compatible with esp-idk. :frowning:
Edit: It does work though if you change to arduino…where the display isn’t compatible.

I updated my gist.

You need to use the external component: speaker media player component; the media player cannot be used under esp-idf. This content will be merged soon.

external_components:
  - source:
      type: git
      url: https://github.com/esphome/voice-kit
      ref: dev
    components:
      - media_player
      - nabu
      - voice_assistant
media_player:
  - platform: nabu
    id: nabu_media_player
    name: Media Player
    internal: false
    speaker:
    sample_rate: 48000
    volume_increment: 0.05
    volume_min: 0.1
    volume_max: 1
1 Like

Works perfectly, thanks!

I had been trying to read/play from the tf card, without any luck. With a working media player, that is less necessary.

This one has wake_word_detection enabled. Its working fine so far:

esphome:
  name: esp32-s3-touch-lcd-185
  friendly_name: esp32-s3-touch-lcd-1.85

# Enable logging
logger:

# Enable Home Assistant API
api:
  on_client_connected:
    then:
      - delay: 1s
      - voice_assistant.start_continuous:
      - delay: 1s
      - voice_assistant.stop:
      - delay: 2s
      - voice_assistant.start_continuous:
  encryption:
    key: "supersecret"
  services:
    - service: set_display_text
      variables:
        new_text: string
      then:
        - text_sensor.template.publish:
            id: display_text
            state: !lambda 'return new_text;'

external_components:
  - source: github://pr#5230
    components: esp_adf
    refresh: 0s

ota:
  - platform: esphome
    password: "password"

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

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Esp32-S3-Touch-Lcd-185"
    password: "DZGnV9UlnSE4"

captive_portal:
  

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

psram:
  mode: octal
  speed: 120MHz
    
web_server:
  port: 80
  version: 2
  include_internal: true

i2s_audio:
  - id: i2s_in
    i2s_lrclk_pin: GPIO2
    i2s_bclk_pin: GPIO15
  - id: i2s_out
    i2s_lrclk_pin: GPIO38
    i2s_bclk_pin: GPIO48

speaker:
  - platform: i2s_audio
    id: i2s_speaker
    i2s_audio_id: i2s_out
    i2s_dout_pin: GPIO47
    dac_type: external
    channel: stereo

microphone:
  - platform: i2s_audio
    id: i2s_microphone
    i2s_audio_id: i2s_in
    i2s_din_pin: GPIO39
    adc_type: external
    pdm: false
    channel: right
    sample_rate: 16000
    bits_per_sample: 16bit

voice_assistant:
  id: va
  microphone: i2s_microphone
  speaker: i2s_speaker
  use_wake_word: true

binary_sensor:
  - platform: gpio
    pin: GPIO6
    name: "Power Button"
    on_press:
      - voice_assistant.start:
          silence_detection: false
    on_release:
      - voice_assistant.stop:                           
  - platform: gpio
    pin: GPIO0
    name: "Boot Button" 

i2c:
  sda: GPIO11
  scl: GPIO10
  scan: true

pca9554:
  - id: 'pca9554a_device'

output:
  - platform: ledc
    pin: GPIO5
    id: backlight

light:
  - platform: monochromatic
    output: backlight
    name: "backlight Light" 
    restore_mode: ALWAYS_ON

spi:
  id: display_qspi
  type: quad
  clk_pin: GPIO40
  data_pins: [GPIO46, GPIO45, GPIO42, GPIO41]

display:
  - platform: qspi_dbi
    model: CUSTOM
    # data_rate: 40MHz
    id: main_display
    spi_id: display_qspi
    color_order: rgb
    dimensions:
      height: 360
      width: 360
    cs_pin: GPIO21
    reset_pin: 
      pca9554: pca9554a_device
      number: 1
    auto_clear_enabled: false #set to false for LVGL    
    init_sequence:
      - [ 0xF0, 0x08 ]
      - [ 0xF2, 0x08 ]
      - [ 0x9B, 0x51 ]
      - [ 0x86, 0x53 ]
      - [ 0xF2, 0x80 ]
      - [ 0xF0, 0x00 ]
      - [ 0xF0, 0x01 ]
      - [ 0xF1, 0x01 ]
      - [ 0xB0, 0x54 ]
      - [ 0xB1, 0x3F ]
      - [ 0xB2, 0x2A ]
      - [ 0xB4, 0x46 ]
      - [ 0xB5, 0x34 ]
      - [ 0xB6, 0xD5 ]
      - [ 0xB7, 0x30 ]
      - [ 0xBA, 0x00 ]
      - [ 0xBB, 0x08 ]
      - [ 0xBC, 0x08 ]
      - [ 0xBD, 0x00 ]
      - [ 0xC0, 0x80 ]
      - [ 0xC1, 0x10 ]
      - [ 0xC2, 0x37 ]
      - [ 0xC3, 0x80 ]
      - [ 0xC4, 0x10 ]
      - [ 0xC5, 0x37 ]
      - [ 0xC6, 0xA9 ]
      - [ 0xC7, 0x41 ]
      - [ 0xC8, 0x51 ]
      - [ 0xC9, 0xA9 ]
      - [ 0xCA, 0x41 ]
      - [ 0xCB, 0x51 ]
      - [ 0xD0, 0x91 ]
      - [ 0xD1, 0x68 ]
      - [ 0xD2, 0x69 ]
      - [ 0xF5, 0x00, 0xA5 ]
      - [ 0xDD, 0x3F ]
      - [ 0xDE, 0x3F ]
      - [ 0xF1, 0x10 ]
      - [ 0xF0, 0x00 ]
      - [ 0xF0, 0x02 ]
      - [ 0xE0, 0xF0, 0x06, 0x0B, 0x09, 0x09, 0x16, 0x32, 0x44, 0x4A, 0x37, 0x13, 0x13, 0x2E, 0x34 ]
      - [ 0xE1, 0xF0, 0x06, 0x0B, 0x09, 0x08, 0x05, 0x32, 0x33, 0x49, 0x17, 0x13, 0x13, 0x2E, 0x34 ]
      - [ 0xF0, 0x10 ]
      - [ 0xF3, 0x10 ]
      - [ 0xE0, 0x0A ]
      - [ 0xE1, 0x00 ]
      - [ 0xE2, 0x00 ]
      - [ 0xE3, 0x00 ]
      - [ 0xE4, 0xE0 ]
      - [ 0xE5, 0x06 ]
      - [ 0xE6, 0x21 ]
      - [ 0xE7, 0x00 ]
      - [ 0xE8, 0x05 ]
      - [ 0xE9, 0x82 ]
      - [ 0xEA, 0xDF ]
      - [ 0xEB, 0x89 ]
      - [ 0xEC, 0x20 ]
      - [ 0xED, 0x14 ]
      - [ 0xEE, 0xFF ]
      - [ 0xEF, 0x00 ]
      - [ 0xF8, 0xFF ]
      - [ 0xF9, 0x00 ]
      - [ 0xFA, 0x00 ]
      - [ 0xFB, 0x30 ]
      - [ 0xFC, 0x00 ]
      - [ 0xFD, 0x00 ]
      - [ 0xFE, 0x00 ]
      - [ 0xFF, 0x00 ]
      - [ 0x60, 0x42 ]
      - [ 0x61, 0xE0 ]
      - [ 0x62, 0x40 ]
      - [ 0x63, 0x40 ]
      - [ 0x64, 0x02 ]
      - [ 0x65, 0x00 ]
      - [ 0x66, 0x40 ]
      - [ 0x67, 0x03 ]
      - [ 0x68, 0x00 ]
      - [ 0x69, 0x00 ]
      - [ 0x6A, 0x00 ]
      - [ 0x6B, 0x00 ]
      - [ 0x70, 0x42 ]
      - [ 0x71, 0xE0 ]
      - [ 0x72, 0x40 ]
      - [ 0x73, 0x40 ]
      - [ 0x74, 0x02 ]
      - [ 0x75, 0x00 ]
      - [ 0x76, 0x40 ]
      - [ 0x77, 0x03 ]
      - [ 0x78, 0x00 ]
      - [ 0x79, 0x00 ]
      - [ 0x7A, 0x00 ]
      - [ 0x7B, 0x00 ]
      - [ 0x80, 0x48 ]
      - [ 0x81, 0x00 ]
      - [ 0x82, 0x05 ]
      - [ 0x83, 0x02 ]
      - [ 0x84, 0xDD ]
      - [ 0x85, 0x00 ]
      - [ 0x86, 0x00 ]
      - [ 0x87, 0x00 ]
      - [ 0x88, 0x48 ]
      - [ 0x89, 0x00 ]
      - [ 0x8A, 0x07 ]
      - [ 0x8B, 0x02 ]
      - [ 0x8C, 0xDF ]
      - [ 0x8D, 0x00 ]
      - [ 0x8E, 0x00 ]
      - [ 0x8F, 0x00 ]
      - [ 0x90, 0x48 ]
      - [ 0x91, 0x00 ]
      - [ 0x92, 0x09 ]
      - [ 0x93, 0x02 ]
      - [ 0x94, 0xE1 ]
      - [ 0x95, 0x00 ]
      - [ 0x96, 0x00 ]
      - [ 0x97, 0x00 ]
      - [ 0x98, 0x48 ]
      - [ 0x99, 0x00 ]
      - [ 0x9A, 0x0B ]
      - [ 0x9B, 0x02 ]
      - [ 0x9C, 0xE3 ]
      - [ 0x9D, 0x00 ]
      - [ 0x9E, 0x00 ]
      - [ 0x9F, 0x00 ]
      - [ 0xA0, 0x48 ]
      - [ 0xA1, 0x00 ]
      - [ 0xA2, 0x04 ]
      - [ 0xA3, 0x02 ]
      - [ 0xA4, 0xDC ]
      - [ 0xA5, 0x00 ]
      - [ 0xA6, 0x00 ]
      - [ 0xA7, 0x00 ]
      - [ 0xA8, 0x48 ]
      - [ 0xA9, 0x00 ]
      - [ 0xAA, 0x06 ]
      - [ 0xAB, 0x02 ]
      - [ 0xAC, 0xDE ]
      - [ 0xAD, 0x00 ]
      - [ 0xAE, 0x00 ]
      - [ 0xAF, 0x00 ]
      - [ 0xB0, 0x48 ]
      - [ 0xB1, 0x00 ]
      - [ 0xB2, 0x08 ]
      - [ 0xB3, 0x02 ]
      - [ 0xB4, 0xE0 ]
      - [ 0xB5, 0x00 ]
      - [ 0xB6, 0x00 ]
      - [ 0xB7, 0x00 ]
      - [ 0xB8, 0x48 ]
      - [ 0xB9, 0x00 ]
      - [ 0xBA, 0x0A ]
      - [ 0xBB, 0x02 ]
      - [ 0xBC, 0xE2 ]
      - [ 0xBD, 0x00 ]
      - [ 0xBE, 0x00 ]
      - [ 0xBF, 0x00 ]
      - [ 0xC0, 0x12 ]
      - [ 0xC1, 0xAA ]
      - [ 0xC2, 0x65 ]
      - [ 0xC3, 0x74 ]
      - [ 0xC4, 0x47 ]
      - [ 0xC5, 0x56 ]
      - [ 0xC6, 0x00 ]
      - [ 0xC7, 0x88 ]
      - [ 0xC8, 0x99 ]
      - [ 0xC9, 0x33 ]
      - [ 0xD0, 0x21 ]
      - [ 0xD1, 0xAA ]
      - [ 0xD2, 0x65 ]
      - [ 0xD3, 0x74 ]
      - [ 0xD4, 0x47 ]
      - [ 0xD5, 0x56 ]
      - [ 0xD6, 0x00 ]
      - [ 0xD7, 0x88 ]
      - [ 0xD8, 0x99 ]
      - [ 0xD9, 0x33 ]
      - [ 0xF3, 0x01 ]
      - [ 0xF0, 0x00 ]
      - [ 0xF0, 0x01 ]
      - [ 0xF1, 0x01 ]
      - [ 0xA0, 0x0B ]
      - [ 0xA3, 0x2A ]
      - [ 0xA5, 0xC3 ]
      - delay 1ms
      - [ 0xA3, 0x2B ]
      - [ 0xA5, 0xC3 ]
      - delay 1ms
      - [ 0xA3, 0x2C ]
      - [ 0xA5, 0xC3 ]
      - delay 1ms
      - [ 0xA3, 0x2D ]
      - [ 0xA5, 0xC3 ]
      - delay 1ms
      - [ 0xA3, 0x2E ]
      - [ 0xA5, 0xC3 ]
      - delay 1ms
      - [ 0xA3, 0x2F ]
      - [ 0xA5, 0xC3 ]
      - delay 1ms
      - [ 0xA3, 0x30 ]
      - [ 0xA5, 0xC3 ]
      - delay 1ms
      - [ 0xA3, 0x31 ]
      - [ 0xA5, 0xC3 ]
      - delay 1ms
      - [ 0xA3, 0x32 ]
      - [ 0xA5, 0xC3 ]
      - delay 1ms
      - [ 0xA3, 0x33 ]
      - [ 0xA5, 0xC3 ]
      - delay 1ms
      - [ 0xA0, 0x09 ]
      - [ 0xF1, 0x10 ]
      - [ 0xF0, 0x00 ]
      - [ 0x2A, 0x00, 0x00, 0x01, 0x67 ]
      - [ 0x2B, 0x01, 0x68, 0x01, 0x68 ]
      - [ 0x4D, 0x00 ]
      - [ 0x4E, 0x00 ]
      - [ 0x4F, 0x00 ]
      - [ 0x4C, 0x01 ]
      - delay 10ms
      - [ 0x4C, 0x00 ]
      - [ 0x2A, 0x00, 0x00, 0x01, 0x67 ]
      - [ 0x2B, 0x00, 0x00, 0x01, 0x67 ]
      - [ 0x3A, 0x55 ]
      - [ 0x21, 0x00 ]
      - [ 0x11, 0x00 ]
      - delay 120ms
      - [ 0x29, 0x00 ]

font:
  - file: "fonts/Montserrat-Medium.ttf" 
    id: montserrat_48
    size: 48

lvgl:
  displays:
    - main_display
  widgets:
    - label:
        id: display_label
        align: CENTER
        text: "Waiting for Updates..."
        text_font: montserrat_48 
        long_mode: WRAP 
        width: 300



text_sensor:
  - platform: template
    name: "Display Text2"
    id: display_text
    update_interval: never
    on_value:
      then:
        - lambda: |-
            if (id(display_label)) { 
              lv_label_set_text(id(display_label), x.c_str());  
              lv_refr_now(NULL); 
            }

matze, trying your code and getting errors:

1 Like

Just remove the fonts or download it from font.google.com:

I now also have the touchscreen working!

This is the code without the font:

esphome:
  name: esp32-s3-touch-lcd-185
  friendly_name: esp32-s3-touch-lcd-1.85

# Enable logging
logger:

# Enable Home Assistant API
api:
  on_client_connected:
    then:
      - delay: 1s
      - voice_assistant.start_continuous:
      - delay: 1s
      - voice_assistant.stop:
      - delay: 2s
      - voice_assistant.start_continuous:
  encryption:
    key: !secret encryption_key
  services:
    - service: set_display_text
      variables:
        new_text: string  # "text" wird zu "new_text" geändert
      then:
        - text_sensor.template.publish:
            id: display_text
            state: !lambda 'return new_text;'

external_components:
  - source: github://pr#5230
    components: esp_adf
    refresh: 0s
  - source:
      type: git
      url: https://github.com/esphome/voice-kit
      ref: dev
    components:
      - media_player
      - nabu
      - voice_assistant

media_player:
  - platform: nabu
    id: nabu_media_player
    name: Media Player
    internal: false
    speaker: i2s_speaker
    sample_rate: 48000
    volume_increment: 0.05
    volume_min: 0.1
    volume_max: 1    

ota:
  - platform: esphome
    password: !secret ota_password

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

  # Enable fallback hotspot (captive portal) in case wifi connection fails
  ap:
    ssid: "Esp32-S3-Touch-Lcd-185"
    password: "DZGnV9UlnSE4"

captive_portal:
  

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

psram:
  mode: octal
  speed: 120MHz
    
web_server:
  port: 80
  version: 2
  include_internal: true

i2s_audio:
  - id: i2s_in
    i2s_lrclk_pin: GPIO2
    i2s_bclk_pin: GPIO15
  - id: i2s_out
    i2s_lrclk_pin: GPIO38
    i2s_bclk_pin: GPIO48

speaker:
  - platform: i2s_audio
    id: i2s_speaker
    i2s_audio_id: i2s_out
    i2s_dout_pin: GPIO47
    dac_type: external
    channel: stereo

# Media Player does not work for esp-idf 
# media_player:
#   - platform: i2s_audio
#     name: ESPHome I2S Media Player
#     dac_type: external
#     i2s_dout_pin: GPIO47
#     i2s_audio_id: i2s_out
#     mode: stereo

microphone:
  - platform: i2s_audio
    id: i2s_microphone
    i2s_audio_id: i2s_in
    i2s_din_pin: GPIO39
    adc_type: external
    pdm: false
    channel: right
    sample_rate: 16000
    bits_per_sample: 16bit

voice_assistant:
  id: va
  microphone: i2s_microphone
  speaker: i2s_speaker
  use_wake_word: true
  on_wake_word_detected:
    then:
      - light.turn_on:
          id: display_backlight
          brightness: 100%
      - lvgl.resume:
      - text_sensor.template.publish:
          id: display_text
          state: "I'm listening"      
      - lvgl.widget.redraw:      
  on_tts_end:
    then:
      - light.turn_on:
          id: display_backlight    
          brightness: 30%
      - text_sensor.template.publish:
          id: display_text
          state: "Say OK Nabu..."
  on_client_connected:
      - text_sensor.template.publish:
          id: display_text
          state: "Say OK Nabu..."

binary_sensor:
  - platform: gpio
    pin: GPIO6
    name: "Power Button"
    on_press:
      - voice_assistant.start:
          silence_detection: false
  - platform: gpio
    pin: GPIO0
    name: "Boot Button" 
  - platform: cst816
    name: "Touch"      

i2c:
  - id: i2c_main
    sda: GPIO11  # Haupt-I2C (für Display, Sensoren, etc.)
    scl: GPIO10
    scan: true

  - id: i2c_touch
    sda: GPIO1
    scl: GPIO3
    frequency: 400kHz
    scan: false  # Prüft, ob das Touchpanel gefunden wird


pca9554:
  - id: 'pca9554a_device'
    i2c_id: i2c_main

output:
  - platform: ledc
    pin: GPIO5
    id: backlight

light:
  - platform: monochromatic
    output: backlight
    id: display_backlight
    name: "backlight Light" 
    restore_mode: ALWAYS_ON

spi:
  id: display_qspi
  type: quad
  clk_pin: GPIO40
  data_pins: [GPIO46, GPIO45, GPIO42, GPIO41]

display:
  - platform: qspi_dbi
    model: CUSTOM
    #lambda: |-
    #  auto touch = id(my_touchscreen)->get_touch();
    #  if (touch) // or touch.has_value()
    #    it.filled_circle(touch.value().x, touch.value().y, 10, RED);    
    # data_rate: 40MHz
    id: main_display
    spi_id: display_qspi
    color_order: rgb
    dimensions:
      height: 360
      width: 360
    cs_pin: GPIO21
    reset_pin: 
      pca9554: pca9554a_device
      number: 1
    auto_clear_enabled: false #set to false for LVGL    
    init_sequence:
      - [ 0xF0, 0x08 ]
      - [ 0xF2, 0x08 ]
      - [ 0x9B, 0x51 ]
      - [ 0x86, 0x53 ]
      - [ 0xF2, 0x80 ]
      - [ 0xF0, 0x00 ]
      - [ 0xF0, 0x01 ]
      - [ 0xF1, 0x01 ]
      - [ 0xB0, 0x54 ]
      - [ 0xB1, 0x3F ]
      - [ 0xB2, 0x2A ]
      - [ 0xB4, 0x46 ]
      - [ 0xB5, 0x34 ]
      - [ 0xB6, 0xD5 ]
      - [ 0xB7, 0x30 ]
      - [ 0xBA, 0x00 ]
      - [ 0xBB, 0x08 ]
      - [ 0xBC, 0x08 ]
      - [ 0xBD, 0x00 ]
      - [ 0xC0, 0x80 ]
      - [ 0xC1, 0x10 ]
      - [ 0xC2, 0x37 ]
      - [ 0xC3, 0x80 ]
      - [ 0xC4, 0x10 ]
      - [ 0xC5, 0x37 ]
      - [ 0xC6, 0xA9 ]
      - [ 0xC7, 0x41 ]
      - [ 0xC8, 0x51 ]
      - [ 0xC9, 0xA9 ]
      - [ 0xCA, 0x41 ]
      - [ 0xCB, 0x51 ]
      - [ 0xD0, 0x91 ]
      - [ 0xD1, 0x68 ]
      - [ 0xD2, 0x69 ]
      - [ 0xF5, 0x00, 0xA5 ]
      - [ 0xDD, 0x3F ]
      - [ 0xDE, 0x3F ]
      - [ 0xF1, 0x10 ]
      - [ 0xF0, 0x00 ]
      - [ 0xF0, 0x02 ]
      - [ 0xE0, 0xF0, 0x06, 0x0B, 0x09, 0x09, 0x16, 0x32, 0x44, 0x4A, 0x37, 0x13, 0x13, 0x2E, 0x34 ]
      - [ 0xE1, 0xF0, 0x06, 0x0B, 0x09, 0x08, 0x05, 0x32, 0x33, 0x49, 0x17, 0x13, 0x13, 0x2E, 0x34 ]
      - [ 0xF0, 0x10 ]
      - [ 0xF3, 0x10 ]
      - [ 0xE0, 0x0A ]
      - [ 0xE1, 0x00 ]
      - [ 0xE2, 0x00 ]
      - [ 0xE3, 0x00 ]
      - [ 0xE4, 0xE0 ]
      - [ 0xE5, 0x06 ]
      - [ 0xE6, 0x21 ]
      - [ 0xE7, 0x00 ]
      - [ 0xE8, 0x05 ]
      - [ 0xE9, 0x82 ]
      - [ 0xEA, 0xDF ]
      - [ 0xEB, 0x89 ]
      - [ 0xEC, 0x20 ]
      - [ 0xED, 0x14 ]
      - [ 0xEE, 0xFF ]
      - [ 0xEF, 0x00 ]
      - [ 0xF8, 0xFF ]
      - [ 0xF9, 0x00 ]
      - [ 0xFA, 0x00 ]
      - [ 0xFB, 0x30 ]
      - [ 0xFC, 0x00 ]
      - [ 0xFD, 0x00 ]
      - [ 0xFE, 0x00 ]
      - [ 0xFF, 0x00 ]
      - [ 0x60, 0x42 ]
      - [ 0x61, 0xE0 ]
      - [ 0x62, 0x40 ]
      - [ 0x63, 0x40 ]
      - [ 0x64, 0x02 ]
      - [ 0x65, 0x00 ]
      - [ 0x66, 0x40 ]
      - [ 0x67, 0x03 ]
      - [ 0x68, 0x00 ]
      - [ 0x69, 0x00 ]
      - [ 0x6A, 0x00 ]
      - [ 0x6B, 0x00 ]
      - [ 0x70, 0x42 ]
      - [ 0x71, 0xE0 ]
      - [ 0x72, 0x40 ]
      - [ 0x73, 0x40 ]
      - [ 0x74, 0x02 ]
      - [ 0x75, 0x00 ]
      - [ 0x76, 0x40 ]
      - [ 0x77, 0x03 ]
      - [ 0x78, 0x00 ]
      - [ 0x79, 0x00 ]
      - [ 0x7A, 0x00 ]
      - [ 0x7B, 0x00 ]
      - [ 0x80, 0x48 ]
      - [ 0x81, 0x00 ]
      - [ 0x82, 0x05 ]
      - [ 0x83, 0x02 ]
      - [ 0x84, 0xDD ]
      - [ 0x85, 0x00 ]
      - [ 0x86, 0x00 ]
      - [ 0x87, 0x00 ]
      - [ 0x88, 0x48 ]
      - [ 0x89, 0x00 ]
      - [ 0x8A, 0x07 ]
      - [ 0x8B, 0x02 ]
      - [ 0x8C, 0xDF ]
      - [ 0x8D, 0x00 ]
      - [ 0x8E, 0x00 ]
      - [ 0x8F, 0x00 ]
      - [ 0x90, 0x48 ]
      - [ 0x91, 0x00 ]
      - [ 0x92, 0x09 ]
      - [ 0x93, 0x02 ]
      - [ 0x94, 0xE1 ]
      - [ 0x95, 0x00 ]
      - [ 0x96, 0x00 ]
      - [ 0x97, 0x00 ]
      - [ 0x98, 0x48 ]
      - [ 0x99, 0x00 ]
      - [ 0x9A, 0x0B ]
      - [ 0x9B, 0x02 ]
      - [ 0x9C, 0xE3 ]
      - [ 0x9D, 0x00 ]
      - [ 0x9E, 0x00 ]
      - [ 0x9F, 0x00 ]
      - [ 0xA0, 0x48 ]
      - [ 0xA1, 0x00 ]
      - [ 0xA2, 0x04 ]
      - [ 0xA3, 0x02 ]
      - [ 0xA4, 0xDC ]
      - [ 0xA5, 0x00 ]
      - [ 0xA6, 0x00 ]
      - [ 0xA7, 0x00 ]
      - [ 0xA8, 0x48 ]
      - [ 0xA9, 0x00 ]
      - [ 0xAA, 0x06 ]
      - [ 0xAB, 0x02 ]
      - [ 0xAC, 0xDE ]
      - [ 0xAD, 0x00 ]
      - [ 0xAE, 0x00 ]
      - [ 0xAF, 0x00 ]
      - [ 0xB0, 0x48 ]
      - [ 0xB1, 0x00 ]
      - [ 0xB2, 0x08 ]
      - [ 0xB3, 0x02 ]
      - [ 0xB4, 0xE0 ]
      - [ 0xB5, 0x00 ]
      - [ 0xB6, 0x00 ]
      - [ 0xB7, 0x00 ]
      - [ 0xB8, 0x48 ]
      - [ 0xB9, 0x00 ]
      - [ 0xBA, 0x0A ]
      - [ 0xBB, 0x02 ]
      - [ 0xBC, 0xE2 ]
      - [ 0xBD, 0x00 ]
      - [ 0xBE, 0x00 ]
      - [ 0xBF, 0x00 ]
      - [ 0xC0, 0x12 ]
      - [ 0xC1, 0xAA ]
      - [ 0xC2, 0x65 ]
      - [ 0xC3, 0x74 ]
      - [ 0xC4, 0x47 ]
      - [ 0xC5, 0x56 ]
      - [ 0xC6, 0x00 ]
      - [ 0xC7, 0x88 ]
      - [ 0xC8, 0x99 ]
      - [ 0xC9, 0x33 ]
      - [ 0xD0, 0x21 ]
      - [ 0xD1, 0xAA ]
      - [ 0xD2, 0x65 ]
      - [ 0xD3, 0x74 ]
      - [ 0xD4, 0x47 ]
      - [ 0xD5, 0x56 ]
      - [ 0xD6, 0x00 ]
      - [ 0xD7, 0x88 ]
      - [ 0xD8, 0x99 ]
      - [ 0xD9, 0x33 ]
      - [ 0xF3, 0x01 ]
      - [ 0xF0, 0x00 ]
      - [ 0xF0, 0x01 ]
      - [ 0xF1, 0x01 ]
      - [ 0xA0, 0x0B ]
      - [ 0xA3, 0x2A ]
      - [ 0xA5, 0xC3 ]
      - delay 1ms
      - [ 0xA3, 0x2B ]
      - [ 0xA5, 0xC3 ]
      - delay 1ms
      - [ 0xA3, 0x2C ]
      - [ 0xA5, 0xC3 ]
      - delay 1ms
      - [ 0xA3, 0x2D ]
      - [ 0xA5, 0xC3 ]
      - delay 1ms
      - [ 0xA3, 0x2E ]
      - [ 0xA5, 0xC3 ]
      - delay 1ms
      - [ 0xA3, 0x2F ]
      - [ 0xA5, 0xC3 ]
      - delay 1ms
      - [ 0xA3, 0x30 ]
      - [ 0xA5, 0xC3 ]
      - delay 1ms
      - [ 0xA3, 0x31 ]
      - [ 0xA5, 0xC3 ]
      - delay 1ms
      - [ 0xA3, 0x32 ]
      - [ 0xA5, 0xC3 ]
      - delay 1ms
      - [ 0xA3, 0x33 ]
      - [ 0xA5, 0xC3 ]
      - delay 1ms
      - [ 0xA0, 0x09 ]
      - [ 0xF1, 0x10 ]
      - [ 0xF0, 0x00 ]
      - [ 0x2A, 0x00, 0x00, 0x01, 0x67 ]
      - [ 0x2B, 0x01, 0x68, 0x01, 0x68 ]
      - [ 0x4D, 0x00 ]
      - [ 0x4E, 0x00 ]
      - [ 0x4F, 0x00 ]
      - [ 0x4C, 0x01 ]
      - delay 10ms
      - [ 0x4C, 0x00 ]
      - [ 0x2A, 0x00, 0x00, 0x01, 0x67 ]
      - [ 0x2B, 0x00, 0x00, 0x01, 0x67 ]
      - [ 0x3A, 0x55 ]
      - [ 0x21, 0x00 ]
      - [ 0x11, 0x00 ]
      - delay 120ms
      - [ 0x29, 0x00 ]

font:
  - file: "fonts/Montserrat-Medium.ttf"  # Alternative große Schriftart (48px)
    id: montserrat_48
    size: 48

touchscreen:
  platform: cst816
  update_interval: 50ms
  skip_probe: true
  id: my_touchscreen
  i2c_id: i2c_touch
  address: 0x15  # Fixe I2C-Adresse aus dem Beispielcode
  interrupt_pin: GPIO4
  calibration:
    x_min: 7
    x_max: 360
    y_min: 9
    y_max: 350
  on_touch:
    then:
      - light.turn_on: display_backlight
      - lvgl.resume:
      - lvgl.widget.redraw:    


lvgl:
  displays:
    - main_display
  touchscreens:
    - touchscreen_id: my_touchscreen    
  on_idle:
    timeout: 20s
    then:
      - logger.log: "LVGL is idle"
      - lvgl.pause:
      - light.turn_off:
          id: display_backlight
          transition_length: 5s    
  widgets:
    - label:
        id: display_label
        align: CENTER
        text: "Getting ready..."
        text_font: montserrat_48  # Hier die Schriftgröße erhöhen!
        long_mode: WRAP  # Falls der Text länger ist, umbricht er automatisch
        width: 300  # Falls nötig, die Breite des Labels anpassen



#text_sensor:
#  - platform: template
#    name: "Display Text"
#    id: display_text
#    update_interval: never
#    on_value:
#      then:
#        - lambda: |-
#            if (id(display_label)) {
#              lv_label_set_text(id(display_label), x.c_str());
#              lv_refr_now(NULL);
#            }

text_sensor:
  - platform: template
    name: "Display Text"
    id: display_text
    update_interval: never
    on_value:
      then:
        - lambda: |-
            if (id(display_label)) {
              lv_label_set_text(id(display_label), id(display_text).state.c_str());
              lv_refr_now(NULL);  // Erzwingt ein sofortiges Redraw
            }


Here you can always find the latest version of my code:

I was able to get the font and compile the code. Working now, great work!! I was able to get touchscreen working as well, was working on debounce when I read your reply.

On another topic, I bought this display to make a gauge for my car and had no luck with arduino. Whould you possibly have working arduino code for this display? Just a sample to get something on the display.

Thanks again for your reply.

1 Like

There is sample code in the link on my first post, but I could not get it to compile in Arduino.

I’ve uploaded a new revision with working gyro:

I have a gauge in my latest revision!