#include <Adafruit_GFX.h>          // Inclut la bibliothèque graphique Adafruit GFX pour la gestion des graphiques
#include <Adafruit_ILI9341.h>      // Inclut la bibliothèque Adafruit ILI9341 pour la gestion de l'écran TFT
#include <SPI.h>                   // Inclut la bibliothèque SPI pour la communication avec l'écran et d'autres périphériques
#include <math.h>                  // Inclut la bibliothèque mathématique pour les fonctions trigonométriques

#define TFT_DC 2                   // Définit la broche pour le signal de commande (D/C) de l'écran TFT
#define TFT_CS 15                  // Définit la broche pour la sélection du chipset (CS) de l'écran TFT
#define TFT_WIDTH 240
#define TFT_HEIGHT 320

Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC);  // Crée un objet Adafruit_ILI9341 avec les broches définies ci-dessus

void setup() {
  tft.begin();                                           // Initialise la communication avec l'écran TFT
  tft.setRotation(0);                                    // Définit l'orientation de l'écran (0 signifie pas de rotation)
  tft.fillScreen(ILI9341_BLACK);                         // Remplit l'écran avec la couleur noire
  tft.setTextColor(ILI9341_WHITE);                       // Définit la couleur du texte en blanc
  tft.setTextSize(2);                                    // Définit la taille du texte comme 2 (relativement grande)
}

void loop() {
  // Boucle infinie pour afficher et modifier les signaux en continu
  while (true) {
    drawAxes();                                          // Dessine les axes X et Y
    
    // Affiche le signal sin(x) sur 2π
    drawSinus();                                         // Dessine le signal sin(x)
    
    // Attend avant d'effacer et remplacer par le signal cos(x)
    delay(2000);
    drawAxes();                                          // Dessine les axes X et Y

    
    // Efface et remplace par le signal cos(x)
    eraseAndReplaceWithCosinus();                        // Efface progressivement une période de sin(x) et la remplace par le signal cos(x)

    // Efface l'écran pour préparer l'affichage du prochain signal
    tft.fillRect(0, 0, tft.width(), tft.height(), ILI9341_BLACK);  // Remplit l'écran avec la couleur noire
  }
}

// Dessine les axes X et Y
void drawAxes() {
  // Dessine l'axe X (horizontal)
  tft.drawLine(0, TFT_HEIGHT / 2, TFT_WIDTH - 1, TFT_HEIGHT / 2, ILI9341_WHITE);    // Dessine une ligne horizontale bleue
  
  // Dessine l'axe Y (vertical)
  tft.drawLine(TFT_WIDTH / 2, 0, TFT_WIDTH / 2, TFT_HEIGHT - 1, ILI9341_WHITE);     // Dessine une ligne verticale blanche
}

// Dessine le signal sin(x)
void drawSinus() {
  float y;
  for (int x = 0; x < TFT_WIDTH; x++) {
    // Calcul de l'ordonnée y en fonction de sin(x)
    y = sin(2 * PI * x / TFT_WIDTH) * (TFT_HEIGHT / 4) + TFT_HEIGHT / 2;    // Calcule la position y du signal sin(x)
    
    // Dessine un pixel à la position (x, y) avec la couleur verte
    tft.drawPixel(x, y, ILI9341_GREEN);                    // Dessine un pixel vert
  }
}

// Efface et remplace progressivement une période de sin(x) par le signal cos(x)
void eraseAndReplaceWithCosinus() {
  float ySin, yCos;
  // Parcourt la largeur de l'écran en plusieurs étapes
  for (int x = 0; x < TFT_WIDTH; x += TFT_WIDTH / 16) {
    // Parcourt un quart de période de sin(x)
    for (int i = 0; i < TFT_WIDTH / 4; i++) {
      // Efface le signal sin(x) sur un quart de période
      ySin = sin(2 * PI * (x + i) / TFT_WIDTH) * (TFT_HEIGHT / 4) + TFT_HEIGHT / 2;    // Calcule la position y du signal sin(x)
      tft.drawPixel(x + i, ySin, ILI9341_BLACK);          // Efface le pixel en noir
      
      // Dessine le signal cos(x) sur le même quart de période
      yCos = cos(2 * PI * (x + i) / TFT_WIDTH) * (TFT_HEIGHT / 4) + TFT_HEIGHT / 2;    // Calcule la position y du signal cos(x)
      tft.drawPixel(x + i, yCos, ILI9341_RED);            // Dessine le pixel en rouge
    }
    // Attend un court instant avant de passer au prochain quart de période
    delay(800);                                            // Attend 800 ms
  }
}
esp:0
esp:2
esp:4
esp:5
esp:12
esp:13
esp:14
esp:15
esp:16
esp:17
esp:18
esp:19
esp:21
esp:22
esp:23
esp:25
esp:26
esp:27
esp:32
esp:33
esp:34
esp:35
esp:3V3
esp:EN
esp:VP
esp:VN
esp:GND.1
esp:D2
esp:D3
esp:CMD
esp:5V
esp:GND.2
esp:TX
esp:RX
esp:GND.3
esp:D1
esp:D0
esp:CLK
lcd2:VCC
lcd2:GND
lcd2:CS
lcd2:RST
lcd2:D/C
lcd2:MOSI
lcd2:SCK
lcd2:LED
lcd2:MISO