Skip to content

Add a dual-polarity monochrome mode for 1bpp (8ppB) buffers#480

Open
zvirja wants to merge 1 commit into
vroland:mainfrom
zvirja:monochrome-dual-polarity
Open

Add a dual-polarity monochrome mode for 1bpp (8ppB) buffers#480
zvirja wants to merge 1 commit into
vroland:mainfrom
zvirja:monochrome-dual-polarity

Conversation

@zvirja

@zvirja zvirja commented May 25, 2026

Copy link
Copy Markdown

I am trying to re-implement existing LilyGo T5 4.7 monochrome driver to use the latest version of this library and I faced an issue that we don't have an update mode for monochrome screen which drives both black and white pixels at the same time. We only have mode to either render from white or from black (so we drive the opposite).

Unfortunately, on my real LilyGo that produces quite low contrast and ghosting. The only reliable solution is to render many times (like 20 cycles) where I drive all pixels all the time (both white and black).

With help of AI I generated and verified that a new lookup table works. Now if we don't specify that previous state was black/white, then we drive all the pixels. It allows to have clean and nice implementation in my driver.

Let me know if you are okay with this. I don't see any issues and to it's a reasonable behavior.

The existing 8ppB lookups (build_8ppB_lut_256b_from_white / _from_black)
drive only a single polarity per frame: one color is pushed and the other
is left undriven (0b00). That works when the previous screen color is known
(PREVIOUSLY_WHITE / PREVIOUSLY_BLACK), but it cannot reproduce the classic
"push the 1-bit frame N times" monochrome refresh, where every pixel is
driven every frame (black -> 0b01 darken, white -> 0b10 lighten). That
two-way push is what builds strong contrast and clears ghosting on both
colors at once.

Add a third 8ppB lookup, lut_8ppB_dual, that drives both polarities, and
select it as the default for MODE_PACKING_8PPB when neither PREVIOUSLY_WHITE
nor PREVIOUSLY_BLACK is set. That combination previously returned no lookup
function (EPD_DRAW_LOOKUP_NOT_IMPLEMENTED); existing callers all pass a
PREVIOUSLY_* hint, so nothing regresses.

Pair with MODE_EPDIY_MONOCHROME | MODE_PACKING_8PPB to push the same 1bpp
frame repeatedly for a high-contrast monochrome refresh.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@zvirja

zvirja commented Jun 6, 2026

Copy link
Copy Markdown
Author

@martinberlin I am not sure if you are the right one, but I saw you active around. Could you please take a look at this one and confirm if there are any chances we could have this one merged? It's a quite trivial change and it unblock me to have a better driver for lilygo.

Thanks!

@martinberlin

martinberlin commented Jun 6, 2026

Copy link
Copy Markdown
Collaborator

This "as is" won't be merged. It lacks context, is not clear if this update affects only this Lilygo or all eink driving for all models (Which I think it does).
I don't mind if it's AI generated or not but should be human tested with different boards and displays. Assigning this to @vroland

@martinberlin martinberlin requested a review from vroland June 6, 2026 06:41
@zvirja

zvirja commented Jun 6, 2026

Copy link
Copy Markdown
Author

@martinberlin I would be happy to provide context, I tried my best in the description.

The issue is that for LilyGo the existing Wave function when we drive only black or white is not working great - it leads to low contrast and ghosting.

Currently for 8PPB we require to either come from totally black or totally white screen. Then you drive either only white or only black. In this PR I am filling the gap by adding mode where we drive both black and white at the same time. I would say that this mode must have been there from the beginning and I don't see any good reason for not having it.

I tested in intensively on the LilyGo 4.7 and could verify that it's the only approach that gives a good contrast.

I would be more than happy to provide more info - just clarify what you need.

P.S. The change is quite trivial, so we could just disregard the AI part entirely.

@vroland

vroland commented Jun 7, 2026

Copy link
Copy Markdown
Owner

I'm not opposed to adding it, but we should document the risk of burn-in. If we drive the pixels hard like this all the time, it may lead to pixels getting "stuck" over time. So the display might degrade much quicker with this approach. I think we can add this, but maybe log a warning when this mode is selected that you use it that it may degrade your display faster and you should use it at your own risk?

@martinberlin

Copy link
Copy Markdown
Collaborator

I think we can add this, but maybe log a warning when this mode is selected that you use it that it may degrade your display faster and you should use it at your own risk?

Fully agree with this. It would be cool also to add an 1BPP example since currently all epdiy examples are done for 16 grays (4 bits per pixel)
Then at least it will be also better documented and with an example @zvirja
Could be just a very simple example that draws a

"Hello this is a 1 BPP monochrome example" and any random things you would like to add.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants