ThingPulse / esp8266-oled-ssd1306

Driver for the SSD1306 and SH1106 based 128x64, 128x32, 64x48 pixel OLED display running on ESP8266/ESP32
https://thingpulse.com
Other
1.99k stars 637 forks source link

Arduino+ESP32 - Display and UI not work in multitask situations #299

Closed eLEcTRiCZiTy closed 3 years ago

eLEcTRiCZiTy commented 4 years ago

Hi,

I tried to use your libraries to display WiFi information and allow users to set up simple settings with your UI. I try to summarize my situation in some facts. Because I do not want to create a project as an example, it will be time-consuming.

I am using SH1106Wire and OLEDDisplayUi. Because of ArduinoOTA and other functions, I have to multitask. When I use only SH1106Wire to display text in the Arduino setup() function, then all works OK. In the Arduino setup, the SH1106Wire shows WiFi connection progress and IP address. Then I set up and initialize OLEDDisplayUi and "update" function have its Task that starts after UI init. After the Arduino setup, the display is utilized only by OLEDDisplayUi and shows garbage (chunks of texts and info are on a random part of the display or its part) or is empty (lower I2C speeds).

I tried to change I2C speed and move everything in the Arduino loop with no effect. My simple project is task-complex because of ArduinoOTA and Button Interface Task, but Display and GUI are programmed from examples and, at this time, show only information from global variables. No task controls it besides the Arduino loop().

I think Your library is task-unsafe or nonrobust and thus unusable for fast prototyping. Prototyping at this moment consumed more time than when I program everything from zero :|

eLEcTRiCZiTy commented 4 years ago

My boss allowed me to create an example program, but it needs ESP32, existing WiFi network, buttons, and a little reconfiguration.

Pin numbers are in defines, enter your WiFi credentials at line 42. example.zip

Ferrograph commented 4 years ago

Did you ever get a resolution on this? This library looks very good but I found that if I updated the display from a task instead of the main loop the display got corrupted. I tried I2C_TWO and different speeds with no change.

Shame . Its a good library.

eLEcTRiCZiTy commented 4 years ago

I did not get any resolution on this. I wrote a simple library myself but it is proprietary. Sorry.

Ferrograph commented 4 years ago

Ok thank you for replying.

thijstriemstra commented 4 years ago

I re-init the screen at every draw (which only happens once every 10 mins) in a project that uses threads. Otherwise the screen wouldn't update at all or become corrupted.

Ferrograph commented 3 years ago

Thanks for the info. Do you think its possible to adjust the library to be thread safe?

ishdemon commented 3 years ago

same here. updated brightness from core 0, now display is glitched, unresponsive.

ishdemon commented 3 years ago

@thijstriemstra Does re-init at every update causes any side effects with memory?

thijstriemstra commented 3 years ago

@ishdemon what threading lib are you using? I recently used https://github.com/wizard97/ArduinoProcessScheduler in a project and glitches were gone. I only saw the issue with https://github.com/ivanseidel/ArduinoThread (and so I won't be using that again).

HankLloydRight commented 3 years ago

I re-init the screen at every draw (which only happens once every 10 mins) in a project that uses threads. Otherwise the screen wouldn't update at all or become corrupted.

@thijstriemstra Does re-init at every update causes any side effects with memory?

I found this thread because I am having the same problem with a corrupted display when using CORE0 on ESP32 to update the display. I tried your suggestion of re-init on each update, and it works!

But in addition, I set up a volatile boolean to track if the OLED had been initialized in the CORE0 loop, and only initialize it the first time, otherwise, just send the data normally. This way the display doesn't blink on/off on each update.

// set up global variable
volatile boolean OLEDinit=false; 
//  add to the display update code called from CORE0:
if (!OLEDinit) {
    display.init();
    display.flipScreenVertically();
    OLEDinit=true;
}
// insert display update code here

And it works like a charm! Thank you.

marcelstoer commented 3 years ago

@HankLloydRight thanks for the feedback. We appreciated it. Do you happen to have a small self-contained example we could ship with the library (in https://github.com/ThingPulse/esp8266-oled-ssd1306/tree/master/examples)? Or could you maybe be motivated to describe the use case and relevant snippets in a paragraph for the README here?

HankLloydRight commented 3 years ago

@HankLloydRight thanks for the feedback. We appreciated it. Do you happen to have a small self-contained example we could ship with the library (in https://github.com/ThingPulse/esp8266-oled-ssd1306/tree/master/examples)? Or could you maybe be motivated to describe the use case and relevant snippets in a paragraph for the README here?

Yes, I can definitely put together an example based on one of the other simple examples -- once I get this project over a big hurdle.

NorthernMan54 commented 1 year ago

I had the same issue in my code base, and moved the display task to core1 to solve the issue. I was already using queues to manage the messaging between my various tasks, so the move was easy.

To identify the issue, I added this to my code prior to writing to the display and saw it bouncing between cores.

Serial.print("write: Executing on core "); Serial.println(xPortGetCoreID());