Skip to content

Investigate unexpected E-Ink display updates on days with no scheduled changes #57

Description

@RomanAlexandroff

Edit: May have been resolved by the pull request #60


The device appears to be performing E-Ink display updates at times when, according to the application's display-state tracking logic, no change should have occurred.

This may be an application-level bug, a side effect of the new GDEY075Z08 display driver, an interaction with deep sleep/wake-up, or another unexpected execution path.

The issue needs to be investigated before assuming that the new display driver is responsible.


Observed behaviour

On 13.08.2026, the device sent the following GxEPD2 diagnostic measurements to Telegram:

[13.08.2026 6:00] 42 Prague Smart Sign: _Update_Part : 16768001 us
[13.08.2026 6:00] 42 Prague Smart Sign: _PowerOff : 41000 us
[13.08.2026 6:00] 42 Prague Smart Sign: _PowerOn : 127000 us
[13.08.2026 6:00] 42 Prague Smart Sign: _Update_Part : 16768000 us
[13.08.2026 6:00] 42 Prague Smart Sign: _PowerOff : 39882 us

[13.08.2026 9:18] 42 Prague Smart Sign: _PowerOff : 40001 us
[13.08.2026 9:18] 42 Prague Smart Sign: _PowerOn : 127000 us
[13.08.2026 9:19] 42 Prague Smart Sign: _Update_Part : 16772000 us
[13.08.2026 9:19] 42 Prague Smart Sign: _PowerOff : 41000 us

[13.08.2026 12:00] 42 Prague Smart Sign: _Update_Part : 16775002 us
[13.08.2026 12:00] 42 Prague Smart Sign: _PowerOff : 40997 us

[13.08.2026 15:02] 42 Prague Smart Sign: _Update_Full : 16775002 us
[13.08.2026 15:02] 42 Prague Smart Sign: _PowerOff : 40001 us
[13.08.2026 15:02] 42 Prague Smart Sign: _PowerOn : 127001 us
[13.08.2026 15:03] 42 Prague Smart Sign: _Update_Part : 16779075 us
[13.08.2026 15:03] 42 Prague Smart Sign: _PowerOff : 41001 us

The important observation is that _Update_* operations appear at approximately:

06:00
09:18
12:00
15:02

The exact times are not perfectly periodic, but the updates occur repeatedly throughout the day.


Why this is unexpected

There were no exams on 13.08.2026.

On days without exams, the contents of the display are not expected to change after the initial daily update.

The application also contains logic specifically intended to track what is currently displayed and avoid redrawing the same content unnecessarily.

Therefore, based on the intended application behaviour, the expected pattern should have been approximately:

06:00  -> display update
09:00  -> no display update
12:00  -> no display update
15:00  -> no display update
...

Instead, GxEPD2 reports display update operations at all of these times.


Further observations after the GDEY075Z08 driver update

The new GxEPD2_750c_GDEY075Z08 driver has now been confirmed to render the display contents correctly. The display image is produced as expected, so the driver migration itself does not appear to have introduced any graphical rendering problems.

However, additional field observations revealed that the display is sometimes refreshed even when there are no expected changes to its contents.

The device wakes up on a fixed schedule:

06:00
09:00
12:00
15:00
18:00
21:00

These are wake-up times, not display-update times. The application may start using the display some time after waking up, and the delay can vary between wake-up cycles, typically by no more than approximately 30 minutes.
Therefore, the timestamps of the GxEPD2 diagnostic messages should be interpreted in relation to the corresponding wake-up cycle rather than as an independent display-update schedule.

Observed unexpected updates

Several days of field observations showed display updates during wake-up cycles where no display change was expected.
Examples:

14.08.2026
06:02 -> _Update_Full / _Update_Part
15:01 -> _Update_Full / _Update_Part
21:01 -> _Update_Full / _Update_Part

15.08.2026
14:59 -> _Update_Full / _Update_Part

16.08.2026
09:02 -> _Update_Full / _Update_Part
21:01 -> _Update_Full / _Update_Part

17.08.2026
09:02 -> _Update_Full / _Update_Part

There does not appear to be a simple or consistent pattern describing which wake-up cycles result in a display update.
The application already contains logic intended to track what is currently displayed and avoid redrawing identical contents. On days without exams, the displayed contents are generally expected to remain unchanged after the initial update.
Therefore, these additional refreshes are currently considered unexpected.

Current conclusion

The exact cause has not been determined.
Possible causes previously considered include:

  • display-state tracking incorrectly detecting a change;
  • another code path invoking the display update independently;
  • display-state information being lost or reinitialised between deep-sleep cycles;
  • some value used by the display-state comparison changing unexpectedly;
  • interaction between the display-update logic and the device wake-up sequence.

However, further investigation is being postponed.

The display drawing logic is currently due for a substantial refactoring. It is considered likely that this refactoring will change the relevant execution flow and may resolve this behaviour as a side effect.
For this reason, no further investigation will be performed at this stage unless the behaviour persists after the display-drawing refactoring.
The unexpected refreshes should nevertheless remain documented here so that the behaviour is not forgotten and can be verified after the refactoring.


Important distinction

The presence of:

_Update_Part

or:

_Update_Full

in the Telegram diagnostics proves that the corresponding GxEPD2 display operation was executed.

It does not yet prove why the application decided to execute that operation.

The immediate goal of this investigation is therefore to determine:

What execution path causes the display-update code to be called at 09:18, 12:00 and 15:02 when no display change is expected?


Possible explanations

