GxEPD2 - Detailed analysis of fast partial update speed of 1.54 Waveshare

Hi

I figured this one deserved a thread of its own, even though it is sprung out of another thread.

I am running a Seeed XIAO RP2040, neat little thing, with a 1.54" BW Waveshare display.

I am doing fast partial updates, but they are not as quick as I expected, or wanted, considering the spec says 0.3 seconds for a fast partial update. My goal is < 0.8 seconds. Which seems conservative enough considering the spec.

I made an analysis of the time-consumption of the various code parts, no surprise really, but a bit interesting anyway, IMO :slight_smile:
See the code with times in the code-sections below

The partial window in the first case is approx 200x45
In the second case, with two setcursor/print it is approx 200x120

Interestingly enough it takes way less than twice the time when the partial window is more than twice the size! Total time in first case is 898ms, when the partial window is increased to more than double, and there's an extra print in the loop, the extra time is still just 21ms. So whatever consumes the bulk of the time, apparently is not the data-transfer.

These tests were all run with a full frame buffer, i.e. the do-while loop was only run once.
(Which reminds me to remove it, as it is not needed in my case).

The surprising thing is the hibernation, it takes 142ms to set the display in hibernation.

So two questions arises, in my head at least

  1. How much of the time consumed is SPI-overhead?
  2. Considering the spec says 300 ms for a fast partial updated, why does it in reality take 894ms, looking at only the update part in the end. I mean, you can do fast partial updates of a full screen, which is commonly recommended, so that's what I would expect the spec info to relate to, 0.3 seconds for a full screen fast partial update.
  display.setPartialWindow(0, y1, 200, 200 - y1); // < 1ms
  display.firstPage(); // < 1ms
  do {   // The do-while takes 898ms with only one setcursor/print (second commented out)
    display.fillScreen(GxEPD_WHITE); // < 1ms
    display.setCursor(x1, y1 - yadv1); // < 1ms
    display.print(lastresbufptr); // 4ms
//    display.setCursor(x2, y2 - yadv2);
//    display.print(prevresbufptr);
  } while (display.nextPage()); // 894ms, this is where "all" the time is consumed
  display.hibernate(); //142ms, that's a lot to just set it in hibernate!
  display.setPartialWindow(0, y2, 200, 200 - y2);
//  display.setPartialWindow(0, y1, 200, 200 - y1); // < 1ms

  display.firstPage(); // < 1ms
  do {   // The do-while takes 898ms/922 with one/two setcursor/print, only 24ms difference
    display.fillScreen(GxEPD_WHITE); // < 1ms
    display.setCursor(x1, y1 - yadv1); // < 1ms
    display.print(lastresbufptr); // 4ms
    display.setCursor(x2, y2 - yadv2); // < 1ms
    display.print(prevresbufptr); // 3ms

  } while (display.nextPage()); // 894ms/915ms with one/two setcursor/print! This is where "all" the time is consumed
  display.hibernate(); //142ms, that's a lot to just set it in hibernate!

A simple look at the driver header file GxEPD2_150_BN.h confirms your times:

    static const uint16_t power_on_time = 100; // ms, e.g. 94000us
    static const uint16_t power_off_time = 150; // ms, e.g. 140000us
    static const uint16_t full_refresh_time = 4000; // ms, e.g. 3825000us
    static const uint16_t partial_refresh_time = 800; // ms, e.g. 736000us

Cool, so the info was there all the time! Thanks! :+1:

Is it possible to see why partial refresh takes 800ms? I'll have a look. Since it is supposed to be 300ms according to the spec.

GxEPD2_154.h that's why:

    static const uint16_t power_on_time = 80; // ms, e.g. 73508us
    static const uint16_t power_off_time = 80; // ms, e.g. 68982us
    static const uint16_t full_refresh_time = 1200; // ms, e.g. 1113273us
    static const uint16_t partial_refresh_time = 300; // ms, e.g. 290867us

Well, I bought the one stating 0.3 seconds. But obviously didn't get what I bought.
Also, I can't seem to find any 1.54" display on the Waveshare product pages that has 0.8 second refresh.

Anyhow I noticed using my setup and code with a button triggering an interrupt and then updating the display, that it's about 5-600 ms for the actual display update to happen, but then it's another 300-400 ms for the call to return.

So I need to make sure I get the right product when ordering more.

Thanks for the help!

Actually, the display that the GxEPD2_154.h you linked refers to, is noted as "no longer available" in the display selection .h-file.

//#define GxEPD2_DRIVER_CLASS GxEPD2_154     // GDEP015OC1  200x200, IL3829, (WFC0000CZ07), no longer available

I can't believe it, you still didn't get the point. S' Zwänzgi isch no nid abegheit.
The earlier version of the Waveshare 1.54" display board used the GDEP015OC1 panel.
Waveshare just didn't update this value in the specs for the new panel they now use.

There's no need to be rude. I more than got the point. Waveshare are selling different displays with different specs under the same product ID, and it's impossible to know exactly what you will get when you order this display under the waveshare name. I pointed out that the 0.3ms display in the file you linked is no longer available, so there is no use in trying to find it.

And also I notice that my supplier is marketing the old no longer available display in the product photo on their webpage, because it's got that printing on the flex cable, so if being picky I really didn't get what I ordered, I got a different version.

Apparently it's the Dalian Good Display company who are manufacturing these displays, and as I understand it, the display i have, DEPG0150BN/SSD1681, is also no longer available, other than to the extent suppliers still have it in stock. The 1.54" B/W display in production now seems to be the GDEY0154D67 which has 0.26 ms fast partial update time according to the specs.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.