
  /* Ce programme est prévu pour ajouter à P16 les routines pour envoyer les valeurs des
     échantillons ainsi que les paramètres de capture vers la voie série du
     dialogue par la ligne USB.
   
   Naturellement les branchements sont strictement identiques à ceux des démonstrateurs
   qui précèdent.
   
   * La durée pour le Clic Long a été passée en paramètre etaugmentée à 0,8 seconde.
   
                  Utilisation :
                  =============
   • MENU USB :  (Appel avec le Clic DROIT dans le MENU de BASE.)
     ----------  >>> Activer le Moniteur de l'IDE en 57600baud.
     * L'écran OLED affiche le texte "Exporte sur USB :" et LED triple s'allume en rouge
       durant environ une seconde. Dans la fenêtre du Moniteur les caractéristiques de la
       saisie ainsi que les valeurs des échantillons sont listés avec séparation des
       fenêtres individuelles. Chaque blos a ses attributs de saisie.
              
   • MENU du RESET :  (Appel avec une touche activée durant le redémarrage.)
     ---------------
     Reste inchangé mis à part le comportement du B.P. de DROITE qui ne crée plus
     de façon inconditionnelle une trace fictive qui simule une sinusoïde amortie
     mais ouvre un Sous menu "generation du Signal." avec trois options. dans ce
     sous MENU la LED tricolore s'illumine en "orange". Les options sont :
     * HAUT : Simule la sinusoïde amortie de l'ancien comportement.
     * BAS : Génère quatre traces individuelles avec des conditions simulées de
             de capture différentes. le programe génère :
             Fenêtre 1 : Une sinusoïde périodique,
             Fenêtre 2 : Une dent de scie montante sans composante continue,
             Fenêtre 3 : Une dent de scie descendante avec composante continue,
             Fenêtre 4 : Un signal triangulaire avec composante continue.
     * GAUCHE : Génère un signal BINAIRE série de type TTL.

             
Compilateur v1.7.9 :                      PGM                 RAM dynamique
Avant modification :                20136 Octets (65%)       985 Octets (48%)
Après exportation sur USB :         20892 Octets (68%)      986 Octets (48%)
Ajout de lagénération des traces :  21902 Octets (71%)      1018 Octets (49%) */

#include "U8glib.h"
U8GLIB_SH1106_128X64 u8g(U8G_I2C_OPT_NONE);  // Usage de la ligne I2C (Two Wire Interface)

//--------------------- Définition des broches d'E/S ------------------------
#define Jaune 2
#define Rouge 3
#define BUZZER 4
#define Verte 5
#define Trp_R 6
#define Trp_V 7
#define Trp_B 8
#define Signal_Etalon 9

#define LED_Arduino 13  // D13 pour surveiller la boucle de base.
#define A0 14  // A0 : Entrée potentiomètre.
#define A3 17  // A3 : Entrée voltmètre.
#define BP_A6 20        // Entrée analogique A6 pour tester Le BP Gauche et le BP Droit.
#define BP_A7 21        // Entrée analogique A7 pour tester Le BP Haut et le BP BAS.

//------------------------ Constantes du programme --------------------------
#define Version "03/12/2023" //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#define Vitesse_USB 57600  //@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
#define Debut_Hexadecimal 538 // Adresse de fin des textes pour du listage en HEXADECIMAL
#define NB_tests_antirebonds 50 // Nombre de tests de stabilisation du B.P. @@@@@@@@@@@@@
#define T_pour_Long 800 // temporisation pour clic long. @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

#define HAUT 2
#define OUI 2
#define BAS 1
#define NON 1
#define GAUCHE 3
#define DROITE 4

//------------------------- Variables du programme --------------------------
boolean Automatique, Clic_long, Front_Montant, Grille, Libre, Mode_CAN, Mode_Fenetre,
     Seuil, Texte, Trace_pleine;
byte Gain, Gain_1, Gain_2, Gain_3, Gain_4, I_BdT, I_BdT_1, I_BdT_2, I_BdT_3, I_BdT_4,
     Num_Fenetre, Touche, U_Synchronisation;
char Caractere;
int BdT, Debut, Grandeur, PTR, SAV_A6, SAV_A7;
long Total, Valeur_totale; // Pour calculer la valeur efficace.
float Valeur; // Valeur de la tension mesurée.

byte TRACE [476]; // Graphe de 119 de large x 4 fenêtres.
  int Valeurs_BT[8] {1, 53, 301, 714, 1540, 4020, 8152, 16380};
  // 16380 est la plus grande valeur acceptable par l'instruction delayMicroseconds.

void setup()  {
  Serial.begin(Vitesse_USB);
  u8g.setFont(u8g_font_6x10); // Polices de 4x6 pixels.
  pinMode(LED_Arduino,OUTPUT); pinMode(Signal_Etalon,OUTPUT);
  pinMode(Jaune,OUTPUT); digitalWrite(Jaune,LOW); pinMode(Rouge,OUTPUT); digitalWrite(Rouge,LOW);
  pinMode(BUZZER,OUTPUT); digitalWrite(BUZZER,LOW); pinMode(Verte,OUTPUT); digitalWrite(Verte,LOW);
  pinMode(Trp_R,OUTPUT); pinMode(Trp_V,OUTPUT); pinMode(Trp_B,OUTPUT); Eteindre_LED_Triple();
  //----------- Génération permanente du signal de test ------------
  analogWrite(Signal_Etalon,138); // Fréquence 490Hz et rapport cyclique 50%.
  //------------- Option sur RESET si un BP est activé -------------
  Mode_Fenetre = false; Tester_le_BP(); if (Touche > 0) Menu_RESET();
  // Ci-avant Mode_Fenetre doit être initialisé avant le Menu_RESET pour ne pas modifier
  // l'état de ce booléen qui peut être repositionné par la fonction du Menu_RESET.
  //----------------- Initialisation des variables -----------------
  Front_Montant = true; Gain = 2; Grille = true; BdT = 0; Mode_CAN = false;
  Num_Fenetre = 1; Seuil = false; Texte = true; Trace_pleine = true;
  if (Lire_Octet_EEPROM(538)) Affiche_la_version_du_logiciel();}

void loop() {
  Aff_MENU_de_BASE();
  digitalWrite(LED_Arduino,HIGH); delay(1); digitalWrite(LED_Arduino,LOW);
  Tester_le_BP(); if (Touche > 0) Gerer_le_MENU_de_BASE();}

//==================== Routines pour la gestion de l'EEPROM ====================
byte Lire_Octet_EEPROM(int PTR) {
  return eeprom_read_byte((unsigned char *) PTR);}
  
byte Ecrire_Octet_EEPROM(int PTR, byte OCTET) {
  eeprom_write_byte((unsigned char*) PTR,OCTET);}

void Aff_TEXTE_EEPROM(int PTR, byte Longueur) {
    for (byte I=0; I<Longueur; I++) {u8g.print(char(Lire_Octet_EEPROM(PTR))); PTR++;};}

//======================== Procédures de servitude =============================

// NOTE : Bien que u8g.print(' '); soit unilisée à plusieurs reprises, remplacer
//        chaque instruction  par un appel à une procédure n'est pas rentable.

void Delai_1S() {delay(1000);}
     
void Eteindre_LED_Triple() {
  digitalWrite(Trp_R,LOW); digitalWrite(Trp_V,LOW); digitalWrite(Trp_B,LOW);}

void Bruiteur (byte Duree) {
  digitalWrite(BUZZER, HIGH); delay(Duree);digitalWrite(BUZZER, LOW);}

void BIP() {Bruiteur(150);}

void Gere_stabilisation_et_duree() {
  byte COMPTEUR; unsigned long Horloge_actuelle;
  Bruiteur(10); // Bip court.
  Horloge_actuelle = millis(); Clic_long = false; COMPTEUR = 0;
  //----------------------- Attendre le relâcher ---------------------- 
  while (COMPTEUR < NB_tests_antirebonds) {
         COMPTEUR++; // Tant que l'un des BP est activé le compteur est maintenu à zéro :
         SAV_A6 = analogRead(BP_A6); SAV_A7 = analogRead(BP_A7);
         if (SAV_A6 < 243 || SAV_A6 > 707 || SAV_A7 < 242 || SAV_A7 > 708) COMPTEUR = 0;
  //-------------------------------------------------------------------
  if ((millis() - Horloge_actuelle) > T_pour_Long) Clic_long = true;
  if (Clic_long) digitalWrite(Jaune,HIGH);}
  digitalWrite(Jaune,LOW);}

void Tester_le_BP() {
  boolean BP_actif = false; Touche = 0;
  SAV_A6 = analogRead(BP_A6); if (SAV_A6 < 243) {
                                  Touche = DROITE; BP_actif = true;}
                              if (SAV_A6 > 707) {
                                  Touche = HAUT; BP_actif = true;}
  SAV_A7 = analogRead(BP_A7); if (SAV_A7 < 242) {
                                  Touche = BAS; BP_actif = true;}
                              if (SAV_A7 > 708) {
                                  Touche = GAUCHE; BP_actif = true;}
  // ---------- Si le B.P. est cliqué alors il est traité  ---------- 
  if (BP_actif) Gere_stabilisation_et_duree();}

void Attendre_un_BP_sans_le_Bleu() {Touche = 0; while (Touche == 0) Tester_le_BP();}

void Attendre_un_BP() {
  digitalWrite(Trp_B,HIGH); Attendre_un_BP_sans_le_Bleu(); digitalWrite(Trp_B,LOW);}

void Point() {u8g.print('.');}

void Aff_NON() {Aff_TEXTE_EEPROM(168,3);} // "NON"

void Aff_OUI() {Aff_TEXTE_EEPROM(165,3);} // "OUI"

void Aff_Pas_de_TRACE() {Aff_TEXTE_EEPROM(210,14);} // "Pas de TRACE !"

void Aff_HAUT_deux_points_espace() {Aff_TEXTE_EEPROM(13,7);} // "HAUT : "

void DROITE_deux_points_espace() {Aff_TEXTE_EEPROM(62,9);} // "DROITE : "

void DROITE_deux_points_espace_Sortie_point() {
  DROITE_deux_points_espace(); Aff_TEXTE_EEPROM(156,7);} // "DROITE : Sortie."

void Aff_HAUT_deux_points_espace_OUI_Point() {
  Aff_HAUT_deux_points_espace(); Aff_OUI(); Point();} // "HAUT : OUI."

void Aff_BAS_deux_points_espace() {Aff_TEXTE_EEPROM(20,6);} // "BAS : "

void Aff_BAS_deux_points_espace_NON_Point() {
  Aff_BAS_deux_points_espace(); Aff_NON(); Point();}

void Aff_GAUCHE_deux_points_espace() {Aff_TEXTE_EEPROM(41,9);} // "GAUCHE : "

void Aff_DROITE_deux_points_espace() {Aff_TEXTE_EEPROM(62,9);} // "DROITE : "

void Aff_DROITE_deux_points_Sortie_Point() {
  Aff_DROITE_deux_points_espace(); Aff_TEXTE_EEPROM(156,7);} // "DROITE : Sortie."

void Aff_EEPROM_Point() {Aff_TEXTE_EEPROM(244,7);}

void Aff_TRACES_Point() {Aff_TEXTE_EEPROM(217,5); Aff_TEXTE_EEPROM(323,2);} // "TRACES."

void Affiche_la_version_du_logiciel() {
  digitalWrite(Trp_V,HIGH); digitalWrite(Trp_R,HIGH);
  u8g.firstPage(); do {
     u8g.drawRFrame(0,0,121,64,5); // Cadre extérieur.
     u8g.setPrintPos(8,15); Aff_TEXTE_EEPROM(460,18); // "Version logicielle"
     u8g.setPrintPos(24,27); Aff_TEXTE_EEPROM(404,3); u8g.print(Version); // "du "); 
     u8g.setPrintPos(42,39); Aff_TEXTE_EEPROM(478,8); // "(FE6AAE)"
     u8g.setPrintPos(14,52); Aff_TEXTE_EEPROM(486,6); // "USB = "
     u8g.print(Vitesse_USB); Aff_TEXTE_EEPROM(492,5);} // "baud."
     while(u8g.nextPage()); Attendre_un_BP_sans_le_Bleu(); Eteindre_LED_Triple();}
  
//======================== GESTION de la BASE de TEMPS ========================

void Affiche_la_duree() {
  if (I_BdT == 0) Aff_TEXTE_EEPROM(82,6); // "1.35mS"
  else {switch (I_BdT) {
          case 1 : {Grandeur = 2; break;}
          case 2 : {Grandeur = 5; break;}  
          case 3 : {Grandeur = 10; break;}
          case 4 : {Grandeur = 20; break;}
          case 5 : {Grandeur = 50; break;}
          case 6 : {Grandeur = 100; break;}
          case 7 : Grandeur = 200;} 
          u8g.print(Grandeur); Aff_TEXTE_EEPROM(86,2);}} // "mS"

void Diminue_la_BT() {I_BdT--; if(I_BdT == 255) I_BdT = 7;}

void Augmente_la_BT() {I_BdT++; if(I_BdT == 8) I_BdT = 0;}
  
//===================== GESTION de l'affichage de la TRACE ====================

void Visualise_la_Trace() {
  byte OCTET, Y;
  for (byte X = 1; X < 120; X++) {
       OCTET = TRACE[(Debut + X)-1];
       if(OCTET < 1) digitalWrite(Verte,HIGH); if(OCTET > 254) digitalWrite(Rouge,HIGH);
       Y = map(OCTET,0,254,59,1);
       if(Trace_pleine) u8g.drawVLine(X, Y, 60-Y);
       else u8g.drawPixel(X, Y);
       Valeur_totale = Valeur_totale + OCTET;}
  digitalWrite(Rouge,LOW); digitalWrite(Verte,LOW);}

