I’m building an analog clock on an ESP32 Wrover Kit with a TFT LCD using the TFT_eSPI library. The clock displays the correct time using NTP, but I have a problem with the hands:
When the hands move, the old position remains visible (trails).
If I clear the whole screen and redraw the background and text every update, it works, but causes flicker and my static text disappears briefly.
Since my background is a colorful image, I cannot just erase the hands with a solid color.
Here is a simplified version of my code that reproduces the issue:
#include <TFT_eSPI.h> #include <time.h> #include <WiFi.h> TFT_eSPI tft = TFT_eSPI(); #define CENTER_X 50 #define CENTER_Y 60 #define RADIUS 50 #define HOUR_LENGTH 10 #define MINUTE_LENGTH 20 const char* ssid = "Dina"; const char* password = "Dd78134003Segco"; const char* ntpServer = "pool.ntp.org"; const long gmtOffset_sec = 12600; // ایران +3:30 const int daylightOffset_sec = 0; int lastMinute = -1; // draw clock hand as triangle void drawHandTriangle(int length, float angleRad, uint16_t color, int width) { float cosA = cos(angleRad); float sinA = sin(angleRad); int xTip = CENTER_X + cosA * length; int yTip = CENTER_Y + sinA * length; int xLeft = CENTER_X + cos(angleRad + 1.57) * width; int yLeft = CENTER_Y + sin(angleRad + 1.57) * width; int xRight = CENTER_X + cos(angleRad - 1.57) * width; int yRight = CENTER_Y + sin(angleRad - 1.57) * width; tft.fillTriangle(xTip, yTip, xLeft, yLeft, xRight, yRight, color); } void drawClockFace() { tft.fillScreen(TFT_BLACK); for (int h = 0; h < 12; h++) { float angle = (h * 30 - 90) * 0.0174533; int x0 = CENTER_X + cos(angle) * (RADIUS - 3); int y0 = CENTER_Y + sin(angle) * (RADIUS - 3); int x1 = CENTER_X + cos(angle) * RADIUS; int y1 = CENTER_Y + sin(angle) * RADIUS; tft.drawLine(x0, y0, x1, y1, TFT_WHITE); } for (int h = 1; h <= 12; h++) { float angle = (h * 30 - 90) * 0.0174533; int x = CENTER_X + cos(angle) * (RADIUS - 15); int y = CENTER_Y + sin(angle) * (RADIUS - 15); tft.setTextColor(TFT_WHITE); tft.setCursor(x - 5, y - 7); tft.print(h); } } void setup() { Serial.begin(115200); tft.init(); tft.setRotation(0); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); } configTime(gmtOffset_sec, daylightOffset_sec, ntpServer); drawClockFace(); } void loop() { struct tm timeinfo; if (!getLocalTime(&timeinfo)) { delay(1000); return; } if (timeinfo.tm_min != lastMinute) { drawClockFace(); // clears and redraws everything → causes flicker lastMinute = timeinfo.tm_min; float hourAngle = ((timeinfo.tm_hour % 12) + timeinfo.tm_min / 60.0) * 30 - 90; float minuteAngle = timeinfo.tm_min * 6 - 90; drawHandTriangle(HOUR_LENGTH, hourAngle * 0.0174533, TFT_WHITE, 2); drawHandTriangle(MINUTE_LENGTH, minuteAngle * 0.0174533, TFT_WHITE, 1); } delay(1000); } Question: How can I update only the hands on top of a static background image and text, without leaving trails or causing flicker?