GxEPD2 - Partial update with deep sleep

Hi all!

To my understanding partial updates in GxEPD2 are only allowed if the screen is at least once fully refreshed/updated. This feature prevents to use effectively EPDs with MCU that are able to deep-sleep: once they wake-up, we lose the frame buffer content and need to perform a full update.

Taking ESP32 as an example, the frame buffer would be to big to be store to RTC_DATA_ATTR but a different approach can be taken:
a) store all the displayed variable to RTC_DATA_ATTR retained variable before going to deep-sleep
b) once woken up redraw the display into the GxEPD2 frame buffer from the retained variables. This recreate the state before the deep sleep: It draws the same bitmaps to the GxEPD2 frame buffer.
c) Now a function should be added to GxEPD2, to allow it to consider the recreated frame buffer as already synced with the EPD. The e-paper doesn't need updating, it shows the same content already from the previous update.
d) Now it's possible to use the partial update functions to only update the portion of the screen that has changed (like a time value, or a temperature and so on), avoiding a complete refresh and hence display flickering.

Similar feature has been solved and integrated into Inkplate Arduino Library, would it be possible to add this also for GxEPD2? I think that it would be a great addition to develop very high quality open source products with EPDs! Thank you!

Sources for Inkplate modifications:

@raggio, Hi, welcome to the forum!

Please read How to get the best out of this forum if you haven't done yet.

For b/w e-paper displays that support differential refresh GxEPD2 makes sure that the content on the screen and the current and previous buffers of the controller are equal after the update has been completed, be it partial or full. This allows next partial wherever it may happen on the screen without the need to write old data. Before the first update this is not true, screen and buffers may differ, therefore the first update (initial update) needs to be a full update.
With your deep sleep you only need to persistently store a flag to remember if the initial update has ever been done, as long as you keep supply to the panel.

See also the comments in GxEPD2_BW.h for the init() method with additional parameters:

    // init method with additional parameters:
    // initial false for re-init after processor deep sleep wake up, if display power supply was kept
    // this can be used to avoid the repeated initial full refresh on displays with fast partial update
    // NOTE: garbage will result on fast partial update displays, if initial full update is omitted after power loss
    // reset_duration = 20 is default; a value of 2 may help with "clever" reset circuit of newer boards from Waveshare 
    // pulldown_rst_mode true for alternate RST handling to avoid feeding 5V through RST pin
    void init(uint32_t serial_diag_bitrate, bool initial, uint16_t reset_duration = 20, bool pulldown_rst_mode = false)

Hope this helps you.


Thank you so much ZinggJM for the prompt reply and all the wonderful work you have done providing the community with your Libraries.
I will definitively read the community rules, I hope to not have done anything bad with my first post!

Your answer is sharp and straight to the point, I was immediately able to use partial refresh after deep-sleep and update my status bar... as you suggested, the trick was easy:

  if( bootCount == 0 ){
    display.init(0, true);
  } else {
    display.init(0, false);

bootCount is a RTC_DATA_ATTR int variable, that increments at every deep-sleep cycle, starting from zero the first boot. That was it!

Thank you again!