void Trace_la_courbe() {
  Debut = 0; Valeur_totale = 0;
  Visualise_la_Trace();}

void Calcule_le_Debut() {
  long Total = 0;
  Debut = (Num_Fenetre - 1) * 119; Valeur_totale = 0;
  // Ci-dessous fait la moyenne sur 255 mesures du potentiomètre.
  for (byte Nb = 0; Nb < 255; Nb ++) Total = Total + (analogRead(A0) >> 3);
  Debut = Debut + (Total >> 8);} // Décale la trace en latéral.

void Affiche_la_TRACE() {Calcule_le_Debut(); Visualise_la_Trace();}

void Trace_la_grille() {
  byte Debut = 1; if (Texte || Mode_CAN) Debut = 12;
  u8g.drawFrame(0,0,121,64); // Cadre extérieur.
  // Trace les cinq  graduations Horizontales.
  for (byte Y = 12; Y < 64; Y = Y+12) u8g.drawHLine(1, Y, 119);
  // Trace les neuf graduations Verticales.
  for (byte X = 12; X < 110; X = X+12) u8g.drawVLine(X, Debut, 60-Debut);
  // Trace les 3 graduations de délimitation des fenêtres.
  for (byte X = 30; X < 128; X = X+30) u8g.drawVLine(X, 61, 2);
  // Remplit l'un des quatre secteurs de positionnement des fenêtres.
  for(byte Ligne = 60; Ligne < 63; Ligne++) {
     u8g.drawHLine(((Num_Fenetre - 1)*30)+1 , Ligne, 29);}}

void Affiche_le_Gain(){
  switch(Gain) {
      case 0 : {Aff_TEXTE_EEPROM(88,4); break;} // "1.25" break;}
      case 1 : {Aff_TEXTE_EEPROM(92,3); break;} // "2.5")
      case 2 : u8g.print('5');} Aff_TEXTE_EEPROM(95,2);} // "v ")

void AFFICHE_TRACE() {// Gère les options d'affichage.
  byte Y_Efficace = (map(byte(Valeur_totale / 119),0,254,59,1)) + 3 ;
  byte Diviseur;
  // Ci-dessus + 3 pour tenir compte de la hauteur du caractère '<'.
  u8g.firstPage(); do {
      if (Texte) {
         if (Mode_Fenetre) {// Affiche les attributs individuels.
            switch(Num_Fenetre) {
               case 1 : {Gain = Gain_1; I_BdT = I_BdT_1; break;}
               case 2 : {Gain = Gain_2; I_BdT = I_BdT_2; break;}
               case 3 : {Gain = Gain_3; I_BdT = I_BdT_3; break;}
               case 4 : {Gain = Gain_4; I_BdT = I_BdT_4;}}}
         u8g.setPrintPos(5,10); Affiche_le_Gain(); Affiche_la_duree(); u8g.print(' ');
         //-------- Affiche la valeur numérique de Vefficace --------
         switch(Gain) {
            case 0 : {Diviseur = 40; break;}
            case 1 : {Diviseur = 20; break;}
            case 2 : Diviseur = 10;}
            u8g.print((float(map(Valeur_totale / 119,0,254,0,50))) / Diviseur,1);
            Aff_TEXTE_EEPROM(97,3);} // "Vef"
         //----------------------------------------------------------
      if (Mode_Fenetre) {u8g.setPrintPos(122,10); u8g.print(Num_Fenetre);
                         u8g.drawFrame(120,0,9,13);}
      if (Grille) Trace_la_grille(); Affiche_la_TRACE();
      u8g.setPrintPos(122, Y_Efficace); u8g.print('<');} // Valeur efficace.
  //--------------------------------------------------------------------
  while(u8g.nextPage());}

void Traite_affichage() {
  boolean FINI = false;
  digitalWrite(Trp_V,HIGH); 
  while (!FINI) {
     Tester_le_BP();
     switch (Touche) {
        case DROITE  : {if (Clic_long) FINI = true;
                       else {Num_Fenetre++; if (Num_Fenetre == 5) Num_Fenetre = 1;} break;}
        case BAS    : {if (Clic_long) Trace_pleine = !Trace_pleine;
                       else Grille = !Grille; break;}
        case HAUT   : {if (Clic_long) BIP();
                       else Texte = !Texte; break;}
        case GAUCHE : {if (Clic_long) BIP();
                       else {Num_Fenetre--; if (Num_Fenetre == 0) Num_Fenetre = 4;}}}
     AFFICHE_TRACE();}
   digitalWrite(Trp_V,LOW);}
 
//========================== Capture des échantilons ==========================

void Affiche_numeriser() {Aff_TEXTE_EEPROM(101,9);} // "Numériser"    
      
void Effectue_une_numerisation() {
    digitalWrite(Trp_V,HIGH);
    int TBT = Valeurs_BT[I_BdT];
    for (int PTR = 0; PTR < 476; PTR++) {
         TRACE[PTR] = analogRead(A3) >> Gain; delayMicroseconds(TBT);}
    digitalWrite(Trp_V,LOW);}
  
//=================== GESTION des options de SYNCHRONISATION ==================

void Affiche_la_tension_de_Seuil() {
  u8g.print(float(map(U_Synchronisation, 1,255, 1, 50))/10,1); Aff_TEXTE_EEPROM(95,2);} // "V ")

void Affiche_la_syncronisation() {
  digitalWrite(Trp_B,HIGH);
  u8g.firstPage(); do {
      for (byte Y = 1; Y < 64; Y = Y+12) u8g.drawHLine(120,Y,8);
      u8g.drawFrame(110,0,9,64); // Gauge verticale.
      u8g.drawBox(111,62-(U_Synchronisation >>2),7,63); // Niveau du seuil.
      u8g.drawFrame(60,19,24,13); u8g.setPrintPos(66,29);
      if (Front_Montant) Aff_TEXTE_EEPROM(130,2); // "FM"
      else Aff_TEXTE_EEPROM(137,2); // "FD")
      u8g.setPrintPos(10,12); Aff_TEXTE_EEPROM(110,16); // "SYNCHRONISATION.")
      u8g.setPrintPos(0,25); Aff_TEXTE_EEPROM(126,7); // "H : FM."
      u8g.setPrintPos(0,37); Aff_TEXTE_EEPROM(133,7); // "B : FD."
      u8g.setPrintPos(0,49); Aff_TEXTE_EEPROM(140,12); // "G : Seuil > "
      if (Seuil) Aff_OUI(); else Aff_NON();
      u8g.setPrintPos(0,61); Aff_TEXTE_EEPROM(152,13); // "D : Sortie.  "
      Affiche_la_tension_de_Seuil();}
  while(u8g.nextPage()); Eteindre_LED_Triple();}
  