Several possible causes should be investigated.

1. Display-state tracking bug

The application may incorrectly determine that the display contents have changed.

For example:

  • The stored previous state may be incorrect.
  • A comparison may always evaluate as "changed".
  • One of the values participating in the comparison may change unexpectedly.
  • The "currently displayed" state may not be updated correctly after a successful refresh.
  • The state may be compared before being initialized correctly.

2. Display-update function has another caller

The display may be updated from somewhere other than the normal "display contents changed" path.

Every caller of the relevant display-drawing function should therefore be identified.

The investigation should determine whether there are multiple independent execution paths capable of initiating a display update.


3. Deep-sleep / wake-up interaction

The device uses ESP32-C3 deep sleep.

If the display-state tracking variables are ordinary RAM variables, their values may not survive deep sleep in the same way as persistent state.

After waking up, the firmware may therefore believe that:

  • the display has never been initialized;
  • the displayed state is unknown;
  • the current state differs from the previously displayed state;
  • or a display refresh is otherwise required.

This possibility needs to be checked against the actual lifetime and initialization of the display-state tracking variables.


4. Firmware startup behaviour

The device may intentionally or unintentionally perform a display update during every boot/wake cycle.

This could happen if the display-update logic runs during initialization before the application has reconstructed the previous display state.

The complete execution path after waking from deep sleep should therefore be examined.


5. Time/date/status values changing

A value used to construct or compare the display contents may change even when there are no exams.

For example:

  • current time;
  • current date;
  • schedule information;
  • network status;
  • downloaded data;
  • temporary/default values;
  • initialization values.

If such a value participates in the display-state comparison, it could cause a redraw even though the visible display is logically unchanged.


6. Interaction with the new GxEPD2 driver

The correct driver for the actual display/controller combination was recently introduced:

Display:   GDEY075Z08
Controller: UC8179
GxEPD2 driver: GxEPD2_750c_GDEY075Z08

The previous project version incorrectly used:

GxEPD2_750c_Z08

which is intended for a different display/controller combination.

The new driver is therefore a significant recent change.

However, it is currently unknown whether this issue existed before the driver migration.

The driver should therefore remain a possible cause, but should not be assumed to be the cause without evidence.


Additional observation: Telegram diagnostic timing

The GxEPD2 diagnostic messages are currently generated from inside _waitWhileBusy().

Consequently, the Telegram log does not necessarily show the complete sequence of application-level display operations.

For example, the 09:18 sequence begins with:

_PowerOff
_PowerOn
_Update_Part
_PowerOff

rather than with _Update_Part.

This means that the Telegram log may represent only part of the complete display-operation sequence.

The investigation should therefore not rely solely on the first _Update_* message appearing in the log to determine when the display-update process started.


Current display timing baseline

With the new GDEY075Z08 / UC8179 driver and the currently working display-buffer configuration, typical measured timings are approximately:

_Update_Full : 16.765–16.775 s
_Update_Part : 16.768–16.790 s
_PowerOn     : ~0.127 s
_PowerOff    : ~0.040 s

These timings are currently considered a separate display-driver investigation and should not be modified while investigating this issue unless necessary.

The display driver should therefore be treated as a stable baseline for this investigation.


Investigation plan

Application-level investigation

  • Identify the function that decides whether the display needs to be updated.
  • Identify all variables used to determine whether the displayed state has changed.
  • Identify where the "currently displayed" state is stored.
  • Identify where that state is updated after a successful display refresh.
  • Identify every caller of the display drawing/update function.
  • Determine whether any caller can bypass the normal display-state comparison.
  • Trace the complete execution path after waking from deep sleep.
  • Determine whether the display-state variables survive deep sleep.
  • Check whether any time/date/schedule/network values used by the comparison change between wake-ups.
  • Add temporary diagnostic logging explaining why a display update was requested.

Recommended diagnostic information

For every display update request, temporarily log information similar to:

[DISPLAY] Update requested
Reason: <reason>
Previous state: <state>
Current state: <state>

If possible, the diagnostic output should also identify which code path requested the update.

The most useful result would be to distinguish between:

Display update requested because state changed

and:

Display update requested even though state is unchanged

This should make it possible to determine whether the problem lies in the state-tracking logic or somewhere earlier/later in the execution flow.


Expected result

On a day without exams or any other legitimate display changes, the firmware should:

  1. Perform the necessary display update when the day's initial state is established.
  2. Preserve the knowledge of what is currently displayed.
  3. Avoid calling the display update functions when the desired display contents are identical to the contents already shown.
  4. Continue waking up and performing all other necessary application tasks without unnecessarily refreshing the E-Ink display.

Why this matters

The GDEY075Z08 display requires approximately 16.8 seconds for each refresh.

Therefore, an unnecessary display refresh is not a trivial operation.

Every unnecessary refresh:

  • keeps the ESP32 active for significantly longer;
  • consumes additional energy;
  • consumes display/controller power;
  • increases the total execution time of the device cycle;
  • unnecessarily stresses the E-Ink display through additional refreshes;
  • makes future power-saving optimizations less effective.

This is particularly important because the project is also being optimized for low power consumption using Wi-Fi Modem Sleep and, in the future, variable CPU frequency and potentially sleep states while waiting for the E-Ink controller.


Status

Investigation required.

The unexpected display updates have been observed in the field, but the exact cause has not yet been established.

The first priority is to determine why the application requests a display update at 09:18, 12:00 and 15:02 on a day with no exams and no expected display changes.

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions