Programme Test tactile pour ESP32 TFT LCD 3,5 pouces ST7796U
Description :
Ce code est un programme complet pour une application de dessin tactile (Paint) destinée à une Carte de développement ESP32 ESP-WROOM-32, Écran tactile résistif TFT LCD 3,5 pouces, module 320×480 ST7796U
Le projet transforme l’ESP32 en une tablette graphique miniature.
Prérequis :
Version IDE :
- Arduino IDE 2.3.7
Bibliothèque :
- Arduino_GFX_Library.h ( version: 1.4 par Moon On Our Nation)
- XPT2046_Touchscreen.h ( version: 1.4 par Paul Stoffregen)
Vidéo de démonstration :
NA
Schéma de câblage :

Code :
#include <Arduino.h>
#include <Arduino_GFX_Library.h>
#include <XPT2046_Touchscreen.h>
#include <SPI.h>
// ============================================================================
// CONFIGURATION DE L'ÉCRAN (Broches SPI de la carte)
// ============================================================================
#define TFT_BL 27 // Broche du rétroéclairage (Backlight)
#define TFT_SCLK 14 // Horloge SPI partagée (Clock)
#define TFT_MOSI 13 // Sortie données SPI partagée (Master Out Slave In)
#define TFT_MISO 12 // Entrée données SPI partagée (Master In Slave Out)
#define TFT_CS 15 // Sélection de la puce Écran (Chip Select)
#define TFT_DC 2 // Broche Données/Commandes pour l'écran
#define TFT_RST -1 // Broche de Reset (non connectée sur ce modèle, gérée en interne)
// Initialisation du bus de données matériel de l'ESP32 pour l'écran
Arduino_DataBus *bus = new Arduino_ESP32SPI(TFT_DC, TFT_CS, TFT_SCLK, TFT_MOSI, TFT_MISO);
// Initialisation du pilote de l'écran ST7796 (Résolution 480x320)
Arduino_GFX *gfx = new Arduino_ST7796(bus, TFT_RST, 0 /* rotation */, false /* IPS */);
// ============================================================================
// CONFIGURATION DU TACTILE VALIDÉ (CS = 33)
// ============================================================================
#define TOUCH_CS 33 // Broche de sélection de la puce tactile (validée par le scanner)
#define TOUCH_IRQ 255 // Désactivation de la broche IRQ pour forcer la lecture directe (Polling)
// Initialisation du contrôleur tactile XPT2046
XPT2046_Touchscreen touch(TOUCH_CS, TOUCH_IRQ);
// Variables globales pour stocker la position du doigt sur l'écran
int16_t touchX = 0;
int16_t touchY = 0;
// Variable pour mémoriser la couleur active du pinceau (Vert par défaut)
uint16_t currentBrushColor = GREEN;
// Structure pour définir les zones tactiles des boutons de la palette de couleurs
struct ColorButton {
int16_t x; // Position X du bouton
int16_t y; // Position Y du bouton
int16_t w; // Largeur du bouton
int16_t h; // Hauteur du bouton
uint16_t color; // Couleur associée
};
// Définition de notre palette de 4 couleurs positionnée en haut à droite
ColorButton palette[] = {
{260, 25, 40, 40, GREEN},
{310, 25, 40, 40, BLUE},
{360, 25, 40, 40, ORANGE},
{411, 25, 40, 40, WHITE}
};
// ============================================================================
// FONCTION DE LECTURE TACTILE (Ultra-permissive)
// ============================================================================
bool checkTouch() {
// Récupération des données brutes de la puce tactile
TS_Point p = touch.getPoint();
// Si p.z > 0, cela signifie qu'une pression physique est exercée sur la dalle
if (p.x > 0 && p.x < 4095 && p.z > 0) {
// Calibrage validé : conversion des coordonnées brutes du XPT2046 (ex: 250 à 3800)
// vers la grille de pixels réels de notre écran en mode paysage (480x320)
touchX = map(p.x, 3800, 250, 0, 480);
touchY = map(p.y, 250, 3800, 0, 320);
return true; // Un appui valide est détecté
}
return false; // Aucun appui en cours
}
// ============================================================================
// DESSIN DE L'INTERFACE GRAPHIQUE AMÉLIORÉE
// ============================================================================
void drawInterface() {
// On efface l'écran complet en le mettant en noir
gfx->fillScreen(BLACK);
// --- Zone de titre ---
gfx->setTextColor(WHITE);
gfx->setTextSize(3);
gfx->setCursor(20, 20);
gfx->println("ESP32 Test1");
gfx->setTextSize(1);
gfx->setTextColor(DARKGREY);
gfx->setCursor(20, 50);
gfx->println("Version 3.5\" ST7796 + XPT2046");
// --- Dessin de la Palette de Couleurs ---
for (int i = 0; i < 4; i++) {
// Dessin du carré de couleur plein
gfx->fillRect(palette[i].x, palette[i].y, palette[i].w, palette[i].h, palette[i].color);
// Petit cadre gris discret autour de chaque carré pour la finition
gfx->drawRect(palette[i].x, palette[i].y, palette[i].w, palette[i].h, LIGHTGREY);
// Si cette couleur est celle actuellement sélectionnée, on ajoute un contour blanc épais
if (palette[i].color == currentBrushColor) {
gfx->drawRect(palette[i].x - 2, palette[i].y - 2, palette[i].w + 4, palette[i].h + 4, WHITE);
}
}
// --- Séparateur visuel (Ligne de démarcation de la zone de dessin) ---
gfx->drawFastHLine(0, 85, 480, DARKGREY);
// --- Bouton "EFFACER" Moderne (Style Flat-Design avec bordure) ---
// Bordure extérieure gris clair pour le relief
gfx->fillRoundRect(138, 248, 204, 54, 12, LIGHTGREY);
// Corps du bouton rouge
gfx->fillRoundRect(140, 250, 200, 50, 10, RED);
// Texte centré dans le bouton
gfx->setTextColor(WHITE);
gfx->setTextSize(2);
gfx->setCursor(195, 266);
gfx->println("EFFACER");
}
// ============================================================================
// INITIALISATION (SETUP)
// ============================================================================
void setup() {
// Démarrage de la communication série pour le débogage PC
Serial.begin(115200);
delay(500);
Serial.println("\n=== Initialisation Interface Graphique (TOUCH_CS:33) ===");
// Configuration et activation immédiate du rétroéclairage de l'écran
pinMode(TFT_BL, OUTPUT);
digitalWrite(TFT_BL, HIGH);
// Initialisation de la bibliothèque d'affichage Arduino_GFX
if (!gfx->begin()) {
Serial.println("Erreur fatale : Impossible d'initialiser l'ecran !");
while (1); // Blocage de sécurité
}
gfx->setRotation(1); // Passage de l'écran en mode Paysage (horizontal)
Serial.println("Ecran LCD configure.");
// Configuration matérielle des broches pour le bus SPI partagé
SPI.begin(TFT_SCLK, TFT_MISO, TFT_MOSI);
// Démarrage du contrôleur tactile XPT2046
touch.begin();
touch.setRotation(1); // On aligne la rotation du tactile sur celle de l'écran
Serial.println("Dalle tactile prete.");
// Premier affichage de notre interface complète
drawInterface();
}
// ============================================================================
// BOUCLE PRINCIPALE (LOOP)
// ============================================================================
void loop() {
// On interroge le tactile à chaque cycle
if (checkTouch()) {
// --- CAS 1 : Clic sur le bouton rouge "EFFACER" ---
if (touchX >= 140 && touchX <= 340 && touchY >= 250 && touchY <= 300) {
Serial.println("Commande : Nettoyage de l'ecran");
drawInterface(); // Réinitialise l'affichage complet
delay(250); // Anti-rebond temporel pour éviter les déclenchements multiples
}
// --- CAS 2 : Clic dans la zone supérieure (Changement de couleur de la palette) ---
else if (touchY < 85) {
// On parcourt nos 4 boutons de couleur pour voir si le clic est dedans
for (int i = 0; i < 4; i++) {
if (touchX >= palette[i].x && touchX <= (palette[i].x + palette[i].w) &&
touchY >= palette[i].y && touchY <= (palette[i].y + palette[i].h)) {
// Si on change de couleur
if (currentBrushColor != palette[i].color) {
currentBrushColor = palette[i].color; // Met à jour la couleur active
Serial.printf("Changement pinceau couleur. Index : %d\n", i);
drawInterface(); // Redessine l'interface pour mettre à jour le cadre blanc de sélection
delay(200); // Anti-rebond
}
}
}
}
// --- CAS 3 : Dessin dans la zone blanche utile (sous la ligne séparatrice) ---
else if (touchY > 90 && touchY < 240 && touchX >= 0 && touchX <= 480) {
// Dessine un point plein de taille '3' avec la couleur actuellement sélectionnée
gfx->fillCircle(touchX, touchY, 3, currentBrushColor);
}
}
// Pause de 5 millisecondes pour laisser l'ESP32 respirer et garder un tracé fluide serré
delay(5);
}