void Gerer_la_synchronisation() {
  boolean FINI = false;
  while (!FINI) {
    U_Synchronisation = map(analogRead(A0), 0,1023, 1, 255);
    Affiche_la_syncronisation();
    Tester_le_BP();
    switch (Touche) {
        case HAUT : {Front_Montant = true; break;}
        case BAS : {Front_Montant = false; break;}
        case GAUCHE : {Seuil= !Seuil; break;}
        case DROITE  : FINI = true;}}}

//================= Attente pour déclencher un enregistrement ================
// Si synchronisation attendre que les contraintes soient satisfaites.

void Gere_le_Declenchement() {
    byte U_Actuelle;
  //----------------- Déclenchement sur Seuil -----------------
  if (Seuil) {
     if (Front_Montant) {
         //------- Attendre U en entrée minimale ------
         U_Actuelle = analogRead(A3) >> 2;
         while ((analogRead(A3) >> 2) > U_Actuelle)
               {U_Actuelle = analogRead(A3) >> 2;}
         while ((analogRead(A3) >> 2) <= U_Actuelle) {
               U_Actuelle = analogRead(A3) >> 2;} // Attendre la valeur minimale.
         //--------------------------------------------
         while ((analogRead(A3) >> 2) < U_Synchronisation) {}} // Attendre le Seuil.        
     else { //------- Attendre U en entrée minimale ------
         while ((analogRead(A3) >> 2) < U_Actuelle)
               {U_Actuelle = analogRead(A3) >> 2;}
         while ((analogRead(A3) >> 2) >= U_Actuelle) {
               U_Actuelle = analogRead(A3) >> 2;} // Attendre la valeur maximale.
         //--------------------------------------------
         while ((analogRead(A3) >> 2) > U_Synchronisation) {}}} // Attendre le Seuil.
  //----------------- Déclenchement sur Front -----------------
  else {if (Front_Montant) while ((analogRead(A3) >> 2) < 128); // Ne rien faire.
        else while ((analogRead(A3) >> 2) > 128);}} // Ne rien faire.

//=============================================================================

void Saisie_des_echantillons() {
  // Gain représente le nombre de décalages à droite donc pour
  // Gain = 2,1,0 le signale sera "multiplié" par 0 2 et 4.
  boolean FINI = false; boolean SAV_Grille = Grille; Mode_CAN = true; Num_Fenetre = 1;
  Automatique = true; Grille = false; Libre = true; Gain = 2; // 5V par défaut.
  while (!FINI) {
     if (!Libre) Gere_le_Declenchement();
     Effectue_une_numerisation();
     Tester_le_BP();
     switch (Touche) {
        case HAUT : {if (Clic_long) {Gain--; if (Gain == 255) Gain = 2;}
                     else Augmente_la_BT(); break;}
        case BAS : {if (Clic_long)  Grille = !Grille; else Diminue_la_BT(); break;}
        case GAUCHE : {if (Clic_long) Gerer_la_synchronisation();
                       else {if (Automatique) Libre = !Libre;} break;}
        case DROITE  : if (Clic_long) FINI = true;
                      else {Automatique = !Automatique;
                            if (!Automatique) digitalWrite(Trp_R,HIGH);}}
     u8g.firstPage(); do {
        u8g.setPrintPos(7,10); Affiche_le_Gain(); Affiche_la_duree(); u8g.print(' ');
        if (Automatique) u8g.print('A'); else u8g.print('M'); u8g.print(' ');
        if (Libre) u8g.print('L');
        else {if (Seuil) u8g.print('N'); else u8g.print('B');
              u8g.print(' '); if (Front_Montant) u8g.print('M'); else u8g.print('D');}
        if (Grille) Trace_la_grille(); Trace_la_courbe();}
     while(u8g.nextPage());
     if (!Automatique) {Attendre_un_BP();
                        if (Touche == DROITE) {Automatique = true;  digitalWrite(Trp_R,LOW);}}}
   Mode_CAN = false; Grille = SAV_Grille; Mode_Fenetre = false;}

//=============================================================================

void Aff_TRACE_H_B_Sortie() {
     Aff_TEXTE_EEPROM(216,7); u8g.print('?'); u8g.setPrintPos(20,31); // " TRACE ?"
     Aff_HAUT_deux_points_espace_OUI_Point(); // "HAUT : OUI."
     u8g.setPrintPos(20,43); Aff_BAS_deux_points_espace();
     Aff_NON(); Point(); // "NON."
     u8g.setPrintPos(20,55); DROITE_deux_points_espace_Sortie_point();} // "DROITE : Sortie."

void Effacer_TRACE_en_EEPROM() {
  boolean FINI = false;
  Eteindre_LED_Triple(); digitalWrite(Trp_R,HIGH);
  if (Lire_Octet_EEPROM(547) == 0) {BIP();
         u8g.firstPage(); do {
            u8g.setPrintPos(10,37); Aff_Pas_de_TRACE();} // "Pas de TRACE !"
         while(u8g.nextPage()); Attendre_un_BP();}
  else {while (!FINI) {
           Tester_le_BP();
           switch (Touche) {
              case HAUT : {{Ecrire_Octet_EEPROM(547,0); // Indique l'effacement de l'EEPROM.
                            for (int Echantillon = 548; Echantillon < 1023; Echantillon++)
                                 Ecrire_Octet_EEPROM(Echantillon,0); FINI = true;} break;}
              case BAS : {FINI = true; break;}
              case GAUCHE : {BIP(); break;}
              case DROITE  : FINI = true;}
              u8g.firstPage(); do {
                 u8g.setPrintPos(20,13); Aff_TEXTE_EEPROM(224,7); // "Effacer"
                 Aff_TRACE_H_B_Sortie();}
              while(u8g.nextPage());} Eteindre_LED_Triple(); digitalWrite(Trp_V,HIGH);}}

void Sauvegarde_Longue_TRACE() {
  boolean FINI = false; boolean Fini = false; boolean Accepte = true;
  if (Lire_Octet_EEPROM(547) == 1) {// Demander confirmation si 4 traces en EEPROM.
     BIP(); Accepte = false;
     while (!Fini) {
       Tester_le_BP();
       switch (Touche) {
          case HAUT : {Fini = true; Accepte = true; break;}
          case BAS : {FINI = true; Fini = true; break;}
          case GAUCHE : {BIP(); break;}
          case DROITE  : FINI = true; Fini = true;}
     u8g.firstPage(); do {
        u8g.setPrintPos(6,13); Aff_TEXTE_EEPROM(288,14); // "ATTENTION : 4 "
        Aff_TRACES_Point(); // "TRACES."
        u8g.setPrintPos(12,25); Aff_TEXTE_EEPROM(302,17); // "On les remplace ?"
        u8g.setPrintPos(20,37); Aff_HAUT_deux_points_espace_OUI_Point();
        u8g.setPrintPos(20,49); Aff_BAS_deux_points_espace(); Aff_NON();
        u8g.setPrintPos(20,61); DROITE_deux_points_espace_Sortie_point();}
     while(u8g.nextPage());}}
  //------------ Ci-dessous sauvegarde la TRACE longue --------------
  if(Accepte) {u8g.firstPage(); do {
             u8g.setPrintPos(0,37); Aff_TEXTE_EEPROM(261,10); // "Sauvegarde"
             Aff_TEXTE_EEPROM(319,4); Aff_TEXTE_EEPROM(231,6); // " la Longue"
             Point();}
             while(u8g.nextPage());
             Ecrire_Octet_EEPROM(547, 2); // Signale longue trace en EEPROM.
             Ecrire_Octet_EEPROM(545, Gain);
             Ecrire_Octet_EEPROM(546, I_BdT_1);
             for (int Echantillon = 0; Echantillon < 476; Echantillon++)
                  Ecrire_Octet_EEPROM(Echantillon + 548, TRACE[Echantillon]);
             Delai_1S();}} // Délai pour avoir le temps de lire le texte.

