Hello everyone,
I used the good example of istvank https://github.com/istvank/Waveshare-ESP32-S3-Touch-LCD-4.3 to test Waveshare-ESP32-S3-Touch-LCD-4.3, I put lvgl widget demo on it, everything compile and work well, except the animation/scrollings blinks, the display is slow and not very stable, you can see the problem in attached videos.
What MCU/Processor/Board and compiler are you using?
Waveshare ESP32-S3-Touch-LCD-4.3
What do you want to achieve?
stablize lvgl ui on Waveshare 4.3 screen
What have you tried so far?
Compile, Upload and test display and UI
Code to reproduce
Add the relevant code snippets here.
The code block(s) should be between ```c and ``` tags:
clone https://github.com/istvank/Waveshare-ESP32-S3-Touch-LCD-4.3.git
//enable widget demo on lv_conf.h
#define LV_USE_DEMO_WIDGETS 1
//include widget demo on main.cpp
#include "lvgl/demos/widgets/lv_demo_widgets.h"
//add function in the setup
lv_demo_widgets();
That display I believe is using an RGB Bus and it also has a pretty high pixel count as well. You are pushing the limits of what can be done with a single core of the ESP32.
Here is the code for how I am dealing with the RGB Bus on an ESP32-S3
My main goal was to get better performance when doing a software rotate which is why things are named the way they are. Because of how I wrote the code there was a side effect. The performance even when not rotating improved greatly. I have one core that handles the synchronization of the frame buffers that are used to send data to the display. The ISR’s that occur when the frame buffer is transmitting no longer occur on the same core that LVGL is running on so LVGL is able to work without being interrupted. LVGL is also rendering to partial buffers instead of full frame buffers and those partial buffers are able to be located in internal RAM instead of SPIRAM. Internal RAM is leaps and bounds faster. The last thing is while one partial buffer is being copied to a full frame buffer which takes places on the second core LVGL is able to continue running on the first core. It is able to render to the second partial buffer. There are almost no blocking calls made so nothing is sitting there waiting.
There is a cost when doing this and that is higher RAM use. For the display you are using a total of 1,536,000 bytes of SPIRAM are used and a total of 153,600 bytes of internal RAM gets used for the frame buffers alone. For that board this is not a big deal because you have 8MB is SPIRAM available and 500K of internal RAM available.
The last thing that is able to be done is you can overclock the SPIRAM so instead of it running at 80mhz you can get it to an effective clock of 120mhz.
Hello @kdschlosser ! Thank you for your detailed reply, and yes it’s a RGB display.
I’m not an expert, but I was suggested to use this kind of mcu for my learning application.
I dont’t need to do a software rotating, but just for my understanding, did you have an example/demo code to using with my card ?
Thank you in advance
RGB displays are tough because the ESP32 needs to be streaming the buffer to the display in an endless loop. Where as an I8080 or SPI display has an IC with GRAM that holds the frame buffer data once it is sent to the IC. The IC then handles the streaming of the framebuffer to the display. This lets the ESP32 do other tasks and not get interrupted constantly.
It’s not easy to get an RGB display working smooth with the high pixel count that you are using.
Do you have any experience in writing Python code?
Hello,
unfortunately, I’m stuck with only RBG ! I have two with same brand :
I just received the 5inch with lvgl demo inside, it’s more better, no flickering but still little slow.
I don’t know if with 4.3 it’s driver problem or something else in the code.
I heard that LovyanGFX is more efficient than ESP_Panel_Library.h I use in my project, but I could never get it to work with platformio.
And yes, I have some experience in Python.
Thank you for your help !
The reason why I ask about the Python is you can run Python on either of those boards you have and it will have LVGL and there are drivers for the RGB display that are written to give you as smooth a UI as possible. You are more than welcome to give it a try if you want. Unless there is some specific need to use C/CPP.
The problem it’s in the code, I got proof, I just uploaded the same code in the new card, just changing resolution, I get same problems (flickering, blinks and more slow animations).
I’ll try just to see difference.
Thank you
also changing the resolution can have a HUGE impact on performance.
192,000,000
6,144,000
as an example a 16 bit color display that has a resolution of 800x480 need to render a total of 384,000 pixels which is 768,000 bytes of data. if the display has a resolution of 480 x 320 not there are 153,600 pixels and 307,200 bytes of data. That is 60% less work that needs to be done. Not only is there less work needing to be done by LVGL the data is also able to send a hell of a lot faster to update the display. 16 lanes running at 12mhz would have a therotical transfer speed of 32 milliseconds for the 800x480 display and 12 milliseconds for the 480x320 display. the 480x320 display is able to update the display 2.66 times faster than the 800x480 display.
No I mean, before uploading my code into the 5inch card, the original firmware shipped into it works great, without flickering or something similar, but after uploading my code, the flickering problem comes back, it’s the code that’s for sure.
what is the resolution for the second display? I know the 4.3" is 800 x 480. IDK what the other is.
The reason why I had asked about using Python is because I have written a binding that will allow you to run Python + LVGL on your boards. It already has everything build into it to handle the displays you are using and it is going to do it as smooth as possible. It even has rotation built into it as well. While the rotation is software rotation you will only notice the smallest performance hit when using it. This is because I use the second core of the ESP32 to handle the rotation. I offload the interrupts used when sending the data to the display to the second core as well. So LVGL and you application code runs on one core and the transmitting/rotation of the frame buffer is handled on the second core. This keeps things free so LVGL is able to keep on running without any lengthy code blocking it. Using double buffering is what allows that to take place.