// =============================================================================
// PROJET HOME HUB - PARTIE 1 : Écran et Joystick
// =============================================================================
// Ce code initialise un écran TFT ILI9341 avec tactile capacitif et un joystick
// analogique sur une carte Arduino Mega. Il affiche un message de bienvenue
// sur l'écran et une représentation graphique du joystick qui réagit à ses mouvements.
//
// Objectif pour les débutants :
// - Comprendre l'inclusion des bibliothèques.
// - Définir les broches matérielles dans le code.
// - Initialiser un écran SPI.
// - Afficher du texte sur un écran TFT.
// - Lire des entrées analogiques (joystick X/Y) et numériques (bouton joystick).
// - Afficher des données dynamiques graphiquement sur l'écran TFT.
// - Optimiser l'affichage pour éviter le scintillement.
// =============================================================================
// --- 1. Inclusion des Bibliothèques ---
#include <Adafruit_GFX.h>
#include <Adafruit_ILI9341.h>
#include <Wire.h>
// --- 2. Définition des Broches de Connexion ---
#define TFT_CS 10
#define TFT_DC 9
#define TFT_RST 8
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
#define TOUCH_SDA 20
#define TOUCH_SCL 21
#define JOY_VERT_PIN A1
#define JOY_HORZ_PIN A0
#define JOY_SEL_PIN 2
// --- Constantes pour le graphique du joystick ---
// Centre de la zone graphique du joystick sur l'écran
#define JOY_GRAPHIC_CENTER_X (tft.width() / 2) // Centre horizontal de l'écran
#define JOY_GRAPHIC_CENTER_Y (tft.height() / 2) // Centre vertical de l'écran
// Rayon du cercle de base du joystick
#define JOY_BASE_RADIUS 60
// Rayon du "manche" du joystick (le cercle qui bouge)
#define JOY_HANDLE_RADIUS 15
// Plage de mouvement maximale du manche à l'intérieur de la base
#define JOY_MOVEMENT_RANGE (JOY_BASE_RADIUS - JOY_HANDLE_RADIUS)
// Variables globales pour stocker la position précédente du manche
// et l'état du bouton pour éviter de redessiner inutilement.
static int prevHandleX = -1;
static int prevHandleY = -1;
static int prevJoyButtonState = -1; // -1 pour l'état initial, 0 pour PRESSÉ, 1 pour RELACHÉ
// --- 3. La Fonction setup() : Préparation et Initialisation ---
void setup() {
tft.begin();
tft.setRotation(1); // Orientation paysage
tft.fillScreen(ILI9341_BLACK); // Fond noir
pinMode(JOY_SEL_PIN, INPUT_PULLUP);
// Affichage du message de bienvenue
tft.setCursor(0, 0);
tft.setTextColor(ILI9341_WHITE);
tft.setTextSize(2);
tft.print("Bienvenue sur le");
tft.setCursor(0, 20);
tft.print("Home Hub !");
// Dessiner le cercle de base du joystick (statique)
tft.drawCircle(JOY_GRAPHIC_CENTER_X, JOY_GRAPHIC_CENTER_Y, JOY_BASE_RADIUS, ILI9341_DARKGREY);
// Dessiner un deuxième cercle pour épaissir le contour
tft.drawCircle(JOY_GRAPHIC_CENTER_X, JOY_GRAPHIC_CENTER_Y, JOY_BASE_RADIUS - 1, ILI9341_DARKGREY);
// Ajouter une étiquette pour le graphique
tft.setCursor(JOY_GRAPHIC_CENTER_X - 50, JOY_GRAPHIC_CENTER_Y + JOY_BASE_RADIUS + 10);
tft.setTextColor(ILI9341_WHITE);
tft.setTextSize(1);
tft.print("Graphique Joystick");
}
// --- 4. La Fonction loop() : Le Cœur du Programme ---
void loop() {
// --- Lecture des valeurs du Joystick ---
int joyX = analogRead(JOY_HORZ_PIN);
int joyY = analogRead(JOY_VERT_PIN);
int joyButtonState = digitalRead(JOY_SEL_PIN);
// --- Mappage des valeurs du joystick aux coordonnées graphiques ---
// On mappe les valeurs du joystick (0-1023) à une plage de mouvement
// relative au centre du graphique, en tenant compte du rayon du manche.
int currentHandleX = map(joyX, 0, 1023, JOY_GRAPHIC_CENTER_X - JOY_MOVEMENT_RANGE, JOY_GRAPHIC_CENTER_X + JOY_MOVEMENT_RANGE);
int currentHandleY = map(joyY, 0, 1023, JOY_GRAPHIC_CENTER_Y - JOY_MOVEMENT_RANGE, JOY_GRAPHIC_CENTER_Y + JOY_MOVEMENT_RANGE);
// --- Mise à jour de l'affichage du joystick ---
// On ne redessine que si la position du manche ou l'état du bouton a changé.
if (currentHandleX != prevHandleX || currentHandleY != prevHandleY || joyButtonState != prevJoyButtonState) {
// Effacer le manche précédent (dessiner un cercle noir à son ancienne position)
if (prevHandleX != -1) { // S'assurer que ce n'est pas le tout premier dessin
tft.fillCircle(prevHandleX, prevHandleY, JOY_HANDLE_RADIUS, ILI9341_BLACK);
}
// Déterminer la couleur actuelle du manche en fonction de l'état du bouton
uint16_t handleColor = ILI9341_BLUE; // Couleur par défaut (bleu)
if (joyButtonState == LOW) { // Si le bouton est pressé
handleColor = ILI9341_RED; // Changer la couleur en rouge
}
// Dessiner le nouveau manche à sa position actuelle avec la couleur appropriée
tft.fillCircle(currentHandleX, currentHandleY, JOY_HANDLE_RADIUS, handleColor);
// Mettre à jour les positions et l'état précédents pour la prochaine itération
prevHandleX = currentHandleX;
prevHandleY = currentHandleY;
prevJoyButtonState = joyButtonState;
}
// Petite pause pour ne pas surcharger le processeur et éviter le scintillement.
// La fréquence de rafraîchissement est suffisamment rapide pour une bonne fluidité.
delay(10);
}