I'm currently working on a small project where I use an ESP32 as a webserver and have a SSD1306 OLED display attached to it using the Adafruit SSD1306 library (via platform io).
The screen is supposed to show some information, like the device's name, the IP and a little icon indicating if a client has connected to the websocket (hence the webserver)
the initial screen looks fine, it shows the information as expected. But when I connect to the ESP websocket and the "onWsEvent" is fired the screen needs to be updated. It does update but it looks just quite a bit off:
Here's the onWsEvent function (i deleted everything irrelevant in there):
Code: Select all
void onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data,
size_t len) {
switch (type) {
case WS_EVT_CONNECT:
Serial.printf("WebSocket client #%u connected from %s\n", client->id(),
client->remoteIP().toString().c_str());
Serial.printf("Core ID: %i\n", xPortGetCoreID());
Serial.printf("Task Name: %s\n", pcTaskGetTaskName(NULL));
wsConnectedCallback();
break;
case WS_EVT_DISCONNECT:
Serial.printf("WebSocket client #%u disconnected\n", client->id());
wsDisconnectedCallback();
break;
}
}
1st - a callback method is called that continues in my main.cpp and changes the display information
2nd - I added an output that shows the task name
And the output shows what I expected: All correct changes are made within the loopTask, when it is changed from the async_tcp task, it shows the problems as seen in the image.
I also have the same output in my method to change the display. here's the output:
WebSocket client #1 connected from 192.168.86.35
Core ID: 1
Task Name: async_tcp <- from onWsEvent
Core ID: 1
Task Name: async_tcp <- from display method because of the connect ws event
WebSocket client #1 disconnected
Core ID: 1
Task Name: async_tcp <- from display method because of the disconnect ws event
Core ID: 1
Task Name: loopTask <- from display method because i updated the screen from a serial monitor input
I am not very experienced with C++ and what's going on in the background in memory etc. i have only some basic understanding from my vocational training 15 years ago. But i know that in other areas the UI can only be updated from the main thread, which makes sense. Does this also apply to here?
How can I fix this and is there a way to execute code from the loopTask coming from another task? Or do I need to handle all display changes on a separate task?
thanks for your help!