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.