Changed epaper logic to better enable partial refresh during operation#876
Closed
Changed epaper logic to better enable partial refresh during operation#876
Conversation
Collaborator
|
I already have partial refresh working at #874 I left a comment/question for you #874 (comment) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
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.
E-ink Display: Partial Refresh and Visual State Changes
Summary
Reworks the e-ink display controller to use proper partial refresh for runtime updates and adds visual state indication (on/off) through inverted color schemes. Also fixes a bug in the outdated Waveshare driver that increased ghosting during partial refresh.
Problem
Our implementation called
epd.Clear()+display_Partial()on every update, which caused:Changes
1. Waveshare Driver Fix (
e-paper/lib/waveshare_epd/epd2in9_V2.py)Root cause of ghosting: The SSD1680 display controller uses two RAM buffers to compute partial refresh diffs:
0x24— the "new" image (what we want to display)0x26— the "old" image (what's currently on screen)The stock Waveshare
display_Partial()only wrote to0x24, leaving0x26stuck at whateverdisplay_Base()last set. Every partial refresh diffed against the original baseline, not the current screen state, causing accumulated ghosting and illegible text.Fix:
display_Base()now saves a copy of the image buffer (_prev_image)display_Partial()explicitly writes_prev_imageto0x26and the new image to0x24before triggering the refresh, then updates_prev_imageafterward2. Display Layout Redesign (
main.py)"On" state (startup + runtime):
"Off" state (shutdown):
display_Base) so the large solid-black regions render crisply, and well.The visual inversion makes it immediately obvious whether the device is on or off.
3. Refresh Strategy (
main.py)init_display()Clear+display_Base)render()display_Partial)clear()Clear+display_Base)render_off()display_Base)4. Bar Height
Increased
BAR_HEIGHTfrom 26px to 30px to prevent text descenders from clipping outside the bar region, as there were some letters overlapping.5. New Helper Functions
update_url(url)— partial refresh of bottom bar onlyupdate_hostname(hostname)— partial refresh of top bar onlyrender(url, hostname)— partial refresh of both barsrender_off(hostname)— full refresh with inverted color schemeNode-Red Integration (TODO)
To show "Acquiring" on the e-ink display when acquisition starts, or "Segmenting" ect.. we just add the following to the Node-Red dashboard flow:
When acquisition starts:
Wire a function node from the "start acquisition" path that outputs:
Connect this to an MQTT-out node (broker:
localhost:1883, no topic — usesmsg.topic).When acquisition stops:
Wire a function node from the "stop acquisition" path that outputs:
Connect this to the same MQTT-out node.
Flow wiring
The acquisition page already has a switch node that routes
acq_statusvalues of"on"and"off". Add the display function nodes as additional outputs from this switch, or wire them in parallel with the existing "start acquisition" and "stop acquisition" function nodes.This uses the existing
configureMQTT action — no Python changes needed. The display controller will do a partial refresh, silently updating the bottom bar text without flashing.Testing
Files Changed
controller/display/main.py— display layout, refresh strategy, on/off statescontroller/display/e-paper/lib/waveshare_epd/epd2in9_V2.py— dual-buffer partial refresh fixnode-red/projects/dashboard/flows.json— (pending) acquisition status display updates