Hello, A friend of mine who knows C language but not the way arduino language structure is trying to help me to a build a menu with swipe touch. It is a esp32 with a 4.0" TFT LCD screen. What happens is that the screen flickers when swiping to the second menu and flickers a lot and really slow trying to go to the second menu and a third. Not sure what to do I'm posting the code see what others think and maybe figure out a way to fix this problem. Please community I need more pairs of eyes on this help?
#include <TFT_eSPI.h>
#include <SPI.h>
TFT_eSPI tft = TFT_eSPI();
// Two row sprites (safe memory)
TFT_eSprite rowSprites[2] = { TFT_eSprite(&tft), TFT_eSprite(&tft) };
// Temporary sprite for smooth page animation (HALF screen only)
TFT_eSprite transitionSprite = TFT_eSprite(&tft);
#define BOX_W 70
#define BOX_H 70
#define GAP_X 20
#define GAP_Y 30
#define TEXT_H 20
int page = 0;
int cursor = 0;
// Touch swipe variables
int touchStartX = 0;
int touchEndX = 0;
const int SWIPE_THRESHOLD = 50; // pixels
void setup() {
Serial.begin(115200);
delay(200);
tft.init();
tft.setRotation(1); // landscape
tft.fillScreen(TFT_BLACK);
// Create sprites for each row
for (int i = 0; i < 2; i++) {
rowSprites[i].createSprite(tft.width(), BOX_H + TEXT_H);
rowSprites[i].setSwapBytes(true);
}
// Create transition sprite for smooth slide (only 320x240)
transitionSprite.createSprite(320, 240);
transitionSprite.setSwapBytes(true);
drawMenu();
}
void loop() {
// Serial input for debugging
if (Serial.available()) {
char c = Serial.read();
if (c == 'L' || c == 'l') moveLeft();
if (c == 'R' || c == 'r') moveRight();
if (c == 'U' || c == 'u') moveUp();
if (c == 'D' || c == 'd') moveDown();
drawMenu();
}
// --- Touch swipe detection ---
uint16_t x, y;
if (tft.getTouch(&x, &y)) {
touchStartX = x;
delay(50);
while (tft.getTouch(&x, &y)) delay(10);
touchEndX = x;
int dx = touchEndX - touchStartX;
if (dx > SWIPE_THRESHOLD) {
prevPageSmooth(); // smooth animation
}
else if (dx < -SWIPE_THRESHOLD) {
nextPageSmooth(); // smooth animation
}
}
}
// ===========================================================
// Draw menu normally (no animation)
// ===========================================================
void drawMenu() {
tft.fillScreen(TFT_BLACK);
int startX = 20;
int startY = 20;
for (int row = 0; row < 2; row++) {
rowSprites[row].fillSprite(TFT_BLACK);
rowSprites[row].setTextColor(TFT_WHITE, TFT_BLACK);
rowSprites[row].setTextDatum(TC_DATUM);
for (int col = 0; col < 4; col++) {
int i = row * 4 + col;
int x = col * (BOX_W + GAP_X);
uint16_t color = (i == cursor) ? TFT_YELLOW : TFT_BLUE;
rowSprites[row].fillRect(x, 0, BOX_W, BOX_H, color);
char label[20];
sprintf(label, "Demo %d", page * 8 + i + 1);
rowSprites[row].drawString(label, x + BOX_W / 2, BOX_H + 5, 2);
}
rowSprites[row].pushSprite(0, startY + row * (BOX_H + GAP_Y + TEXT_H));
}
tft.setTextDatum(MC_DATUM);
tft.setTextColor(TFT_WHITE, TFT_BLACK);
tft.drawString("Page:", tft.width() - 50, 20, 2);
tft.drawNumber(page + 1, tft.width() - 50, 50, 4);
}
// ===========================================================
// Smooth animation for NEXT page (slide left)
// ===========================================================
void nextPageSmooth() {
if (page >= 2) return;
int oldPage = page;
int newPage = page + 1;
// Render NEW PAGE into transition sprite
transitionSprite.fillSprite(TFT_BLACK);
renderPageToSprite(newPage);
// Slide animation
for (int x = 320; x >= 0; x -= 20) {
drawMenu(); // draw old page
transitionSprite.pushSprite(x, 80); // slide new page in
}
page = newPage;
cursor = 0;
drawMenu();
}
// ===========================================================
// Smooth animation for PREVIOUS page (slide right)
// ===========================================================
void prevPageSmooth() {
if (page <= 0) return;
int oldPage = page;
int newPage = page - 1;
// Render NEW PAGE into transition sprite
transitionSprite.fillSprite(TFT_BLACK);
renderPageToSprite(newPage);
// Slide animation
for (int x = -320; x <= 0; x += 20) {
drawMenu(); // draw old page
transitionSprite.pushSprite(x, 80); // slide new page in
}
page = newPage;
cursor = 0;
drawMenu();
}
// ===========================================================
// Draws menu content (two rows) INTO transition sprite
// ===========================================================
void renderPageToSprite(int pg) {
int startY = 0; // inside sprite (0β240)
for (int row = 0; row < 2; row++) {
// temp sprite for row
rowSprites[row].fillSprite(TFT_BLACK);
rowSprites[row].setTextColor(TFT_WHITE, TFT_BLACK);
rowSprites[row].setTextDatum(TC_DATUM);
for (int col = 0; col < 4; col++) {
int i = row * 4 + col;
int x = col * (BOX_W + GAP_X);
uint16_t color = TFT_BLUE; // cursor highlight ignored in transition
rowSprites[row].fillRect(x, 0, BOX_W, BOX_H, color);
char label[20];
sprintf(label, "Demo %d", pg * 8 + i + 1);
rowSprites[row].drawString(label, x + BOX_W/2, BOX_H + 5, 2);
}
rowSprites[row].pushToSprite(&transitionSprite, 0, startY + row * (BOX_H + GAP_Y + TEXT_H));
}
}
// ===========================================================
// Cursor movement
// ===========================================================
void moveLeft() {
if (cursor % 4 == 0) {
if (page > 0) { page--; cursor = 3; }
} else cursor--;
}
void moveRight() {
if (cursor % 4 == 3) {
if (page < 2) { page++; cursor = 0; }
} else cursor++;
}
void moveUp() { if (cursor >= 4) cursor -= 4; }
void moveDown() { if (cursor < 4) cursor += 4; }