Reimplement "Dynamic E-Ink" as a derived class #3316
Merged
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Aim
Enable developers to configure E-Ink displays' refresh behavior, to balance performance and display health.
How is it implemented
New
EInkDynamicDisplay
class derives from the existingEInkDisplay
class. It hooks the existingdisplay()
andforceDisplay()
calls. If the macroUSE_EINK_DYNAMICDISPLAY
is defined, EInkDynamicDisplay is instantiated in Screen.cpp, instead of the EInkDisplay classConfiguration
The behavior of the E-Ink display is configured by several macros which are added to a variant's
platformio.ini
file as build_flags.USE_EINK_DYNAMICDISPLAY
Defining this macro enables the "Dynamic E-Ink" behavior. If this macro is not defined, the existing
EInkDisplay
class behavior is used.EINK_LIMIT_FASTREFRESH
This macro specifies how many consecutive fast-refreshes are permitted, before a full-refresh is enforced.
EINK_LIMIT_RATE_BACKGROUND_SEC
This macro specifies the minimum interval, in seconds, between "BACKGROUND" updates. Currently, frames drawn by calling
display()
are flagged as BACKGROUND.EINK_LIMIT_RATE_RESPONSIVE_SEC
This macro specifies the minimum interval, in seconds, between "RESPONSIVE" updates. Currently, frames drawn by calling
forceDisplay()
are flagged as RESPONSIVE. (Unless specified otherwise withsetFrameFlag()
)(Optional)
EINK_LIMIT_GHOSTING_PX
This macro specifies, in pixel count, the amount of "image ghosting" to be tolerated, before a full-refresh is enforced.
This option has a modest additional overhead. If this macro is omitted, the "ghost pixel" tracking code will not run, and no additional resources will be used.
(Optional)
EINK_BACKGROUND_USES_FAST
By default, BACKGROUND updates are drawn with a full-refresh. If this macro is defined, the display will use fast-refresh for even these BACKGROUND updates, until another limit eventually forces a full-refresh (
EINK_LIMIT_FASTREFRESH
,EINK_LIMIT_GHOSTING_PX
)Implementing for additional displays
The display should first be configured to use the existing
EInkDisplay
class. So long as GxEPD2 supports "fast partial refresh" for the model, it should then be as simple as defining the macros in the variant's platformio.ini or variant.h file.Performance
Most calls, the code has negligible impact (measured<20µs). When a new frame is eventually due, the impact of all checks running (including ghost pixel tracking) is <15ms. As the physical operation of updating an E-Ink display can take several seconds, a net gain in performance is expected.
In two different scenarios, performance was compared between the existing
EInkDisplay
class, and the newEInkDynamicDisplay
class.Test device was Heltec Wireless Paper V1.1
No other nodes present
What next
Real-world Testing
The values set in this PR for Heltec Wireless Paper V1.0 are only a suggested start point. They haven't been tested in the real world. Please do adjust the configuration for this display, and any future displays, if you feel that the settings could be improved
Heltec Wireless Paper V1.1
A rewrite of the GxEPD2 code for LCMEN2R13EFC1 is ready to push, which will enable fast refresh, and dynamic E-Ink config. There is also a minor tweak to the V1.0 GxEPD2 code.
Mark specific frames as
COSMETIC
orDEMAND_FAST
inScreen.cpp
This should be along shortly. A few non-invasive lines of code will ensure that some key splash screens are explicitly marked for either full-refresh or fast-refresh.
Expose Dynamic-EInk settings to end user?
Unsure if this would be desirable, or exactly what it would involve, but I see no reason theoretically that the macros configuring the E-Ink behavior couldn't be exposed as runtime settings to the user.
Simplified flow diagram
For future reference, code maintenance.