What do you want to achieve?
Eliminate an intermittent, periodic full-screen flicker/glitch on an ESP32-S3 RGB parallel display (Sunton ESP32-8048S070C, 800x480), using the Arduino framework (Arduino IDE). A constant/subtle flicker was already resolved by lowering PCLK. What remains is a rare, roughly periodic full-screen flash that I have not been able to eliminate through any Arduino-side configuration.
I’ve since discovered that Espressif’s official esp_lvgl_port component exposes an avoid_tearing flag specifically designed for this class of problem, but this component is ESP-IDF only and has no equivalent in Arduino_GFX or LovyanGFX. I’d like to confirm whether that’s really the only path, or if there’s something within the Arduino ecosystem I’m missing.
What have you tried so far?
- Moved the LVGL draw buffer from a plain static array to
heap_caps_mallocwithMALLOC_CAP_DMA— improved FPS from ~9 to ~26 and reduced a constant subtle flicker significantly. - Reduced
prefer_speed(PCLK) from 16MHz to 12MHz onArduino_ESP32RGBPanel— this fully eliminated the constant flicker. Confirmed via community reports that PCLK too high causes flicker under CPU load on this exact board. - Tried several different hsync/vsync porch/pulse timing combinations sourced from different community repos for the same board model — no measurable effect on the remaining periodic flick.
- Tried increasing buffer size (up to 1/4 and 1/8 of the screen) and different
heap_capsflags (MALLOC_CAP_INTERNAL | MALLOC_CAP_8BITvsMALLOC_CAP_DMA) — no improvement over the DMA + 40-line buffer baseline; larger allocations sometimes failed outright due to internal RAM fragmentation. - Switched the display driver to LovyanGFX (
Bus_RGB/Panel_RGB, including the officially bundledlgfx_user/LGFX_Sunton_ESP32-8048S070.hconfig anduse_psram=1viaconfig_detail()) — introduced new artifacts (sync corruption / wrong colors) that I couldn’t resolve, so I reverted to Arduino_GFX. - Suspected the GT911 I2C touch polling (happening inside the
read_cb, same core aslv_timer_handler) as the cause of the periodic flick. Tried throttling the I2C read to once per 50ms — no change. Then moved touch polling entirely to a separate FreeRTOS task pinned to Core 0 (away from the core runninglv_timer_handler/display refresh) — still no change. - Confirmed via Espressif’s own FAQ that the ESP32-S3 RGB “screen drift” bug is fixed as of ESP-IDF 5.1+/arduino-esp32 v3.x (already on 3.3.11), so that specific known bug shouldn’t apply here.
- Found a related open GitHub issue reporting that Arduino’s precompiled esp32 core libraries ship with
CONFIG_ESP32S3_DATA_CACHE_LINE_SIZE=32, while Octal PSRAM DDR mode uses 64-byte wrap bursts — a mismatch that could cause periodic cache-coherency glitches. Another maker confirmed that manually patching this setting does not take effect reliably in Arduino IDE builds.
Code to reproduce
Simplified version of my current setup (Arduino_GFX + confirmed-working pinout/timing for this exact board):
#include <Arduino_GFX_Library.h>
#include <TAMC_GT911.h>
#include <lvgl.h>
#include <Wire.h>
#include "esp_heap_caps.h"
Arduino_ESP32RGBPanel *rgbpanel = new Arduino_ESP32RGBPanel(
41 /* DE */, 40 /* VSYNC */, 39 /* HSYNC */, 42 /* PCLK */,
14 /* R0 */, 21 /* R1 */, 47 /* R2 */, 48 /* R3 */, 45 /* R4 */,
9 /* G0 */, 46 /* G1 */, 3 /* G2 */, 8 /* G3 */, 16 /* G4 */, 1 /* G5 */,
15 /* B0 */, 7 /* B1 */, 6 /* B2 */, 5 /* B3 */, 4 /* B4 */,
0, 8, 2, 43, // hsync
0, 8, 2, 12, // vsync
1, 12000000, false // pclk_active_neg, prefer_speed, useBigEndian
);
Arduino_RGB_Display *gfx = new Arduino_RGB_Display(800, 480, rgbpanel);
lv_color_t *buf1;
void my_disp_flush(lv_display_t *disp, const lv_area_t *area, uint8_t *px_map) {
uint32_t w = (area->x2 - area->x1 + 1);
uint32_t h = (area->y2 - area->y1 + 1);
gfx->draw16bitRGBBitmap(area->x1, area->y1, (uint16_t *)px_map, w, h);
lv_display_flush_ready(disp);
}
void setup() {
gfx->begin();
pinMode(2, OUTPUT);
digitalWrite(2, HIGH);
size_t buf_size = 800 * 40 * sizeof(lv_color_t);
buf1 = (lv_color_t *)heap_caps_malloc(buf_size, MALLOC_CAP_DMA);
lv_init();
lv_tick_set_cb(millis);
lv_display_t *disp = lv_display_create(800, 480);
lv_display_set_flush_cb(disp, my_disp_flush);
lv_display_set_buffers(disp, buf1, NULL, buf_size, LV_DISPLAY_RENDER_MODE_PARTIAL);
lv_display_set_default(disp);
lv_obj_t *label = lv_label_create(lv_scr_act());
lv_label_set_text(label, "Hello, world!");
}
void loop() {
lv_timer_handler();
delay(5);
}
The remaining flicker manifests as a brief full-screen flash, roughly periodic (every few seconds), even with a completely static UI (no animations, no periodic redraws in my own code) and no touch interaction at all.
Screenshot and/or video
I have a photo of an earlier, worse symptom (before the PCLK fix — full misalignment/corruption, resolved since). The current remaining issue is a brief full-screen flash that’s hard to capture in a still photo; I can try to record a video if it would help diagnose this.
Environment
- MCU/Board: ESP32-S3-WROOM-1 (Sunton ESP32-8048S070C, 7" 800x480 RGB parallel TFT, EK9716 display driver, GT911 capacitive touch, 8MB PSRAM/OPI, 16MB Flash)
- LVGL version: 9.2.2 (installed via Arduino Library Manager)
- Display driver: GFX Library for Arduino (Arduino_GFX) 1.6.7
- arduino-esp32 core: 3.3.11
- IDE: Arduino IDE 2.3.10
- Board settings: ESP32S3 Dev Module, USB CDC On Boot: Disabled, Flash Size 16MB, Partition Scheme 16M Flash (3MB APP/9.9MB FATFS), PSRAM: OPI PSRAM, Flash Mode QIO 80MHz, Upload Speed 921600