Skip to content

Fix SH1106 issue when there are other i2c devices on the line and tra…#431

Merged
marcelstoer merged 1 commit into
ThingPulse:masterfrom
zefir-o:master
May 28, 2026
Merged

Fix SH1106 issue when there are other i2c devices on the line and tra…#431
marcelstoer merged 1 commit into
ThingPulse:masterfrom
zefir-o:master

Conversation

@zefir-o

@zefir-o zefir-o commented May 18, 2026

Copy link
Copy Markdown
Contributor

…nsmition fails and it causes issues on the screen

@marcelstoer

Copy link
Copy Markdown
Member

The core idea is sound: the old code wrote to buffer_back before confirming the display received the data,
so a failed transmission silently suppressed retries on the next display() call. Deferring the sync until after confirmed success is the right fix.

Dead #ifdef nested inside its own #else branch (non-double-buffer path)

#else   // <-- OLEDDISPLAY_DOUBLE_BUFFER is NOT defined here                                       
  ...
  #ifdef OLEDDISPLAY_DOUBLE_BUFFER   // always false — dead code
    if (txOk) memcpy(buffer_back, buffer, displayBufferSize);
  #endif                                                                                                                                                                              
#endif

From what I understand, OLEDDISPLAY_DOUBLE_BUFFER can never be defined inside its own #else block, so the memcpy is unreachable. txOk tracking in the non-double-buffer path is therefore a complete no-op.
This block should be removed (and since buffer_back doesn't exist in that path, removing should be ok).

Other issues

  1. sendDataChunk writes byte-by-byte instead of using _wire->write(const uint8_t*, size_t). Most Wire
    implementations support bulk writes, which are more efficient:
// current                                                                                                                                                                            
for (uint8_t i = 0; i < length; i++) _wire->write(data[i]);
// suggested                                                                                                                                                                          
_wire->write(data, length);
  1. No retry in sendDataChunk: sendCommandChecked retries twice on failure, but sendDataChunk does not.
    Maybe worth a comment?
  2. pageOk short-circuit ordering is correct (both sendCommandChecked calls in the address phase are
    always executed because each is the left operand of &&). A brief comment would help.

Kudos

  • Replacing the hardcoded 8 and 128 in the non-double-buffer loop with displayHeight / 8 and displayWidth is
    a correctness improvement for non-128×64 geometries.
  • The updated comment ("Do not update buffer_back yet: if an I2C transfer fails, the same dirty region must be retried.") clearly captures the invariant.
  • yield() is preserved in all exit paths through the page loop — both the continue on command failure and the break on data chunk failure flow through the outer yield().

…nsmition fails and it causes issues on the screen
@zefir-o

zefir-o commented May 21, 2026

Copy link
Copy Markdown
Contributor Author

@marcelstoer thank you for reviewing the PR.
I updated it, take a look, please.

@marcelstoer

Copy link
Copy Markdown
Member

LGTM, thanks

@zefir-o

zefir-o commented May 22, 2026

Copy link
Copy Markdown
Contributor Author

@marcelstoer thank you for reviewing the PR.
I don't see the merge button. Should it be performed from your side?

@marcelstoer marcelstoer merged commit c69cd07 into ThingPulse:master May 28, 2026
6 checks passed
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.

2 participants