I2C and SPI display corruption / flipped display

I am developing a product based on Boron LTE that uses an OLED display. I have tried two different displays (SSD1306 OLED 128x64 using I2C, and SH1106 OLED 128x64 using SPI). I’m using the SSD1306 and SH1106 libraries from Adafruit in my tests. I have not yet been able to get u8g2 to work without crashing, so I haven’t tested that yet.

Both displays show the same problem. After a while (minutes, or maybe hours) the display flips vertically, thus showing an upside down image. From time to time after that flip it also corrrupts occasionally, with graphics skewed left to right, or completely garbled. It recovers from that corruption on the next refresh, but still the display is upside down. It only goes back to normal orientation after a reset.

Currently I’m using the SH1106 SPI 128x64 display for testing. Has anyone else seen this problem? I haven’t been able to find it in my searches of this board.

EDIT: I had 4.7K pullup resistors on the I2C signal and clock lines. I have no pullups on SPI.
EDIT 2: Display is flipped vertically, and the horizontal skew does not appear to correct itself until reset.

@picsil, how are you writing to the display - callback (timer, Particle.function, etc), another thread? Can you share your code?

The display is updated once per second in a Timer. Your question got me wondering though if that was causing the corruption, even though I was trying to be careful to disable the timer during critical operations. I removed the timer and moved the update into my main loop. I’ll watch this for a while and see what happens. I’ll report back after it runs for a while.

1 Like

@picsil, timers need to be kept short and ideally simple. Your approach is good and by writing non-blocking loop() code should be good. One thing I have done is to use a Timer to build the display buffer, set a flag and have loop() display the buffer.

1 Like

Thanks @peekay123 for putting me on the right track. It’s been running stable now for about 4 hours with no corruption. Moving the display updates out of a Timer and into loop() seems to have solved the problem.

1 Like