/*
╔══════════════════════════════════════════════════════════════════╗
║ CYD ESP32-2432S028 — TFT GRAPHICS TEST ║
║ सर्व settings या file मध्ये आहेत — कुठलीही file edit नको! ║
║ By: Arvind Patil | AI Centre Nandurbar ║
╚══════════════════════════════════════════════════════════════════╝
─── फक्त हे करा ────────────────────────────────────────────────────
1. TFT_eSPI library install करा (Library Manager)
2. हे sketch upload करा — बाकी काहीही edit नको!
─── Arduino IDE Board Settings ──────────────────────────────────────
Board → ESP32 Dev Module
CPU Freq → 240 MHz
Flash Size → 4MB
Upload → 921600
─── CYD WIRING (already internal) ──────────────────────────────────
TFT MOSI → GPIO 13 TFT CLK → GPIO 14
TFT CS → GPIO 15 TFT DC → GPIO 2
TFT MISO → GPIO 12 TFT BL → GPIO 21 (Backlight)
TOUCH CS → GPIO 33 RGB LED → R:4 G:16 B:17
*/
// ════════════════════════════════════════════════════════════════════
// USER SETUP — TFT_eSPI ला library files edit न करता configure करतो
// #define USER_SETUP_LOADED सांगतो: "माझे settings वापर"
// ════════════════════════════════════════════════════════════════════
#define USER_SETUP_LOADED // ← हे key आहे! Library चे setup skip होते
#define ILI9341_DRIVER // CYD चा TFT chip
#define TFT_WIDTH 240
#define TFT_HEIGHT 320
// ── SPI Pins (CYD ESP32-2432S028 fixed pins) ──
#define TFT_MISO 12
#define TFT_MOSI 13
#define TFT_SCLK 14
#define TFT_CS 15
#define TFT_DC 2
#define TFT_RST -1 // Reset नाही — GPIO ला जोडलेला नाही
#define TFT_BL 21 // Backlight
#define TOUCH_CS 33 // Touch screen chip select
// ── Font support ──
#define LOAD_GLCD // Font 1
#define LOAD_FONT2 // Font 2
#define LOAD_FONT4 // Font 4
#define LOAD_FONT6 // Font 6 (digits)
#define LOAD_FONT7 // Font 7 (7-segment style)
#define LOAD_FONT8 // Font 8 (large digits)
#define LOAD_GFXFF // FreeFonts
#define SMOOTH_FONT // Anti-aliased fonts
// ── SPI Frequency ──
#define SPI_FREQUENCY 55000000 // 55 MHz — CYD साठी optimal
#define SPI_READ_FREQUENCY 20000000
#define SPI_TOUCH_FREQUENCY 2500000
// ════════════════════════════════════════════════════════════════════
// LIBRARY INCLUDES
// ════════════════════════════════════════════════════════════════════
#include <TFT_eSPI.h> // USER_SETUP_LOADED define केल्यामुळे
#include <SPI.h> // वरचे defines आपोआप वापरले जातात
TFT_eSPI tft = TFT_eSPI();
// ── RGB LED (CYD वर active LOW आहे) ──
#define LED_R 4
#define LED_G 16
#define LED_B 17
void ledColor(bool r, bool g, bool b) {
digitalWrite(LED_R, !r);
digitalWrite(LED_G, !g);
digitalWrite(LED_B, !b);
}
// ── Display Size ──
#define W 320
#define H 240
// ── Timing ──
#define HOLD_MS 1800
#define SHORT_MS 1100
// ── FPS tracking ──
float fps_result = 0;
// ════════════════════════════════════════════════════════════════════
// HELPER FUNCTIONS
// ════════════════════════════════════════════════════════════════════
// Title bar — प्रत्येक test च्या वरती
void titleBar(const char* txt, uint16_t col = TFT_GOLD) {
tft.fillRect(0, 0, W, 22, TFT_NAVY);
tft.drawFastHLine(0, 22, W, col);
tft.setTextFont(2);
tft.setTextColor(col, TFT_NAVY);
tft.setCursor(8, 4);
tft.print(txt);
tft.setTextColor(0x4A69, TFT_NAVY);
tft.setCursor(W - 90, 4);
tft.print("AI Ctr Ndbr");
}
void waitTest(uint16_t ms = HOLD_MS) { delay(ms); }
// ════════════════════════════════════════════════════════════════════
// TEST 1 — SPLASH SCREEN
// ════════════════════════════════════════════════════════════════════
void testSplash() {
// Gradient background
for (int x = 0; x < W; x++) {
uint8_t r = map(x, 0, W, 20, 60);
uint8_t g = map(x, 0, W, 10, 30);
uint8_t b = map(x, 0, W, 80, 180);
tft.drawFastVLine(x, 0, H, tft.color565(r, g, b));
}
tft.setTextDatum(MC_DATUM);
tft.setTextFont(4);
tft.setTextColor(TFT_WHITE);
tft.drawString("CYD ESP32-2432S028", W/2, H/2 - 36);
tft.setTextFont(6);
tft.setTextColor(TFT_GOLD);
tft.drawString("TFT TEST", W/2, H/2 + 6);
tft.setTextFont(2);
tft.setTextColor(TFT_CYAN);
tft.drawString("AI Centre Nandurbar | Arvind Patil", W/2, H/2 + 50);
tft.setTextFont(1);
tft.setTextColor(0x4A69);
tft.drawString("ILI9341 SPI 55MHz No User_Setup Edit!", W/2, H - 16);
delay(2500);
}
// ════════════════════════════════════════════════════════════════════
// TEST 2 — COLOR FILL BENCHMARK
// ════════════════════════════════════════════════════════════════════
void testColorFill() {
const uint16_t colors[] = {
TFT_RED, TFT_GREEN, TFT_BLUE, TFT_YELLOW,
TFT_CYAN, TFT_MAGENTA, TFT_WHITE, TFT_ORANGE,
0x801F, 0xFC18
};
const char* names[] = {
"RED","GREEN","BLUE","YELLOW",
"CYAN","MAGENTA","WHITE","ORANGE",
"PURPLE","PINK"
};
for (int i = 0; i < 10; i++) {
uint32_t t0 = millis();
tft.fillScreen(colors[i]);
uint32_t ms = millis() - t0;
tft.setTextDatum(MC_DATUM);
tft.setTextFont(4);
tft.setTextColor(i == 6 ? TFT_BLACK : TFT_BLACK);
tft.drawString(names[i], W/2, H/2 - 14);
char buf[24];
sprintf(buf, "%lu ms", ms);
tft.setTextFont(2);
tft.drawString(buf, W/2, H/2 + 18);
delay(350);
}
}
// ════════════════════════════════════════════════════════════════════
// TEST 3 — HSV GRADIENT
// ════════════════════════════════════════════════════════════════════
void testGradient() {
titleBar("HSV GRADIENT SWEEP");
for (int x = 0; x < W; x++) {
for (int y = 26; y < H; y++) {
float hue = (float)x * 360.0f / W;
float sat = 1.0f;
float val = 0.4f + 0.6f * (float)(y - 26) / (H - 26);
float H2 = hue / 60.0f;
int i = (int)H2;
float f = H2 - i;
uint8_t p = val * (1 - sat) * 255;
uint8_t q = val * (1 - f * sat) * 255;
uint8_t t2 = val * (1 - (1 - f) * sat) * 255;
uint8_t v = val * 255;
uint8_t r2, g2, b2;
switch (i % 6) {
case 0: r2=v;g2=t2;b2=p; break;
case 1: r2=q;g2=v;b2=p; break;
case 2: r2=p;g2=v;b2=t2; break;
case 3: r2=p;g2=q;b2=v; break;
case 4: r2=t2;g2=p;b2=v; break;
default:r2=v;g2=p;b2=q; break;
}
tft.drawPixel(x, y, tft.color565(r2, g2, b2));
}
}
waitTest();
}
// ════════════════════════════════════════════════════════════════════
// TEST 4 — LINE BURST
// ════════════════════════════════════════════════════════════════════
void testLines() {
tft.fillScreen(TFT_BLACK);
titleBar("LINE BURST — 360 LINES");
int cx = W / 2, cy = (H + 26) / 2;
int r = min(cx, cy - 26) - 2;
for (int angle = 0; angle < 360; angle += 2) {
float rad = angle * DEG_TO_RAD;
int x2 = cx + r * cos(rad);
int y2 = cy + r * sin(rad);
uint8_t hue = (uint8_t)(angle * 255 / 360);
float H2 = (float)angle / 60.0f;
int i = (int)H2 % 6;
float f = H2 - (int)H2;
uint8_t v = 255;
uint8_t p = 0;
uint8_t q = 255 * (1 - f);
uint8_t t2 = 255 * f;
uint8_t r2, g2, b2;
switch (i) {
case 0: r2=v;g2=t2;b2=p; break;
case 1: r2=q;g2=v;b2=p; break;
case 2: r2=p;g2=v;b2=t2; break;
case 3: r2=p;g2=q;b2=v; break;
case 4: r2=t2;g2=p;b2=v; break;
default:r2=v;g2=p;b2=q; break;
}
tft.drawLine(cx, cy, x2, y2, tft.color565(r2, g2, b2));
}
tft.fillCircle(cx, cy, 5, TFT_WHITE);
waitTest();
}
// ════════════════════════════════════════════════════════════════════
// TEST 5 — RECTANGLES
// ════════════════════════════════════════════════════════════════════
void testRects() {
tft.fillScreen(TFT_BLACK);
titleBar("FILLED RECTANGLES");
int cx = W/2, cy = (H+26)/2;
for (int i = 0; i < 50; i++) {
int w = W - i * 6;
int h = (H - 26) - i * 4;
if (w < 4 || h < 4) break;
tft.fillRect(cx-w/2, cy-h/2, w, h,
tft.color565(i*5, 255-i*5, (i*11)%255));
}
waitTest(SHORT_MS);
tft.fillScreen(TFT_BLACK);
titleBar("OUTLINE RECTANGLES");
for (int i = 0; i < 40; i++) {
int w = W - i * 7;
int h = (H - 26) - i * 5;
if (w < 4 || h < 4) break;
tft.drawRect(cx-w/2, cy-h/2, w, h,
tft.color565(0, (i*6)%255, 255-i*6));
}
waitTest(SHORT_MS);
}
// ════════════════════════════════════════════════════════════════════
// TEST 6 — CIRCLES
// ════════════════════════════════════════════════════════════════════
void testCircles() {
tft.fillScreen(TFT_BLACK);
titleBar("RANDOM FILLED CIRCLES");
for (int i = 0; i < 30; i++) {
int x = random(10, W-10);
int y = random(30, H-10);
int r = random(8, 40);
tft.fillCircle(x, y, r,
tft.color565(random(80,255), random(80,255), random(80,255)));
tft.drawCircle(x, y, r, TFT_WHITE);
}
waitTest(SHORT_MS);
tft.fillScreen(TFT_BLACK);
titleBar("CONCENTRIC CIRCLES");
int cx = W/2, cy = (H+26)/2;
for (int r = 2; r < 110; r += 4) {
float hue = r * 3.0f;
uint8_t rv = 127 + 127 * sin(hue * DEG_TO_RAD);
uint8_t gv = 127 + 127 * sin((hue+120) * DEG_TO_RAD);
uint8_t bv = 127 + 127 * sin((hue+240) * DEG_TO_RAD);
tft.drawCircle(cx, cy, r, tft.color565(rv, gv, bv));
}
waitTest();
}
// ════════════════════════════════════════════════════════════════════
// TEST 7 — TRIANGLES
// ════════════════════════════════════════════════════════════════════
void testTriangles() {
tft.fillScreen(TFT_BLACK);
titleBar("ROTATING TRIANGLES");
int cx = W/2, cy = (H+26)/2;
for (int i = 0; i < 22; i++) {
float r = 10 + i * 5;
float a1 = i * 0.3f, a2 = a1 + 2.094f, a3 = a2 + 2.094f;
tft.fillTriangle(
cx + r*cos(a1), cy + r*sin(a1),
cx + r*cos(a2), cy + r*sin(a2),
cx + r*cos(a3), cy + r*sin(a3),
tft.color565(i*12, 255-i*12, (i*10)%255)
);
tft.drawTriangle(
cx + r*cos(a1), cy + r*sin(a1),
cx + r*cos(a2), cy + r*sin(a2),
cx + r*cos(a3), cy + r*sin(a3),
TFT_WHITE
);
}
waitTest();
}
// ════════════════════════════════════════════════════════════════════
// TEST 8 — TEXT FONTS
// ════════════════════════════════════════════════════════════════════
void testText() {
tft.fillScreen(TFT_BLACK);
titleBar("TEXT & FONTS");
int y = 30;
tft.setTextDatum(TL_DATUM);
tft.setTextFont(2); tft.setTextColor(TFT_CYAN, TFT_BLACK);
tft.setCursor(6, y); tft.print("Font2: ABCDEFGHIJKLMNOPQRST"); y += 20;
tft.setTextFont(4); tft.setTextColor(TFT_GOLD, TFT_BLACK);
tft.setCursor(6, y); tft.print("Font4: 0123456"); y += 30;
tft.setTextFont(6); tft.setTextColor(TFT_WHITE, TFT_BLACK);
tft.setCursor(6, y); tft.print("09:47"); y += 52;
tft.setTextFont(7); tft.setTextColor(TFT_GREEN, TFT_BLACK);
tft.setCursor(6, y); tft.print("12:59"); y += 52;
tft.setTextFont(2); tft.setTextColor(TFT_ORANGE, TFT_BLACK);
tft.setCursor(6, y); tft.print("AI Centre Nandurbar | Arvind Patil");
waitTest();
// Font 8 demo
tft.fillScreen(TFT_BLACK);
titleBar("7-SEG FONT 8");
tft.setTextDatum(MC_DATUM);
tft.setTextFont(8); tft.setTextColor(TFT_GOLD, TFT_BLACK);
tft.drawString("88:88", W/2, H/2 + 8);
tft.setTextFont(2); tft.setTextColor(TFT_CYAN, TFT_BLACK);
tft.drawString("IST — INDIA STANDARD TIME", W/2, H - 16);
waitTest();
}
// ════════════════════════════════════════════════════════════════════
// TEST 9 — BOUNCING BALLS FPS
// ════════════════════════════════════════════════════════════════════
struct Ball { float x, y, vx, vy; uint8_t r; uint16_t c; };
#define N_BALLS 12
Ball balls[N_BALLS];
void testBalls() {
tft.fillScreen(TFT_BLACK);
titleBar("BOUNCING BALLS — FPS TEST");
for (int i = 0; i < N_BALLS; i++) {
balls[i] = {
(float)random(20, W-20), (float)random(40, H-20),
(float)random(10,30)/10.0f * (random(2)?1:-1),
(float)random(10,25)/10.0f * (random(2)?1:-1),
(uint8_t)random(8, 20),
tft.color565(random(80,255), random(80,255), random(80,255))
};
}
uint32_t frames = 0;
uint32_t t0 = millis();
uint32_t duration = 3000;
while (millis() - t0 < duration) {
// Erase old positions (overdraw)
for (int i = 0; i < N_BALLS; i++)
tft.fillCircle(balls[i].x, balls[i].y, balls[i].r + 1, TFT_BLACK);
// Update physics
for (int i = 0; i < N_BALLS; i++) {
balls[i].x += balls[i].vx;
balls[i].y += balls[i].vy;
if (balls[i].x < balls[i].r || balls[i].x > W - balls[i].r)
balls[i].vx *= -1;
if (balls[i].y < 28 + balls[i].r || balls[i].y > H - balls[i].r)
balls[i].vy *= -1;
}
// Draw
for (int i = 0; i < N_BALLS; i++) {
tft.fillCircle(balls[i].x, balls[i].y, balls[i].r, balls[i].c);
tft.drawCircle(balls[i].x, balls[i].y, balls[i].r, TFT_WHITE);
}
frames++;
float elapsed = (millis() - t0) / 1000.0f;
fps_result = elapsed > 0 ? frames / elapsed : 0;
// Live FPS display
tft.setTextFont(2);
tft.setTextColor(TFT_WHITE, TFT_NAVY);
char buf[32];
sprintf(buf, "%.1f FPS | %lu frames", fps_result, frames);
tft.fillRect(W/2 - 80, 4, 200, 16, TFT_NAVY);
tft.setCursor(W/2 - 78, 5);
tft.print(buf);
}
// Result banner
tft.fillRect(0, H-28, W, 28, TFT_BLACK);
tft.setTextFont(4); tft.setTextDatum(MC_DATUM);
tft.setTextColor(TFT_GREEN, TFT_BLACK);
char result[40];
sprintf(result, "%.1f FPS", fps_result);
tft.drawString(result, W/2, H - 13);
delay(2500);
}
// ════════════════════════════════════════════════════════════════════
// TEST 10 — ROUNDED RECTS + PROGRESS BAR
// ════════════════════════════════════════════════════════════════════
void testRoundRects() {
tft.fillScreen(TFT_BLACK);
titleBar("ROUNDED RECTS + PROGRESS BAR");
int cx = W/2, cy = (H+26)/2 - 20;
for (int i = 0; i < 25; i++) {
int w = W - i*10 - 4;
int h = (H-60) - i*6;
if (w < 10 || h < 10) break;
tft.fillRoundRect(cx-w/2, cy-h/2, w, h, 8,
tft.color565(i*10, 80, 255-i*10));
tft.drawRoundRect(cx-w/2, cy-h/2, w, h, 8, TFT_WHITE);
}
// Animated progress bar
int bx=20, by=H-36, bw=W-40, bh=18;
tft.drawRoundRect(bx, by, bw, bh, 4, TFT_WHITE);
for (int p = 0; p <= 100; p += 2) {
int fw = (bw - 4) * p / 100;
tft.fillRoundRect(bx+2, by+2, fw, bh-4, 3,
tft.color565(p*2, 255-p*2, 0));
// Percentage label
tft.fillRect(bx+bw/2-14, by-16, 28, 14, TFT_BLACK);
tft.setTextFont(1); tft.setTextDatum(MC_DATUM);
tft.setTextColor(TFT_WHITE, TFT_BLACK);
char pct[8]; sprintf(pct, "%d%%", p);
tft.drawString(pct, bx + bw/2, by - 9);
delay(8);
}
waitTest(SHORT_MS);
}
// ════════════════════════════════════════════════════════════════════
// TEST 11 — PIXEL BENCHMARK
// ════════════════════════════════════════════════════════════════════
void testPixels() {
tft.fillScreen(TFT_BLACK);
titleBar("PIXEL BENCHMARK");
uint32_t t0 = millis();
uint32_t count = 0;
for (int y = 28; y < H; y++) {
for (int x = 0; x < W; x++) {
tft.drawPixel(x, y, tft.color565(x, y, (x+y)&0xFF));
count++;
}
}
uint32_t ms = millis() - t0;
uint32_t pps = count * 1000 / ms;
tft.setTextFont(2); tft.setTextColor(TFT_WHITE, TFT_NAVY);
char buf[56];
sprintf(buf, "%lu px | %lu ms | %lu px/s", count, ms, pps);
tft.fillRect(0, 0, W, 22, TFT_NAVY);
tft.setCursor(6, 5);
tft.print(buf);
waitTest();
}
// ════════════════════════════════════════════════════════════════════
// TEST 12 — SUMMARY SCREEN
// ════════════════════════════════════════════════════════════════════
void testSummary() {
tft.fillScreen(TFT_BLACK);
// Gradient header
for (int x = 0; x < W; x++) {
uint16_t col = tft.color565(x/2, 0, 255 - x/2);
tft.drawFastVLine(x, 0, 24, col);
}
tft.setTextFont(2); tft.setTextDatum(MC_DATUM);
tft.setTextColor(TFT_WHITE);
tft.drawString("GRAPHICS TEST COMPLETE", W/2, 12);
struct Row { const char* label; const char* val; uint16_t col; };
Row rows[] = {
{"Display", "ILI9341 320x240", TFT_CYAN},
{"Board", "ESP32-2432S028 CYD", TFT_GOLD},
{"Library", "TFT_eSPI Bodmer", TFT_GREEN},
{"Setup", "Embedded (no edit)", 0x07E0},
{"SPI Freq", "55 MHz", TFT_CYAN},
{"Tests", "11 PASSED", TFT_ORANGE},
{"FPS", "", 0xFC18},
{"Author", "Arvind Patil", TFT_GOLD},
{"Org", "AI Centre Nandurbar",TFT_CYAN},
};
char fpsbuf[16];
sprintf(fpsbuf, "%.1f FPS", fps_result);
rows[6].val = fpsbuf;
tft.setTextFont(2); tft.setTextDatum(TL_DATUM);
int y = 34;
for (auto& ro : rows) {
tft.setTextColor(0x4A69, TFT_BLACK);
tft.setCursor(10, y); tft.print(ro.label);
tft.setTextColor(ro.col, TFT_BLACK);
tft.setCursor(130, y); tft.print(ro.val);
tft.drawFastHLine(8, y+17, W-16, 0x1082);
y += 20;
}
}
// ════════════════════════════════════════════════════════════════════
// SETUP
// ════════════════════════════════════════════════════════════════════
void setup() {
Serial.begin(115200);
delay(300);
// RGB LED
pinMode(LED_R, OUTPUT);
pinMode(LED_G, OUTPUT);
pinMode(LED_B, OUTPUT);
ledColor(false, false, true); // Blue = booting
// Backlight ON
pinMode(TFT_BL, OUTPUT);
digitalWrite(TFT_BL, HIGH);
// TFT Init
tft.init();
tft.setRotation(1); // Landscape 320×240
tft.fillScreen(TFT_BLACK);
Serial.println("=== CYD TFT Graphics Test ===");
Serial.println("USER_SETUP_LOADED — library config embedded");
Serial.printf("Display: %d x %d\n", tft.width(), tft.height());
Serial.println("AI Centre Nandurbar | Arvind Patil");
ledColor(false, true, false); // Green = ready
}
// ════════════════════════════════════════════════════════════════════
// LOOP — सर्व tests एकामागे एक, loop होत राहतो
// ════════════════════════════════════════════════════════════════════
void loop() {
ledColor(true, false, false); // Red = running
Serial.println("\n--- All Tests Starting ---");
testSplash();
testColorFill();
testGradient();
testLines();
testRects();
testCircles();
testTriangles();
testText();
testBalls();
testRoundRects();
testPixels();
testSummary();
ledColor(false, true, false); // Green = done
Serial.printf("All tests done! FPS: %.1f\n", fps_result);
delay(5000);
}
Loading
esp32-2432s028r
esp32-2432s028r