void Enregistrer_une_FENETRE() {
  int Decalage = 429 + (119 * Num_Fenetre); // 429 = 548 - 119.
  Calcule_le_Debut(); // Détermine le Début de la FENETRE.
  //--------------- Ci-dessous sauvegarde la FENETRE -----------------
  for (int Echantillon = 0; Echantillon < 119; Echantillon++)
      Ecrire_Octet_EEPROM(Echantillon + Decalage, TRACE[Echantillon + Debut]);}

void Sauvegarde_FENETRE() {
  u8g.firstPage(); do {
     u8g.setPrintPos(20,37); Aff_TEXTE_EEPROM(261,10); // "Sauvegarde"
     Aff_TEXTE_EEPROM(319,4); u8g.print(Num_Fenetre); // " la " et le n° de la fenêtre. 
     Point();} while(u8g.nextPage());
  Ecrire_Octet_EEPROM(547, 1); // Signale quatre traces individuelles en EEPROM.
  //--------------- Sauvegarde les attributs de la FENETRE --------------
  switch (Num_Fenetre) {
     case 1 : {Ecrire_Octet_EEPROM(539,Gain); Ecrire_Octet_EEPROM(540,I_BdT); break;}
     case 2 : {Ecrire_Octet_EEPROM(541,Gain); Ecrire_Octet_EEPROM(542,I_BdT); break;}
     case 3 : {Ecrire_Octet_EEPROM(543,Gain); Ecrire_Octet_EEPROM(544,I_BdT); break;}
     case 4 : {Ecrire_Octet_EEPROM(545,Gain); Ecrire_Octet_EEPROM(546,I_BdT);}}
  //---------------------------------------------------------------------
  Enregistrer_une_FENETRE(); Delai_1S();} // Pour avoir le temps de lire le texte.

void Menu_Sauvegarde_TRACE() {
  boolean FINI = false; Eteindre_LED_Triple(); digitalWrite(Trp_R,HIGH);
  while (!FINI) {
     Tester_le_BP();
     switch (Touche) {
        case HAUT : {Sauvegarde_Longue_TRACE(); FINI = true; break;}
        case BAS : {Sauvegarde_FENETRE(); FINI = true; break;}
        case GAUCHE : {Num_Fenetre++; if (Num_Fenetre == 5) Num_Fenetre = 1; break;}
        case DROITE : FINI = true;}
     u8g.firstPage(); do {
        u8g.drawFrame(100,27, 13,14); u8g.drawHLine(80, 33, 20);
        u8g.drawHLine(92, 46, 14); u8g.drawVLine(106, 41, 6);
        u8g.setPrintPos(104,37); u8g.print(Num_Fenetre);
        u8g.setPrintPos(10,13); Aff_TEXTE_EEPROM(261,10); // "Sauvegarde"
        Aff_TEXTE_EEPROM(216,7); u8g.print('?'); // " TRACE ?"
        u8g.setPrintPos(0,25); Aff_TEXTE_EEPROM(13,7); // "HAUT : "
        Aff_TEXTE_EEPROM(273,9); // "Complète."
        u8g.setPrintPos(0,37); Aff_BAS_deux_points_espace();
        Aff_TEXTE_EEPROM(200,7); // "fenêtre"
        u8g.setPrintPos(0,49); Aff_GAUCHE_deux_points_espace(); // "GAUCHE : "
        Aff_TEXTE_EEPROM(282,6); // "Change");
        u8g.setPrintPos(0,61); Aff_DROITE_deux_points_Sortie_Point();} // "DROITE : Sortie."
     while(u8g.nextPage());} Eteindre_LED_Triple(); }

void Recharge_un_enregistrement() {
  Num_Fenetre = 1;
  Mode_Fenetre = (Lire_Octet_EEPROM(547) == 1);
  //------------------- Récupère les quatre paires d'attributs -----------------
  Gain_1 = Lire_Octet_EEPROM(539); Gain_2 = Lire_Octet_EEPROM(541);
  Gain_3 = Lire_Octet_EEPROM(543); Gain_4 = Lire_Octet_EEPROM(545);
  I_BdT_1 = Lire_Octet_EEPROM(540); I_BdT_2 = Lire_Octet_EEPROM(542);
  I_BdT_3 = Lire_Octet_EEPROM(544); I_BdT_4 = Lire_Octet_EEPROM(546);
  //----- Si traces individuelles imposer les attributs de la fenetre n°1. -----
  if (Mode_Fenetre) {Gain = Gain_1; I_BdT = I_BdT_1;}
  //--------- Si traces longue imposer les attributs de la position n°4. -------
  else {Gain = Gain_4; I_BdT = I_BdT_4;}
  //----------------------------------------------------------------------------
  for (int Echantillon = 548; Echantillon < 1024; Echantillon++)
        TRACE[int(Echantillon - 548)] = Lire_Octet_EEPROM(Echantillon);}

void Recharger_TRACE() {
  boolean FINI = false;
  digitalWrite(Trp_B,HIGH);
  if (Lire_Octet_EEPROM(547) == 0) {BIP();
         u8g.firstPage(); do {
            u8g.setPrintPos(10,37); Aff_Pas_de_TRACE();} // "Pas de TRACE !"
         while(u8g.nextPage()); Attendre_un_BP();}
  else {while (!FINI) {
           Tester_le_BP();
           switch (Touche) {
              case HAUT : {{Recharge_un_enregistrement(); FINI = true;} break;}
              case BAS : {FINI = true; break;}
              case GAUCHE : {BIP(); break;}
              case DROITE  : FINI = true;}
              u8g.firstPage(); do {
                 u8g.setPrintPos(20,13); Aff_TEXTE_EEPROM(251,9); // "Recharger"
                 Aff_TRACE_H_B_Sortie();}
              while(u8g.nextPage());}} digitalWrite(Trp_B,LOW);}

void Afficher_nature_TRACE() {
  u8g.print('(');
  switch (Lire_Octet_EEPROM(547)) {
        case 0 : {Aff_Pas_de_TRACE(); u8g.print(')'); break;} // "Pas de TRACE !)"
        case 2 : {Aff_TEXTE_EEPROM(231,7); Aff_TEXTE_EEPROM(217,5); // "Longue TRACE"
                  Aff_TEXTE_EEPROM(324,2); break;} // ".)"
        case 1 : {Aff_TEXTE_EEPROM(238,6); Aff_TEXTE_EEPROM(216,6);} // "Quatre TRACE"
  Aff_TEXTE_EEPROM(323,3);}} // "S.)"

void Menu_EEPROM() {
  boolean FINI = false; digitalWrite(Trp_V,HIGH);
  while (!FINI) {
     Tester_le_BP();
     switch (Touche) {
        case HAUT : {Effacer_TRACE_en_EEPROM(); FINI = true; break;}
        case BAS : {BIP();break;}
        case GAUCHE : {Recharger_TRACE(); FINI = true; break;}
        case DROITE  : if (Clic_long) FINI = true; else {Menu_Sauvegarde_TRACE(); FINI = true;}}
     u8g.firstPage(); do {
        u8g.setPrintPos(20,13);
        Aff_TEXTE_EEPROM(0,5); Aff_EEPROM_Point(); // " MENU EEPROM."
        u8g.setPrintPos(12,25);
        Aff_TEXTE_EEPROM(13,7); Aff_TEXTE_EEPROM(224,7); Point(); // "HAUT : Effacer.");
        u8g.setPrintPos(0,37); Aff_GAUCHE_deux_points_espace(); // "GAUCHE : "
        Aff_TEXTE_EEPROM(251,10); // "Recharger."
        u8g.setPrintPos(0,49); Aff_DROITE_deux_points_espace(); // "DROITE : "
        Aff_TEXTE_EEPROM(261,12); // "Sauvegarder."
        u8g.setPrintPos(12,61); Afficher_nature_TRACE();}
     while(u8g.nextPage());} Eteindre_LED_Triple();}

//========================= Transfert TRACES sur USB ==========================

void POINT() {Serial.print('.');}

void Aff_Texte_EEPROM_sur_Moniteur(int PTR, byte Longueur) {
  for (byte I=0; I<Longueur; I++) {Serial.print(char(Lire_Octet_EEPROM(PTR))); PTR++;}}

void Separation_etoiles() {Serial.print(' '); for (byte Nb = 0; Nb < 67; Nb++) Serial.print('*');}

void Aff_TRACE_sur_USB() {Aff_Texte_EEPROM_sur_Moniteur(217,5);} // "HAUT : TRACE"

void Espace_Egal_Espace() {Aff_Texte_EEPROM_sur_Moniteur(454,3);} // " = "

void Exporte_Calibre_et_Base_de_Temps () {
  Serial.println(); Aff_Texte_EEPROM_sur_Moniteur(497,8); //" Calibre"
  Espace_Egal_Espace();
  switch(Gain) {
      case 0 : {Aff_Texte_EEPROM_sur_Moniteur(88,4); break;} // "1.25"
      case 1 : {Aff_Texte_EEPROM_sur_Moniteur(92,3); break;} // "2.5"
      case 2 : Serial.print('5');} // "5")
  Serial.print("v   ");
  Aff_Texte_EEPROM_sur_Moniteur(171, 13); Espace_Egal_Espace(); // "BASE de TEMPS = "
  if (I_BdT == 0) {Aff_Texte_EEPROM_sur_Moniteur(82,4); Serial.println();} // "1.35mS"
  else {switch (I_BdT) {
          case 1 : {Grandeur = 2; break;}
          case 2 : {Grandeur = 5; break;}  
          case 3 : {Grandeur = 10; break;}
          case 4 : {Grandeur = 20; break;}
          case 5 : {Grandeur = 50; break;}
          case 6 : {Grandeur = 100; break;}
          case 7 : Grandeur = 200;} 
          Serial.print(Grandeur); Aff_Texte_EEPROM_sur_Moniteur(86,2); Serial.println();}} // "mS"

void Liste_les_valeurs_des_Echantillons(boolean Longue_TRACE) {
  // 119 Ech par fenêtre sera listé en 7 Lignes de 17 Echantillons.
  byte Compteur = 0; byte Ligne = 0; byte Fenetre = 1; byte OCTET;
  if (!Longue_TRACE) {I_BdT = I_BdT_1; Gain = Gain_1;}
  Separation_etoiles(); Exporte_Calibre_et_Base_de_Temps();
  for (int Index = 0; Index < 476; Index++) {
       Serial.print(' '); OCTET = TRACE[Index];
       if (OCTET < 100) Serial.print('0'); if (OCTET < 10) Serial.print('0');
       Serial.print(TRACE[Index]); Compteur++;
       if (Compteur == 17) {
           Compteur = 0; Serial.println(); Ligne++;
           if (Ligne == 7) {
               Ligne = 0; Separation_etoiles(); Fenetre++;
               if (Fenetre < 5) {
                  if (!Longue_TRACE) {
                     switch (Fenetre) {
                       case 2 : {I_BdT = I_BdT_2; Gain = Gain_2; break;}
                       case 3 : {I_BdT = I_BdT_3; Gain = Gain_3; break;}
                       case 4 : {I_BdT = I_BdT_4; Gain = Gain_4;}}}
                  Exporte_Calibre_et_Base_de_Temps();}}}}}

void Exporte_sur_USB() {
  boolean Longue_TRACE = !Mode_Fenetre;
  Serial.println(); Serial.println(); Serial.print(' ');
  Aff_Texte_EEPROM_sur_Moniteur(326, 8); // "Listage "
  if (Longue_TRACE) {
     Aff_Texte_EEPROM_sur_Moniteur(231, 7); // "Longue "
     Aff_TRACE_sur_USB(); Aff_Texte_EEPROM_sur_Moniteur(68, 2);} // "TRACE :"
  else {Aff_Texte_EEPROM_sur_Moniteur(300, 2); // "4 "
       Aff_TRACE_sur_USB(); Serial.print('S'); Aff_Texte_EEPROM_sur_Moniteur(68, 2);} // "TRACES :"
  Serial.println(); Serial.println(); Liste_les_valeurs_des_Echantillons(Longue_TRACE);
  Serial.println();}

void Liste_la_TRACE_sur_USB() {
  digitalWrite(Trp_R,HIGH);
  u8g.firstPage(); do {
  u8g.setPrintPos(5,35); Aff_TEXTE_EEPROM(509, 17);} // " Exporte sur USB :"
  while(u8g.nextPage());
  Exporte_sur_USB(); Delai_1S(); digitalWrite(Trp_R,LOW);}
  
//============================== Gestion du RESET =============================

//----------- Fonction de durées de la Base de Temps -----------
void Affiche_duree_totale() {
  if (Total >= 1000) {u8g.print(Total / 1000); u8g.print('S');}
  else {u8g.print(Total); Aff_TEXTE_EEPROM(86,2);}} // "mS"

void Menu_duree_BdT() {
  boolean FINI = false;
  while (!FINI) {
    u8g.firstPage(); do {
    u8g.setPrintPos(23,13); Aff_TEXTE_EEPROM(171,13); // "BASE de TEMPS"
    u8g.setPrintPos(12,29); Aff_TEXTE_EEPROM(184,8); // "Durée : "
    Affiche_la_duree(); u8g.setPrintPos(12,44); Aff_TEXTE_EEPROM(192,8); // "Total : "
    if (I_BdT == 0) Aff_TEXTE_EEPROM(430,6); // "0.643S" 
    else {Total = Grandeur * 40; Affiche_duree_totale();}
    u8g.setPrintPos(0, 58); Aff_TEXTE_EEPROM(200,10); // "Fenêtre : "
    if (I_BdT == 0) Aff_TEXTE_EEPROM(434,5); // "0.16S"
    else {Total = Grandeur * 10; Affiche_duree_totale();}}
    while(u8g.nextPage());
  Attendre_un_BP();
  switch (Touche) {
    case HAUT : {Augmente_la_BT(); break;}
    case BAS  : {Diminue_la_BT(); break;}
    case GAUCHE : {BIP(); break;}
    case DROITE  : FINI = true;}}}

//--------------- Fonction de listage de l'EEPROM --------------

void Aff_Listage_EEPROM_Point() {
  Aff_TEXTE_EEPROM(326,8); Aff_EEPROM_Point();} // "Listage EEPROM."

void Lister_OCTET() {
  byte OCTET = Lire_Octet_EEPROM(PTR);
  if (PTR < Debut_Hexadecimal) {  
     if ((OCTET > 31) && (OCTET < 126)) {Serial.print(' '); Serial.print(char(OCTET));}
     else Serial.print("..");}
  else {if (OCTET < 16) Serial.print('0'); Serial.print(OCTET,HEX);}
  Serial.print(' '); PTR++;}

void Lister_ENTETE() {
   Serial.println(); Aff_Texte_EEPROM_sur_Moniteur(350,54); Serial.println();}
   // " ADRS  00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F"

void Lister_une_LIGNE() {   
  byte Compteur_Octets = 0; Serial.print(' '); if (PTR<10) {Serial.print('0');};
  if (PTR<100) {Serial.print('0');}; if (PTR<1000) {Serial.print('0');};
  Serial.print(PTR); Serial.print("  ");  
  while (Compteur_Octets < 16) {Lister_OCTET(); Compteur_Octets++;} Serial.println();}

void Lister_un_BLOC() {
  byte Compteur_lignes = 0; Lister_ENTETE();
  while (Compteur_lignes < 16) {Lister_une_LIGNE(); Compteur_lignes++;}}

void Lister_EEPROM() {
  digitalWrite(Trp_B,HIGH);
  u8g.firstPage(); do {
    u8g.setPrintPos(20,37); Aff_Listage_EEPROM_Point();}
  while(u8g.nextPage());
  Serial.println(); Aff_Texte_EEPROM_sur_Moniteur(326,24); Aff_Texte_EEPROM_sur_Moniteur(244,6);
  Aff_Texte_EEPROM_sur_Moniteur(134,2); // "Listage du contenu de l'EEPROM :"
  Serial.println(); Serial.println();
  PTR = 0; Lister_un_BLOC(); Lister_un_BLOC(); Lister_un_BLOC(); Lister_un_BLOC();
  Delai_1S(); digitalWrite(Trp_B,LOW);} // Délai pour avoir le temps de lire le texte.
  
//-------- Gestion de l'option d'affichage de la version -------

int SRAM_LIBRE() { // Fonction qui retourne la taille de SRAM disponible.
  extern int __heap_start, *__brkval; // Déclaration des deux pointeurs dédiés.
  byte BIDON; // Dernière variable allouée, donc occupe le "haut" du TAS.
  if (__brkval == 0) {return (int) &BIDON -(int) &__heap_start;}
  else {return (int) &BIDON -(int) __brkval;}}

void Menu_Version() {
  boolean FINI = false; digitalWrite(Trp_B,HIGH);
  while (!FINI) {
     Tester_le_BP();
     switch (Touche) {
        case HAUT : {Ecrire_Octet_EEPROM(538, true); FINI = true; break;}
        case BAS : {Ecrire_Octet_EEPROM(538, false); FINI = true; break;}
        case GAUCHE : {BIP(); break;}
        case DROITE  : FINI = true;}
     u8g.firstPage(); do {
        u8g.setPrintPos(8,13); u8g.print('('); Aff_TEXTE_EEPROM(444,13); // "PILE - TAS = "
        u8g.print(SRAM_LIBRE()); u8g.print(')'); u8g.setPrintPos(0,25);
        Aff_TEXTE_EEPROM(26,3); u8g.print(' '); Aff_TEXTE_EEPROM(416,8); // "Aff Version "
        Aff_TEXTE_EEPROM(457,3); Aff_TEXTE_EEPROM(406,6); // "sur RESET");
        u8g.setPrintPos(12,37); Aff_HAUT_deux_points_espace_OUI_Point();
        u8g.setPrintPos(18,49); Aff_BAS_deux_points_espace_NON_Point();
         u8g.setPrintPos(0,61); Aff_DROITE_deux_points_Sortie_Point();}
     while(u8g.nextPage());} digitalWrite(Trp_B,LOW);}

//---------- Fonction de génération des TRACEs fictives --------

void Genere_une_Sinusoide_amortie() {// Trace une sinusoïde amortie avec décrément linéaire.
  byte Amplitude; I_BdT = 2; Gain = 0; Mode_Fenetre = false;
  for (PTR = 0; PTR < 476; PTR++) {
       Amplitude = 127 - (PTR >> 2); // >> 2 pour diviser la valeur par 4.
       TRACE[PTR] = 128 + (sin(radians(PTR * 6)) * Amplitude);}}
       // Ci-dessus la valeur 6 représente la fréquence du signal.

void Etat_1() {for (byte I = 0; I < 12; I++) {TRACE[PTR] = 203; PTR++;}}

void Etat_0() {for (byte I = 0; I < 12; I++) {TRACE[PTR] = 25; PTR++;}}

void Genere_un_signal_Binaire() {// Trace une suite binaire d'un signal série.
  I_BdT = 3; Gain = 0; Mode_Fenetre = false; PTR = 0;
  Etat_1(); Etat_0(); Etat_1(); Etat_1(); Etat_0(); Etat_1(); Etat_0(); Etat_0();
  Etat_1(); Etat_0(); Etat_1(); Etat_1(); Etat_0(); Etat_1(); Etat_0(); Etat_1();
  Etat_1(); Etat_0(); Etat_1(); Etat_1(); Etat_0(); Etat_1(); Etat_0(); Etat_1();
  Etat_0(); Etat_1(); Etat_0(); Etat_1(); Etat_0(); Etat_1(); Etat_0(); Etat_1(); 
  Etat_1(); Etat_0(); Etat_1(); Etat_1(); Etat_0(); Etat_1(); Etat_0();
  for (byte I = 0; I < 7; I++) {TRACE[PTR] = 25; PTR++;}}

void Genere_fenetre_1() {
  // Trace une sinusoïde d'amplitude constante.
  I_BdT_1 = 2; Gain_1 = 0;
  for (PTR = 0; PTR < 476; PTR++) {
       TRACE[PTR] = 128 + (sin(radians(PTR * 9)) * 100);}}
       // Ci-dessus la valeur 9 représente la fréquence du signal.

void Genere_fenetre_2() {
  PTR = 119; I_BdT_2 = 1; Gain_2 = 1;
  byte OCTET = 0;
  while (PTR < 357) {
    TRACE[PTR] = OCTET; PTR++; OCTET = OCTET + 5;
    if (OCTET > 200) OCTET = 0;}}

void Genere_fenetre_3() {
  PTR = 238; I_BdT_3 = 2; Gain_3 = 2;
  byte OCTET = 200;
  while (PTR < 357) {
    TRACE[PTR] = OCTET; PTR++; OCTET = OCTET - 6;
    if (OCTET < 40) OCTET = 200;}}

void Dent_de_scie() {
  byte OCTET = 40;
  for (byte I = 0; I < 24; I++) {TRACE[PTR] = OCTET; PTR++; OCTET = OCTET + 6;}
  for (byte I = 0; I < 24; I++) {OCTET = OCTET - 6; TRACE[PTR] = OCTET; PTR++;}}

void Genere_fenetre_4() {
  byte OCTET; PTR = 357; I_BdT_4 = 3; Gain_4 = 0;
  Dent_de_scie(); Dent_de_scie();
  OCTET = 40; while (PTR < 476) {TRACE[PTR] = OCTET; PTR++; OCTET = OCTET + 6;}}

void Affiche_Generation_du_signal_Point() {u8g.print("Generation du signal.");}

void Genere_4_Traces_individuelles() {
  Mode_Fenetre = true;
  u8g.firstPage(); do {u8g.setPrintPos(0,30); Affiche_Generation_du_signal_Point();}
  while(u8g.nextPage()); Delai_1S();
  Genere_fenetre_1(); Genere_fenetre_2(); Genere_fenetre_3(); Genere_fenetre_4();}

void Menu_Genere_des_TRACES() {
  digitalWrite(Trp_R,HIGH);
  u8g.firstPage(); do {
     u8g.setPrintPos(0,13); Affiche_Generation_du_signal_Point();
     u8g.setPrintPos(0,25); Aff_HAUT_deux_points_espace();
     Aff_TEXTE_EEPROM(526,11); // "Sinusoïdal."
     u8g.setPrintPos(0,37); Aff_BAS_deux_points_espace(); Aff_TEXTE_EEPROM(370,2); // "4 "
     Aff_TRACES_Point(); u8g.setPrintPos(0,49); // "TRACES."
     Aff_GAUCHE_deux_points_espace(); // "GAUCHE : "
     u8g.print("BINAIRE."); u8g.setPrintPos(0,61); DROITE_deux_points_espace_Sortie_point();}
     while(u8g.nextPage());
  Attendre_un_BP_sans_le_Bleu();
  switch (Touche) {
     case HAUT : {Genere_une_Sinusoide_amortie(); break;}
     case BAS : {Genere_4_Traces_individuelles(); break;}
     case GAUCHE : Genere_un_signal_Binaire();}
  digitalWrite(Trp_R,LOW);}
  
//--------------------------------------------------------------

void Menu_RESET() {
  boolean FINI = false; digitalWrite(Trp_V,HIGH);
  Gere_stabilisation_et_duree();  // Attendre le relacher.
  while (!FINI) {
     Tester_le_BP();
     switch (Touche) {
        case HAUT : {Menu_duree_BdT(); break;}
        case BAS : {Lister_EEPROM();break;}
        case GAUCHE : {Menu_Version(); break;}
        case DROITE  : if (Clic_long) FINI = true; else Menu_Genere_des_TRACES();}
     u8g.firstPage(); do {
        u8g.setPrintPos(20,13); Aff_TEXTE_EEPROM(50,5); // "Menu " 
        Aff_TEXTE_EEPROM(404,8); Aff_TEXTE_EEPROM(17,2); // "du RESET :"
        u8g.setPrintPos(0,25); Aff_HAUT_deux_points_espace(); // "HAUT : "
        Aff_TEXTE_EEPROM(50,5); Aff_TEXTE_EEPROM(184,5); // "Menu duree"
        u8g.setPrintPos(106,25); Aff_TEXTE_EEPROM(412,4); // "BdT."
        u8g.setPrintPos(0,37); // Ci-dessous "BAS : Listage EEPROM."
        Aff_BAS_deux_points_espace(); Aff_Listage_EEPROM_Point();
        // Ci-dessous "GAUCHE : Version O/N."
        u8g.setPrintPos(0,49); Aff_GAUCHE_deux_points_espace(); Aff_TEXTE_EEPROM(416,12);
        // Ci-dessous "DROITE : TRACE fictive ."
        u8g.setPrintPos(0,61); Aff_DROITE_deux_points_espace();
        Aff_TEXTE_EEPROM(439,5); Aff_TEXTE_EEPROM(217,5); Aff_TEXTE_EEPROM(323,2);}
        // Ci-dessus ""Init TRACES."
     while(u8g.nextPage());} Eteindre_LED_Triple();}

//=============================================================================

void Aff_MENU_de_BASE() {
  digitalWrite(Trp_B,HIGH);
  u8g.firstPage(); do {
      u8g.setPrintPos(20,13); Aff_TEXTE_EEPROM(0,13); // "MENU de BASE."
      u8g.setPrintPos(0,25); Aff_HAUT_deux_points_espace(); // "HAUT : "
      Affiche_numeriser(); Point();
      u8g.setPrintPos(0,37); Aff_TEXTE_EEPROM(20,21); // "BAS : Afficher TRACE."
      u8g.setPrintPos(0,49); Aff_TEXTE_EEPROM(41,21); // "GAUCHE : Menu EEPROM."
      u8g.setPrintPos(0,61); Aff_TEXTE_EEPROM(62,20);} // "DROITE : Sortie USB."
  while(u8g.nextPage()); Eteindre_LED_Triple();}

void Gerer_le_MENU_de_BASE() {
  switch (Touche) {
          case DROITE : {Liste_la_TRACE_sur_USB(); break;}
          case GAUCHE : {Menu_EEPROM(); break;}
          case HAUT  : {Saisie_des_echantillons(); break;}
          case BAS   : Traite_affichage();}}
