in terms of performance os the ESP32-S3. It is exactly the same with respect to speed as the original ESP32. It has more pins and it has larger flash and psram availability to it over the esp32. The ESP32-S3 does have support for the RGB bus only if you use the driver that is included in the ESP-IDF. The ESP-IDF version that is used in the Arduino IDE is old and it doesn’t included the needed pieces to access the RGB bus driver in the ESP-IDF. So bitbang or hacking SPI are the only things that are going to allow it to work and there are performance losses for doing so.
Thank you kdschlosser.
It’s why I didn’t get a better experience when tested ESP32S3 by Arduino IDE.
and worse when hooked ESP32S3 with a ST7789V the latter even can’t light up.
BTW. what “The Sonton ESP displays are RGB” means? is the “Sonton ESP " special?
what I used is just buy online ESP32 S3 and 1.69” TFT which used ST7789V.
And RGB display is kind of a misnomer. That term is not about the display itself it’s about the connection between the display and the driver IC that runs the display. It’s how the data gets transmitted to that driver IC. With an RGB bus the display IC doesn’t have any internal memory so in order for the display to work properly the buffer data has to be constantly streamed to the display. over and over again.
This is how it works out. say you are transmitting the data at 12Mhz that is 12,000,000 bits per second. Now that sounds like a lot right? It’s really not. with an RGB display that is using 16 lanes (16 pins connected to transfer the data) it is able to send 8 bits at a time in parallel. so lets do some quick math.
we assume an 800 x 400 display using 16 lanes so the color depth is RGB565 which is 2 bytes of data per pixel.
800 x 400 x 2 = 640,000 bytes of data.
There are 8 bits to a byte
640,000 x 8 = 5,120,000 bits.
Per the esp32 data sheet there is an interrupt time of 0.003094 seconds when doing a DMA transfer and if you are not using DMA there is no interrupt time because you have to wait until it is done sending, Polling is what that method is called. Polling incurs a 7us processing time for each transaction where as DMA transfers have a 21us processing time per transaction. The last piece is a polling transaction has a maximum size of 64 bytes per transaction where as on the esp32-s3 the maximum size per transaction is about 64,000 bytes when using DMA.
so this is what the math looks like
(transaction_time * (buf_size_bytes / max_trans_size)) + ((bits_to_byte * buf_size_bytes) / (frequency_in_hz * lane_count))
Lets plug in some numbers.
(2.1e-5 * (640,000 / 64,000)) + ((8 * 640,000) / (12,000,000 * 16)) = ~0.02688 seconds (~26.88 milliseconds)
That is what it would take in time to transmit a single frame over 16 lanes at 12MHz. How many of those can be sent in a single second…
1000 / 26.88 = 37.20 frames per second.
That’s not too bad, But that is only the time it takes to send the data, not to render it. It can easily take 7 to 12 milliseconds if doing a render where 1/2 the frame needs to be redrawn. lets call it 7 milliseconds…
26.88 + 7 = 33.88
1000 / 33.88 = 29.51
so now we are at 29.51 frames per second. If you then include needing to carry out other tasks at the same time like checking pin states and if you have to run any complex calculations that number is going to keep on falling. If you need to scroll and the entire screen needs to redraw then it starts getting expensive to do and the frame rate is going to be around 19 and then you take a hit for doing other things and now you are down to 10.
The ESP32 does have 2 cores to be able to do 2 things at the same time, problem is LVGL is not written to be thread safe so it’s not able to split the workload between 2 processes either.
A display that is 800 x 400 using an RGB bus at 16 bit color depth is not going to provide a nice user experience. The absolute maximum I would go on the ESP32 using an RGB bus with a very light workload for additional tasks would be a 480 x 320 display.
If you dive in really deep and you get everything using the 2 cores to their best it would give you 20 to 25 frames per second using DMA memory and 2 frame buffers.
There is another spot that could put you in a jam and that is the need to use the PSRAM for the frame buffer due to their size. If there is any code that has to access the PSRAM at the same time the buffer is being sent the data rates are going to drop. If there is one other thing accessing the memory the data rates are cut in half. The second core accesses the ram then you are down to 1/3rd of the transmission speed.
This is where you would use an I8080 interface. You get the 16 lanes. You can use DMA memory and double buffering. and the buffer sizes only need to be 1/10th the size thanks to the display IC having GRAM. The buffers also don’t have to be synced with each which means you can render to the second buffer while the first is being sent. The buffer sizes are also small enough so they can fit into sram which is a large amount faster. and the last thing is you can get a higher clock using I8080. 20MHz is pretty common.
High resolution displays using an RGB bus is not ideal if you want smooth UI transitions when using the ESP32.If you UI is being used for displaying sensor readings and there isn’t much in the way of user input it then you will do OK. You will achieve a better result using an I8080 bus if wanting smooth UI transitions and there is a lot of user input.
If at all possible I would steer clear of using the Arduino IDE. That because it doesn’t provide you with the display bus drivers that are going to run the best. I would not use any libraries to handle the transfers to the display. The code is not that hard to write so you are not using a framework other than the drivers in the ESP-IDF.
Here is an example of what the code would look like.
Hi i have few questions regarding this topic. I am doing a project which involves esp32 and 8 bit parallel interface (5" LCD) WITH ILI9488 Driver. I am in platform io . Modified the driver inside TFT_eSPI library to make an example work. Then moved on to lvgl . Designed a ui in square line studio and imported to my project. And got it working somehow. My question is the ui upadtes are very slow in my case and i tried with 8 bit color depth it didn’t work so u had to move to 16 bit color depth, does it create memory issues and can i try 32 bit color depth. Feel free to ask anything to me
You are using an S3 I am guessing. If you are interested in better performance there are a few things I recommend doing. The first is to use the ESP-IDF directly and it’s build system to compile for the MCU. don’t use platform.io or the Arduino IDE the ESP32 is not an Arduino and as such the EP-IDF has modified/altered and a lot of wrapper code has been written in order to get the Arduino IDE t compile for the ESP32. That wrapper code slows things down. The other thing is grafix libraries like TFT-eSPI are not just drivers. they are a grafix framework much like LVGL. How it handles things is not going to produce the best results because you are not using it how it was intended to be used. Yes it does work, will it go what it needs to do with the best possible performance? No it will not.
Use the low level drivers that are written into the ESP-IDF for the display driver. They are fairly easy to use. I have the startup commands for your display if you need them…
because you are using an 8 lane connection to the display I recommend using RGB888 for the color depth if your display supports that color depth. I only recommend the use of the color depth IF you need to byte swap if you use RGB565. Byte swapping takes time and the time spent doing that you can trad off to get a higher color depth. If you don’t need to byte swap then use RGB565. You will want to use 2 frame buffers. each frame buffer should be 1/10th the size of the display times the color depth in bytes. so width * height / 10 * bytes_per_pixel. These buffers need to be allocated using heap_caps_malloc and passing the DMA memory flag to that function. This will create the buffers in DMA memory space. If you have enough internal memory that is DMA addressable to hold both the buffers then that would be ideal to use the internal memory. If not you can use the SPIRAM (PSRAM) but it is going to be slower. You can speed things up a bit by overclocking the SPI speed for the SPIRAM. How much you can overclock it depends on if the flash memory is quad SPI or octal SPI. You can get the most performance if you have octal flash.
If you want to squeeze every little bit of performance out of it you will need to create a task using FreeRTOS and have that task run on the second core of the ESP32. This task would handle the IO for the display. You would want to start the display driver in this task. The reason being is the DMA buffer is only so large and when that buffer is done sending more data needs to be placed into the buffer, This is done inside of an ISR which occurs on the core the driver was started on. an ISR literally interrupts the processor and tells it to stop doing what it’s doing to do something else. That is going to slow things down if LVGL is running on the same core as the driver. By separating the 2 the interrupts will occur on the other core and not stop LVGL from doing what it is doing.
Stop using squareline studio. or only use it as a starting point. The code it writes is not the most efficient code. In order to get the best performance you will need to either clean up the code that square line produces or write it from scratch.
If you provide me with more specifics as to what you are using for hardware I can give you better direction on what you need to do. I would need to know the variant of the ESP32 you are using. How much PSRAM and how much flash does it have. I am assuming because you are using the ILI9488 IC that you have a resolution of 320 x 480 for the display, is that correct?
hey thanks for the replay, what i am really trying to achieve is to incooperate LVGL with pico boards like RP2350.
i made a gui and included it in my pico project and used the DMA+hstx combo for driving a HDMI like signal and used pico DVI HDMI sock to get a result in monitor or any hdmi display . so my GUI is made in 800x480 thats what i want , since pico 2w has limited RAM i need to reduce the color depth to 8 bit to make it work and i am getting some output through HDMI. i also need to try through SPI and 8 bit parallel and 16 bit parallel to find which is more faster and better. my preferred display size is 4.5 inch or 5 inch.
also can you tell me whats the LCD you are using right now , like is it 16 bit parallel or 32 bit and any links which i can refer to