How to handle correctly "buffers" and "sprites" to completely remove flickering ? #1116
-
Hello Bodmer, I am learning programming esp32 (plugged to a classic TFT 320x240 screen + differents sensors), and of course I discovered your fantastic library. Congratulations for this amazing work ! I'am trying to create a gauge with a jpeg background and a moving needle. At some point, I decided to find a way to totally remove the residual flickering of the needle (generated by the alternance of patching back the buffer to the TFT and writing over the needle with the sprite). Is there a way to achieve it in an academic manner ?
Many thanks for your help, |
Beta Was this translation helpful? Give feedback.
Replies: 2 comments 4 replies
-
This is one of the more difficult tasks to achieve unless the images are small due to the limited RAM available on most low cost processors. To answer you questions:
Other approaches are to store the decoded image in SPIFFS/LittleFS and pull it out when needed. Ideally two large memory buffers are needed, one could be in FLASH (SPIFFS or LittleFS) or in a PROGMEM array. Buffer 1 to contain a clean image, which is copied into Buffer 2 then the needle added and then the whole of Buffer 2 copied to the screen. Clearly the buffers only need to cover the part of the screen where the needle sweeps. In the next loop Buffer 1 is copied to Buffer 2 and the needle drawn in the new position. A more memory efficient approach is to make buffer 2 just large enough to refresh the area where the needle was last drawn and the new needle area. Clearly this needs coordinate calculations. to get the buffer rendered in exactly the right place, so large beffers are the simplest. If your ESP32 has PSRAM then full screen buffers can be allocated, but the larger the buffer the longer it takes to copy to the screen. The main probelm with large buffers is that the needle update time is large so the movement in not fluid. The "Animated dial" example was mainly intended for things that change slowly like temperature or humidity, then the needle flickers only ocassionally when it moves. Clearly you want to avoid a noisy signal in this situation by averaging or setting bound for the delta change before a redraw. |
Beta Was this translation helpful? Give feedback.
-
I have a two part issue related to this. 1. I threw in some millis() calls to track timing and the big part of the timing cost is the tft.readrect call, the actual writing of the old buffer and the writing of the sprite are quite fast. So when you first write the old buffer, then read the new area, then write the new sprite, you have a long pause for reading, not for rotating / pushing. I tried to look for a way to read the image of another sprite, rather than the screen itself, but don't think that exists in your library. If I'm using one sprite for my background, then being able to pull the background values from that sprite, then hold in buffer and push should be much faster, as that's all chip internal rather than communicating with the board (as I believe tft.readrect does).
|
Beta Was this translation helpful? Give feedback.
This is one of the more difficult tasks to achieve unless the images are small due to the limited RAM available on most low cost processors.
To answer you questions: