Waveshare epaper display: White screen without content until first refresh/update

Hey everyone,
I’m playing around with the 2.9inch waveshare epaper display at the moment. As the partial refresh is still broken/buggy in the esphome implementation (ESPHome + Waveshare 2.9inv2 e-ink display + partial refresh = flicker/artifacts? for details), I want to settle on a “update once every 30 minutes” approach to not have the “all white, all black, back to the actual image” flickering all the time. As I’m at the moment mostly showing weather info, a smaller update frequency is fine. (And when I later add notifications about sensor changes, a bit of flickering actually adds to the notification awareness :slight_smile: )

My problem: when I boot up the esp, the display quickly shows the right image/text, but does another black/white refresh and then stays white until the next regular (non-bootup) refresh. With a refresh of 30 minutes or longer, this would mean I would have to wait that long until the display actually shows something for the first time.

Potential workaround: somehow trigger a “manual” refresh 10 seconds after booting is done completely. How would I do that?
Alternatively: is the behaviour that I have actually an issue with my settings, and the display should show the correct content directly after booting and not just after the first regular refresh?

This is the display section of my yaml:

esphome:
  name: epaper

esp32:
  board: esp32doit-devkit-v1
  framework:
    type: arduino

...

spi:
  clk_pin: 19
  mosi_pin: 18

display:
  - platform: waveshare_epaper
    cs_pin: 21
    dc_pin: 3
    busy_pin: 22
    reset_pin: 1
    model: 2.90inv2
    rotation: 90°
    update_interval: 30min
    full_update_every: 1
    reset_duration: 2ms
    id: eink
    lambda: |-
      it.image(0, 92, id(otter_icon));
      it.printf(150, 0, id(font1), "Hey, it is");
      if (id(outside_temperature).has_state()) {
      it.printf(190, 20, id(font2), "%.1f", id(outside_temperature).state);
      }
      it.printf(150, 50, id(font1), "degrees outside");
      it.printf(150, 70, id(font1), "and it is");
      if (id(outside_weather).has_state()) {
      it.printf(150, 90, id(font2), "%s", id(outside_weather).state.c_str());
      }

Greatful for every hint in the right direction, thanks in advance!

I have the same problem. I’m using battery and doing the deep sleep after the screen is done to maximise the battery. But first initial refresh after boot uses energy for nothing. Could I disable it? And maybe do the refresh manually after I’m sure all the data is loaded and ready to print on screen

Okay, after playing around a bit more, for now I’ve settled on solving 2 usecases with the same “method”:

I wanted to introduce multiple display pages anyway, to show notifications separate from the weather info. So I defined a dropdown helper within HA (page1, page2 and page3) which I look up from within the esphome code. So now by switching pages inside HA I can on the one side show different information, but can also manually trigger a refresh of the display.

text_sensor:
  - platform: homeassistant
    id: outside_weather
    entity_id: weather.home
    internal: true
  - platform: homeassistant
    id: pages
    entity_id: input_select.epaper_page
    on_value:
      then:
        - display.page.show: !lambda |-
            if (id(pages).state == "page1") {
              return page1;
            }
            if (id(pages).state == "page2") {
              return page2;
            }
            if (id(pages).state == "page3") {
              return page3;
            }
        - component.update: eink

spi:
  clk_pin: 19
  mosi_pin: 18

display:
  - platform: waveshare_epaper
    cs_pin: 21
    dc_pin: 3
    busy_pin: 22
    reset_pin: 1
    model: 2.90inv2
    rotation: 90°
    update_interval: 1800s
    full_update_every: 1
    #reset_duration: 2ms
    id: eink
    
    pages:
      - id: page1
        lambda: |-
          it.image(0, 92, id(otter_icon));
          it.printf(70, 0, id(font1), "Hey Irina, it is");
          if (id(outside_temperature).has_state()) {
          it.printf(70, 20, id(font2), "%.1f", id(outside_temperature).state);
          }
          it.printf(70, 50, id(font1), "degrees outside");
          it.printf(70, 70, id(font1), "and it is");
          if (id(outside_weather).has_state()) {
          it.printf(70, 90, id(font2), "%s", id(outside_weather).state.c_str());
          }
      - id: page2
        lambda: |-
          it.printf(0, 0, id(font1), "page2");
      - id: page3
        lambda: |-
          it.printf(0, 0, id(font1), "page3");

The “- component.update: eink” after the page switch within the sensor made the difference.

1 Like