Machine a état, avec écran LCD et Keypad

bonjour tout le monde,

Depuis plusieurs mois je suis sur un projet : réaliser le programme et l'interface homme machine d'un compacteur automatique de laboratoire.

(je suis dans ma première année d'étude donc je suis extrêmement débutant)

Dans ce compacteur j'ai 4 moteurs : moteur 0 = rotation du plateau (ou est posé le moule), moteur 1 = translation arrière, moteur 2 = translation avant et moteur 3 = battage de la dame.

Il y a aussi 5 capteurs : 3 capteurs mécanique de position (voir l'image ci dessous), un capteur inductif pour la dame et un capteur magnétique pour la porte de sécurité.

Ce compacteur doit réaliser des cycles, une succession de mouvement et d'instruction automatiquement (cycle d'environ 1min30)

j'utilise un Keypad, pour se dirigé dans l'interface (tel touche ouvre tel menu)

Voici comment le compacteur est actuellement câblé (simplement maintenant l'écran est branché directement sur l'arduino il n'y a plus de générateur

venons-en au fait, il y a quelque mois j'ai réalisé tout le code (code + écran) en utilisant des fonctions, ca avait plutôt bien marché, mais le moment venu de faire l'interruption de la porte ca a coincé,

je devais faire en sorte que lorsque la porte s'ouvre TOUT ce met en pause le temps de l'ouverture de la porte avec affiché sur l'écran "porte ouverte" . Et lorsque la porte se referme, un nouvel écran apparait qui demande a l'utilisateur si oui ou non il veut continuer le cycle, si il valide alors le cycle reprend sinon on retourne au menu.

sauf que actuellement lorsque la porte se referme, les moteurs et le programme redémarre directement et on quitte l'interruption, j'ai donc essayer de rajouter des étapes dans l'interruption avec un écran de validation etc, rien y fait.

voici le code de l'interruption actuel (dans le code fait avec des fonctions) :

bool porteOuverte = false;

void checkDoor() 
{
    if (digitalRead(portDeTest) == HIGH) 
    {
        // La porte est ouverte
        while (digitalRead(portDeTest) == HIGH) 
        {
            analogWrite(DigitalOut[0], false);
            analogWrite(DigitalOut[1], false);
            analogWrite(DigitalOut[2], false);
            analogWrite(DigitalOut[3], false);

            if (currentMenu == START_cycle1 && !porteOuverte) 
            {
                porteOuverte = true;
                // Affiche "Porte ouverte"
                u8g2.clearBuffer();
                u8g2.drawStr(10, 20, "! PORTE OUVERTE !");
                u8g2.drawStr(10, 45, "veuillez refermer");
                u8g2.drawStr(13, 60, "la porte");
                u8g2.sendBuffer();
            }

            if (currentMenu == START_cycle2 && !porteOuverte) 
            {
                porteOuverte = true;
                // Affiche "Porte ouverte"
                u8g2.clearBuffer();
                u8g2.drawStr(10, 20, "! PORTE OUVERTE !");
                u8g2.drawStr(10, 45, "veuillez refermer");
                u8g2.drawStr(13, 60, "la porte");
                u8g2.sendBuffer();
            }

            if (currentMenu == START_cycle3 && !porteOuverte) 
            {
                porteOuverte = true;
                // Affiche "Porte ouverte"
                u8g2.clearBuffer();
                u8g2.drawStr(10, 20, "! PORTE OUVERTE !");
                u8g2.drawStr(10, 45, "veuillez refermer");
                u8g2.drawStr(13, 60, "la porte");
                u8g2.sendBuffer();
            }

            if (currentMenu == START_cycle4 && !porteOuverte) 
            {
                porteOuverte = true;
                // Affiche "Porte ouverte"
                u8g2.clearBuffer();
                u8g2.drawStr(10, 20, "! PORTE OUVERTE !");
                u8g2.drawStr(10, 45, "veuillez refermer");
                u8g2.drawStr(13, 60, "la porte");
                u8g2.sendBuffer();
            }


            if (currentMenu == INIT_1 && !porteOuverte) 
            {
                porteOuverte = true;
                // Affiche "Porte ouverte"
                u8g2.clearBuffer();
                u8g2.drawStr(10, 20, "! PORTE OUVERTE !");
                u8g2.drawStr(10, 45, "veuillez refermer");
                u8g2.drawStr(13, 60, "la porte");
                u8g2.sendBuffer();
            }

            if (currentMenu == INIT_2 && !porteOuverte) 
            {
                porteOuverte = true;
                // Affiche "Porte ouverte"
                u8g2.clearBuffer();
                u8g2.drawStr(10, 20, "! PORTE OUVERTE !");
                u8g2.drawStr(10, 45, "veuillez refermer");
                u8g2.drawStr(13, 60, "la porte");
                u8g2.sendBuffer();
            }

            if (currentMenu == INIT_3 && !porteOuverte) 
            {
                porteOuverte = true;
                // Affiche "Porte ouverte"
                u8g2.clearBuffer();
                u8g2.drawStr(10, 20, "! PORTE OUVERTE !");
                u8g2.drawStr(10, 45, "veuillez refermer");
                u8g2.drawStr(13, 60, "la porte");
                u8g2.sendBuffer();
            }

            if (currentMenu == INIT_4 && !porteOuverte) 
            {
                porteOuverte = true;
                // Affiche "Porte ouverte"
                u8g2.clearBuffer();
                u8g2.drawStr(10, 20, "! PORTE OUVERTE !");
                u8g2.drawStr(10, 45, "veuillez refermer");
                u8g2.drawStr(13, 60, "la porte");
                u8g2.sendBuffer();
            }
        }
    } 
    else 
    {
        // La porte est fermée
        if (currentMenu == START_cycle1 && porteOuverte) 
        {
            porteOuverte = false;
            displayStart1(); // Affiche à nouveau l'écran StartCycle1
        }

        if (currentMenu == START_cycle2 && porteOuverte) 
        {
            porteOuverte = false;
            displayStart2(); // Affiche à nouveau l'écran StartCycle1
        }

        if (currentMenu == START_cycle3 && porteOuverte) 
        {
            porteOuverte = false;
            displayStart3(); // Affiche à nouveau l'écran StartCycle1
        }

        if (currentMenu == START_cycle3 && porteOuverte) 
        {
            porteOuverte = false;
            displayStart4(); // Affiche à nouveau l'écran StartCycle1
        }

        if (currentMenu == INIT_1 && porteOuverte) 
        {
            porteOuverte = false;
            displayInit1(); // Affiche à nouveau l'écran StartCycle1
        }

        if (currentMenu == INIT_2 && porteOuverte) 
        {
            porteOuverte = false;
            displayInit2(); // Affiche à nouveau l'écran StartCycle1
        }

        if (currentMenu == INIT_3 && porteOuverte) 
        {
            porteOuverte = false;
            displayInit3(); // Affiche à nouveau l'écran StartCycle1
        }

        if (currentMenu == INIT_4 && porteOuverte) 
        {
            porteOuverte = false;
            displayInit4(); // Affiche à nouveau l'écran StartCycle1
        }
    }
}

il y a autant de code car j'ai mit l'écran porte ouverte seulement sur les écran ou en parallèle les moteurs tournent, donc lors d'un cycle ou d'une initialisation.

et voici aussi le programme entier et complet :




//pas de validation apres interruption porte 
// nouveau keypad



#include <U8g2lib.h>
#include <Keypad.h>
#include <Arduino.h>
#include <avr/io.h>
#include <avr/interrupt.h>

U8G2_ST7920_128X64_F_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* CS=*/ 10, /* reset=*/ 8);

#define ROWS 4
#define COLS 4

const char kp4x4Keys[ROWS][COLS]  = {{'1', '2', '3', 'A'}, {'4', '5', '6', 'B'}, {'7', '8', '9', 'C'}, {'*', '0', '#', 'D'}};
byte rowKp4x4Pin [4] = {30, 32, 34, 36};
byte colKp4x4Pin [4] = {22, 24, 26, 28};
//fil bleu a gauche vers l'* et sur le 2 (22)

//Variables
Keypad kp4x4  = Keypad(makeKeymap(kp4x4Keys), rowKp4x4Pin, colKp4x4Pin, ROWS, COLS);


//____________________________________ CODE ECRAN _____________________________________________//

enum Menu {
  MAIN_MENU, //0
  INFO_MENU, //1
  START_MENU, //2 
  TEST_MENU, //3

  PROCTOR_MENU, //4
  CBR_MENU, //5 

  PROCTOR_NORMAL, //6
  PROCTOR_MODIFIE,//7

  CBR_NORMAL,//8
  CBR_MODIFIE,//9


  INFO_CYCLE1,//10
  INFO_CYCLE2,//13
  INFO_CYCLE3,//16
  INFO_CYCLE4,//19

  START_cycle1,//11
  START_cycle2,//14
  START_cycle3,//17
  START_cycle4,//20

  INIT_1,//12
  INIT_2,//15
  INIT_3,//18
  INIT_4,//21
  
  CONTINUE_CYCLE_1, //22
  CONTINUE_CYCLE_2, //23 
  CONTINUE_CYCLE_3, //24
  CONTINUE_CYCLE_4, //25

  FIN_CYCLE_1, //26
  FIN_CYCLE_2, //27
  FIN_CYCLE_3, //28
  FIN_CYCLE_4, //29

  TEST_MOTEUR, //30
  TEST_CAPTEUR, //31
};

Menu currentMenu = MAIN_MENU;

void displayMainMenu() 
{  // main menu 0
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_minicute_tr); //
  u8g2.drawButtonUTF8(5,8, U8G2_BTN_INV, u8g2.getDisplayWidth()-2*5,7,1,"      COMPACTEUR");
 
  u8g2.setFont(u8g2_font_unifont_t_symbols);
    u8g2.drawGlyph(90, 29, 0x2192);  
    u8g2.drawGlyph(90, 45, 0x2192);  
    u8g2.drawGlyph(90, 61, 0x2192);  
      u8g2.setFont(u8g2_font_minicute_tr); 
  u8g2.drawStr(17, 26, "Information     1");
  u8g2.drawStr(17, 42, "Demarrer       2");
  u8g2.drawStr(17, 58, "Test machine   3");
  u8g2.sendBuffer();
}

void displayInfoMenu() { //menu 1
  u8g2.clearBuffer();
    u8g2.setFont(u8g2_font_unifont_t_symbols);
    u8g2.drawGlyph(87, 66, 0x2190); //fleche retour
  u8g2.setFont(u8g2_font_minicute_tr); //
  u8g2.drawButtonUTF8(5,8, U8G2_BTN_INV, u8g2.getDisplayWidth()-2*5,7,1,"     INFORMATION");
  // Changer temporairement la taille de la police
   u8g2.setFont(u8g2_font_minicute_tr); // Choix d'une autre taille de police
  u8g2.drawStr(23, 24, "By PROVITEQ");
  // Revenir à la taille de police par défaut
  u8g2.drawStr(18, 39, "- V 1.0.2");
  u8g2.drawStr(1, 50, "01 60 78 99 60 ");
  u8g2.setFont(u8g2_font_04b_03_tr);
  u8g2.drawStr(79, 62, "0    retour ");
  u8g2.sendBuffer();
}

void displayStartMenu() 
{ //menu 2
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_unifont_t_symbols);
    u8g2.drawGlyph(85, 30, 0x2192); 
    u8g2.drawGlyph(85, 45, 0x2192); 
    u8g2.drawGlyph(87, 66, 0x2190); //fleche retour
   u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.drawButtonUTF8(5,8, U8G2_BTN_INV, u8g2.getDisplayWidth()-2*5,7,1,"       DEMARRER");
  u8g2.drawStr(20, 27, "PROCTOR A      1");
  u8g2.drawStr(20, 42, "PROCTOR B      2");
  u8g2.drawStr(28, 52, " (CBR)");
  u8g2.setFont(u8g2_font_04b_03_tr);
  u8g2.drawStr(79, 62, "0    retour");
  u8g2.sendBuffer();
}

void displayTestMenu() 
{ //menu 3
  u8g2.clearBuffer();
    u8g2.setFont(u8g2_font_unifont_t_symbols);
    u8g2.drawGlyph(91, 31, 0x2192); 
    u8g2.drawGlyph(91, 50, 0x2192); 
    u8g2.drawGlyph(87, 66, 0x2190); //fleche retour
  u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.drawButtonUTF8(5,8, U8G2_BTN_INV, u8g2.getDisplayWidth()-2*5,7,1,"   TEST MACHINE");
  u8g2.drawStr(10, 28, "Test Moteurs     1");
  u8g2.drawStr(10, 47, "Test Capteurs    2");
  u8g2.setFont(u8g2_font_04b_03_tr);
  u8g2.drawStr(79, 62, "0    retour");
  u8g2.sendBuffer();
}


void displayProctorMenu() 
{ //menu 4
  u8g2.clearBuffer();
    u8g2.setFont(u8g2_font_unifont_t_symbols);
    u8g2.drawGlyph(100, 31, 0x2192); 
    u8g2.drawGlyph(100, 50, 0x2192); 
    u8g2.drawGlyph(87, 66, 0x2190); //fleche retour
u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.drawButtonUTF8(5,8, U8G2_BTN_INV, u8g2.getDisplayWidth()-2*5,7,1,"   CYCLE PROCTOR A");
  u8g2.drawStr(10, 28, "PROCTOR Normal    1");
  u8g2.drawStr(10, 47, "PROCTOR Modifie   2");
  u8g2.setFont(u8g2_font_04b_03_tr);
  u8g2.drawStr(79, 62, "0    retour");
  u8g2.sendBuffer();
}

void displayCbrMenu()
{ //menu 5
  u8g2.clearBuffer();
    u8g2.setFont(u8g2_font_unifont_t_symbols);
    u8g2.drawGlyph(100, 31, 0x2192); 
    u8g2.drawGlyph(100, 50, 0x2192); 
    u8g2.drawGlyph(87, 66, 0x2190); //fleche retour
u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.drawButtonUTF8(5,8, U8G2_BTN_INV, u8g2.getDisplayWidth()-2*5,7,1,"   CYCLE PROCTOR B");
  u8g2.drawStr(10, 28, "PROCTOR Normal    1");
  u8g2.drawStr(10, 47, "PROCTOR Modifie   2");
  u8g2.setFont(u8g2_font_04b_03_tr);
  u8g2.drawStr(79, 62, "0    retour");
  u8g2.sendBuffer();
}

void displayProctorNormal() 
{ // menu 6
  u8g2.clearBuffer();
      u8g2.setFont(u8g2_font_unifont_t_symbols);
    u8g2.drawGlyph(95, 26, 0x2192); 
    u8g2.drawGlyph(95, 39, 0x2192); 
    u8g2.drawGlyph(95, 53, 0x2192);
    u8g2.drawGlyph(87, 66, 0x2190); //fleche retour
u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.drawButtonUTF8(5,8, U8G2_BTN_INV, u8g2.getDisplayWidth()-2*5,7,1,"  PROCTOR A NORMAL");
  u8g2.drawStr(17, 23, "Info cycle        1");
  u8g2.drawStr(17, 36, "Lancer cycle     2 ");
  u8g2.drawStr(17, 50, "Initialisation    3 ");
  u8g2.setFont(u8g2_font_04b_03_tr);
  u8g2.drawStr(79, 62, "0    retour");
  u8g2.sendBuffer();
}

void displayProctorModifie() 
{ // menu 7
  u8g2.clearBuffer();
      u8g2.setFont(u8g2_font_unifont_t_symbols);
    u8g2.drawGlyph(95, 26, 0x2192); 
    u8g2.drawGlyph(95, 39, 0x2192); 
    u8g2.drawGlyph(95, 53, 0x2192);
    u8g2.drawGlyph(87, 66, 0x2190); //fleche retour
u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.drawButtonUTF8(5,8, U8G2_BTN_INV, u8g2.getDisplayWidth()-2*5,7,1,"  PROCTOR A MODIFIE");
  u8g2.drawStr(17, 23, "Info cycle        1");
  u8g2.drawStr(17, 36, "Lancer cycle     2 ");
  u8g2.drawStr(17, 50, "Initialisation    3 ");
  u8g2.setFont(u8g2_font_04b_03_tr);
  u8g2.drawStr(79, 62, "0    retour");
  u8g2.sendBuffer();
}

void displayCbrNormal() 
{ // menu 8
  u8g2.clearBuffer();
      u8g2.setFont(u8g2_font_unifont_t_symbols);
    u8g2.drawGlyph(95, 26, 0x2192); 
    u8g2.drawGlyph(95, 39, 0x2192); 
    u8g2.drawGlyph(95, 53, 0x2192);
    u8g2.drawGlyph(87, 66, 0x2190); //fleche retour
u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.drawButtonUTF8(5,8, U8G2_BTN_INV, u8g2.getDisplayWidth()-2*5,7,1,"  PROCTOR B NORMAL");
  u8g2.drawStr(17, 23, "Info cycle        1");
  u8g2.drawStr(17, 36, "Lancer cycle     2 ");
  u8g2.drawStr(17, 50, "Initialisation    3 ");
  u8g2.setFont(u8g2_font_04b_03_tr);
  u8g2.drawStr(79, 62, "0    retour");
  u8g2.sendBuffer();
}

void displayCbrModifie() 
{ // menu 9
  u8g2.clearBuffer();
      u8g2.setFont(u8g2_font_unifont_t_symbols);
    u8g2.drawGlyph(95, 26, 0x2192); 
    u8g2.drawGlyph(95, 39, 0x2192); 
    u8g2.drawGlyph(95, 53, 0x2192);
    u8g2.drawGlyph(87, 66, 0x2190); //fleche retour
u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.drawButtonUTF8(5,8, U8G2_BTN_INV, u8g2.getDisplayWidth()-2*5,7,1,"  PROCTOR B MODIFIE");
  u8g2.drawStr(17, 23, "Info cycle        1");
  u8g2.drawStr(17, 36, "Lancer cycle     2 ");
  u8g2.drawStr(17, 50, "Initialisation    3 ");
  u8g2.setFont(u8g2_font_04b_03_tr);
  u8g2.drawStr(79, 62, "0    retour");
  u8g2.sendBuffer();
}


void displayInfo1() 
{ //10
  u8g2.clearBuffer();
        u8g2.setFont(u8g2_font_unifont_t_symbols);
    u8g2.drawGlyph(87, 66, 0x2190); //fleche retour
u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.drawStr(3, 10, "3 couches");
  u8g2.drawStr(3, 23, "25 coups par couche");
  u8g2.drawStr(1, 40, "duree : 1min 10s");
  u8g2.drawStr(1, 50, "(duree / couche)");
  u8g2.setFont(u8g2_font_04b_03_tr);
  u8g2.drawStr(79, 62, "0    retour");
  u8g2.sendBuffer();
}

void displayInfo2() 
{ //13
  u8g2.clearBuffer();
          u8g2.setFont(u8g2_font_unifont_t_symbols);
    u8g2.drawGlyph(87, 66, 0x2190); //fleche retour
u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.drawStr(3, 10, "5 couches");
  u8g2.drawStr(3, 23, "25 coups par couche");
  u8g2.drawStr(1, 40, "duree : 1min 10s");
  u8g2.drawStr(1, 50, "(duree / couche)");
  u8g2.setFont(u8g2_font_04b_03_tr);
  u8g2.drawStr(79, 62, "0    retour");
  u8g2.sendBuffer();
}

void displayInfo3() 
{ //16
  u8g2.clearBuffer();
          u8g2.setFont(u8g2_font_unifont_t_symbols);
    u8g2.drawGlyph(87, 66, 0x2190); //fleche retour
u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.drawStr(3, 10, "3 couches");
  u8g2.drawStr(3, 23, "56 coups par couche");
  u8g2.drawStr(1, 40, "duree : 2min 50s");
  u8g2.drawStr(1, 50, "(duree / couche)");
  u8g2.setFont(u8g2_font_04b_03_tr);
  u8g2.drawStr(79, 62, "0    retour");
  u8g2.sendBuffer();
}

void displayInfo4() 
{ //19
  u8g2.clearBuffer();
          u8g2.setFont(u8g2_font_unifont_t_symbols);
    u8g2.drawGlyph(87, 66, 0x2190); //fleche retour
u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.drawStr(3, 10, "5 couches");
  u8g2.drawStr(3, 23, "56 coups par couche");
  u8g2.drawStr(1, 40, "duree : 2min 50s");
  u8g2.drawStr(1, 50, "(duree / couche)");
  u8g2.setFont(u8g2_font_04b_03_tr);
  u8g2.drawStr(79, 62, "0    retour");
  u8g2.sendBuffer();
}


void displayStart1() 
{ //14
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.drawButtonUTF8(5,8, U8G2_BTN_INV, u8g2.getDisplayWidth()-2*5,7,1,"  PROCTOR A NORMAL");
  u8g2.drawStr(20, 35, "CYCLE EN COURS");
  u8g2.drawStr(2, 54, "ne pas ouvrir la porte");
  u8g2.sendBuffer();
}

void displayStart2() 
{ //14
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.drawButtonUTF8(5,8, U8G2_BTN_INV, u8g2.getDisplayWidth()-2*5,7,1,"  PROCTOR A MODIFIE");
  u8g2.drawStr(20, 35, "CYCLE EN COURS");
  u8g2.drawStr(2, 54, "ne pas ouvrir la porte");
  u8g2.sendBuffer();
}

void displayStart3() 
{ //17
  u8g2.clearBuffer();
u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.drawButtonUTF8(5,8, U8G2_BTN_INV, u8g2.getDisplayWidth()-2*5,7,1,"  PROCTOR B NORMAL");
  u8g2.drawStr(20, 35, "CYCLE EN COURS");
  u8g2.drawStr(2, 54, "ne pas ouvrir la porte");
  u8g2.sendBuffer();
}

void displayStart4() 
{ //20
  u8g2.clearBuffer();
 u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.drawButtonUTF8(5,8, U8G2_BTN_INV, u8g2.getDisplayWidth()-2*5,7,1,"  PROCTOR B MODIFIE");
  u8g2.drawStr(20, 35, "CYCLE EN COURS");
  u8g2.drawStr(2, 54, "ne pas ouvrir la porte");
  u8g2.sendBuffer();
}



void displayInit1() 
{ //12 
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.drawButtonUTF8(5,8, U8G2_BTN_INV, u8g2.getDisplayWidth()-2*5,7,1,"    INITIALISATION");
  u8g2.drawStr(24, 30, "INITIALISATION");
  u8g2.drawStr(40, 41, "EN COURS");
    u8g2.drawStr(2, 58, "ne pas ouvrir la porte");
  u8g2.sendBuffer();
}

void displayInit2() 
{ //15
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.drawButtonUTF8(5,8, U8G2_BTN_INV, u8g2.getDisplayWidth()-2*5,7,1,"    INITIALISATION");
  u8g2.drawStr(24, 30, "INITIALISATION");
  u8g2.drawStr(40, 41, "EN COURS");
    u8g2.drawStr(2, 58, "ne pas ouvrir la porte");
  u8g2.sendBuffer();
}

void displayInit3() 
{ //18
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.drawButtonUTF8(5,8, U8G2_BTN_INV, u8g2.getDisplayWidth()-2*5,7,1,"    INITIALISATION");
  u8g2.drawStr(24, 30, "INITIALISATION");
  u8g2.drawStr(40, 41, "EN COURS");
    u8g2.drawStr(2, 58, "ne pas ouvrir la porte");
  u8g2.sendBuffer();
}

void displayInit4() 
{ //21
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.drawButtonUTF8(5,8, U8G2_BTN_INV, u8g2.getDisplayWidth()-2*5,7,1,"    INITIALISATION");
  u8g2.drawStr(24, 30, "INITIALISATION");
  u8g2.drawStr(40, 41, "EN COURS");
    u8g2.drawStr(2, 58, "ne pas ouvrir la porte");
  u8g2.sendBuffer();
}


int cycleCounter = 0; 
void displayContinueCycle1() 
{ //22
u8g2.clearBuffer();
        u8g2.setFont(u8g2_font_unifont_t_symbols);
    u8g2.drawGlyph(98, 52, 0x2192); 
    u8g2.drawGlyph(98, 64, 0x2192); 
      u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.drawButtonUTF8(5,8, U8G2_BTN_INV, u8g2.getDisplayWidth()-2*5,7,1,"   COUCHE TERMINE");
 u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.setCursor(30, 32);
  u8g2.print("Couche : ");
  u8g2.print(cycleCounter); // Affiche la valeur du compteur
  u8g2.drawStr(85, 32, "/3");
  u8g2.drawStr(10, 49, "Continuer cycle    1");
  u8g2.drawStr(10, 61, "Annuler cycle      A");
  u8g2.sendBuffer();
}

void displayContinueCycle2() 
{ //23
u8g2.clearBuffer();
        u8g2.setFont(u8g2_font_unifont_t_symbols);
    u8g2.drawGlyph(98, 52, 0x2192); 
    u8g2.drawGlyph(98, 64, 0x2192); 
      u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.drawButtonUTF8(5,8, U8G2_BTN_INV, u8g2.getDisplayWidth()-2*5,7,1,"   COUCHE TERMINE");
 u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.setCursor(30, 32);
  u8g2.print("Couche : ");
  u8g2.print(cycleCounter); // Affiche la valeur du compteur
  u8g2.drawStr(85, 32, "/5");
  u8g2.drawStr(10, 49, "Continuer cycle    1");
  u8g2.drawStr(10, 61, "Annuler cycle      A");
  u8g2.sendBuffer();
}

void displayContinueCycle3() 
{ //24
u8g2.clearBuffer();
        u8g2.setFont(u8g2_font_unifont_t_symbols);
    u8g2.drawGlyph(98, 52, 0x2192); 
    u8g2.drawGlyph(98, 64, 0x2192); 
      u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.drawButtonUTF8(5,8, U8G2_BTN_INV, u8g2.getDisplayWidth()-2*5,7,1,"   COUCHE TERMINE");
 u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.setCursor(30, 32);
  u8g2.print("Couche : ");
  u8g2.print(cycleCounter); // Affiche la valeur du compteur
  u8g2.drawStr(85, 32, "/3");
  u8g2.drawStr(10, 49, "Continuer cycle    1");
  u8g2.drawStr(10, 61, "Annuler cycle      A");
  u8g2.sendBuffer();
}

void displayContinueCycle4() 
{ //25
u8g2.clearBuffer();
        u8g2.setFont(u8g2_font_unifont_t_symbols);
    u8g2.drawGlyph(98, 52, 0x2192); 
    u8g2.drawGlyph(98, 64, 0x2192); 
      u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.drawButtonUTF8(5,8, U8G2_BTN_INV, u8g2.getDisplayWidth()-2*5,7,1,"   COUCHE TERMINE");
 u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.setCursor(30, 32);
  u8g2.print("Couche : ");
  u8g2.print(cycleCounter); // Affiche la valeur du compteur
  u8g2.drawStr(85, 32, "/5");
  u8g2.drawStr(10, 49, "Continuer cycle    1");
  u8g2.drawStr(10, 61, "Annuler cycle      A");
  u8g2.sendBuffer();
}



void displayFinCycle1() 
{ //15
 u8g2.clearBuffer();
         u8g2.setFont(u8g2_font_unifont_t_symbols);
    u8g2.drawGlyph(44, 53, 0x2190); //fleche retour
  u8g2.setFont(u8g2_font_ncenB10_tr);
  u8g2.drawStr(20, 30, "FIN CYCLE");
  u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.drawStr(32, 50, "0    retour");
  u8g2.sendBuffer();
}

void displayFinCycle2() 
{ //15
 u8g2.clearBuffer();
         u8g2.setFont(u8g2_font_unifont_t_symbols);
    u8g2.drawGlyph(44, 53, 0x2190); //fleche retour
  u8g2.setFont(u8g2_font_ncenB10_tr);
  u8g2.drawStr(20, 30, "FIN CYCLE");
   u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.drawStr(32, 50, "0    retour");
  u8g2.sendBuffer();
}

void displayFinCycle3() 
{ //15
 u8g2.clearBuffer();
         u8g2.setFont(u8g2_font_unifont_t_symbols);
    u8g2.drawGlyph(44, 53, 0x2190); //fleche retour
  u8g2.setFont(u8g2_font_ncenB10_tr);
  u8g2.drawStr(20, 30, "FIN CYCLE");
   u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.drawStr(32, 50, "0    retour");
  u8g2.sendBuffer();
}

void displayFinCycle4() 
{ //15
 u8g2.clearBuffer();
         u8g2.setFont(u8g2_font_unifont_t_symbols);
    u8g2.drawGlyph(44, 53, 0x2190); //fleche retour
  u8g2.setFont(u8g2_font_ncenB10_tr);
  u8g2.drawStr(20, 30, "FIN CYCLE");
   u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.drawStr(32, 50, "0    retour");
  u8g2.sendBuffer();
}


void displayTestMoteur() 
{ //menu 33
  u8g2.clearBuffer();
    u8g2.setFont(u8g2_font_unifont_t_symbols);
    //vers gauche 
    u8g2.drawGlyph(12, 27, 0x2190); 
    u8g2.drawGlyph(12, 40, 0x2190); 
    u8g2.drawGlyph(12, 52, 0x2190); 
    u8g2.drawGlyph(12, 64, 0x2190); 
    //vers droite 
    u8g2.drawGlyph(105, 27, 0x2192); 
    u8g2.drawGlyph(105, 40, 0x2192); 
    u8g2.drawGlyph(105, 52, 0x2192); 
    u8g2.drawGlyph(105, 64, 0x2192); 
 u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.drawButtonUTF8(5,8, U8G2_BTN_INV, u8g2.getDisplayWidth()-2*5,7,1,"     TEST MOTEURS");
  u8g2.drawStr(3, 25, "1    Rotation| Stop   1");
  u8g2.drawStr(70, 37, "|");
  u8g2.drawStr(3, 37, "2   Avancer   Stop   2");
  u8g2.drawStr(3, 49, "3   Reculer | Stop   3");
  u8g2.drawStr(4, 61, "A   Battage | Stop   A");
  u8g2.sendBuffer();
}

void displayTestCapteur() 
{ //menu 33
  u8g2.clearBuffer();
    u8g2.setFont(u8g2_font_unifont_t_symbols);
    //vers gauche 
    u8g2.drawGlyph(12, 27, 0x2190); 
    u8g2.drawGlyph(12, 40, 0x2190); 
    u8g2.drawGlyph(12, 52, 0x2190); 
 u8g2.drawGlyph(87, 66, 0x2190); //fleche retour
 u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.drawButtonUTF8(5,8, U8G2_BTN_INV, u8g2.getDisplayWidth()-2*5,7,1,"     TEST CAPTEURS");
  u8g2.drawStr(3, 25, "1    Capteur Centre");
  u8g2.drawStr(3, 37, "2   Capteur Type A");
  u8g2.drawStr(3, 49, "3   Capteur Type B");
  u8g2.setFont(u8g2_font_04b_03_tr);
  u8g2.drawStr(79, 62, "0    retour");
  u8g2.sendBuffer();
}


//____________________________________ CODE COMPACTEUR _____________________________________________//

const int numInputs = 6;
const int analogIn[numInputs] = {A0, A1, A2, A8, A4, A5};
const int numOutputs = 4;
const int DigitalOut[numOutputs] = {2, 3, 4, 5};
bool capteurDame = false;

int val = 0;
float voltage = 0.0;

bool readanalogInA1() //capteur 6, rouge
{
  val = analogRead(A1);
  voltage = val * (5.0 / 1023.0);
  return voltage > 4.97;
}

bool readanalogInA0() //capteur 4, bleu 
{
  val = analogRead(A0);
  voltage = val * (5.0 / 1023.0);
  return voltage > 4.97;
}

bool readanalogInA2() //capteur centre, gris
{
  val = analogRead(A2);
  voltage = val * (5.0 / 1023.0);
  return voltage > 4.97;
}

bool readanalogInA8() //capteur Dame, blancOUnoir
{
  val = analogRead(A8);
  voltage = val * (5.0 / 1023.0);
  return voltage > 4.97;
}

void moteur(int *DigitalOut, bool moteuron) 
{
    analogWrite(*DigitalOut, moteuron ? 255 : 0);
}

void readKp4x4() { /* function readKp4x4 */
  //// Read button states from keypad
  char key = kp4x4.getKey();
  if (key) {
    Serial.println(key);
  }
}
/*
char readKey() 
{
      char key = kp4x4.getKey();

    if (key) 
    {
        Serial.println(key);
    }
    return key;
}*/

void rotation_1sur6()
{
    //delay(50);
    moteur(&DigitalOut[0], true);
    delay(340);
    moteur(&DigitalOut[0], false);
}

void rotation_1sur12()
{
    moteur(&DigitalOut[0], true);
    delay(140);
    moteur(&DigitalOut[0], false);
}

void rotation_1sur4()
{
    moteur(&DigitalOut[0], true);
    delay(550);
    moteur(&DigitalOut[0], false);
}

void translationAvantJusquaCapteurA0() 
{
    int count_5V = 0;

    while (count_5V < 2) 
    {
        float tension = analogRead(A0) * (5.0 / 1023.0);

       // Serial.print("Tension : ");
       //Serial.println(tension, 2);

        if (tension >= 4.97) 
        {
            count_5V++;
            //Serial.println("Voltage 5V");
        } 
        else 
        {
            count_5V = 0; // Réinitialiser le compteur si la tension n'est pas de 5V
        }

        //Serial.print("Nombre de fois à 5V : ");
        //Serial.println(count_5V);

        if (count_5V == 2) 
        {
            //Serial.println("Moteur coupé");
            moteur(&DigitalOut[2], false);
        } 
        else 
        {
            moteur(&DigitalOut[2], true);
        }

        delay(50); // Attendre avant la prochaine lecture
    }
}

bool derniere_mesure;
float seuil=4.97;
bool A2_vrai;
int compte_5V = 0;
bool A1_vrai = false;

void translationAvantJusquaCapteurA1() 
{
    int count_5V = 0;

    while (count_5V < 3) 
    {
        float tension = analogRead(A1) * (5.0 / 1023.0);

        //Serial.print("Tension : ");
        //Serial.println(tension, 2);

        if (tension >= 4.97) 
        {
            count_5V++;
            //Serial.println("Voltage 5V");
        } 
        else 
        {
            count_5V = 0; // Réinitialiser le compteur si la tension n'est pas de 5V
        }

        //Serial.print("Nombre de fois à 5V : ");
        //Serial.println(count_5V);

        if (count_5V == 3) 
        {
            //Serial.println("Moteur coupé");
            moteur(&DigitalOut[2], false);
        } 
        else 
        {
            moteur(&DigitalOut[2], true);
        }

        delay(50); // Attendre avant la prochaine lecture
    }
}


void TranslationArriereJusquaCapteurA2()
{
    int count_5V = 0;

    while (count_5V < 2) 
    {
        float tension = analogRead(A2) * (5.0 / 1023.0);

        //Serial.print("Tension : ");
        //Serial.println(tension, 2);

        if (tension >= 4.97) 
        {
            count_5V++;
            //Serial.println("Voltage 5V");
        } else {
            count_5V = 0; // Réinitialiser le compteur si la tension n'est pas de 5V
        }

        //Serial.print("Nombre de fois à 5V : ");
        //Serial.println(count_5V);

        if (count_5V == 02) 
        {
            //Serial.println("Moteur coupé");
            moteur(&DigitalOut[1], false);
        } 
        else 
        {
            moteur(&DigitalOut[1], true);
        }

        delay(13); // Attendre avant la prochaine lecture
    }
}

void moveA1toA0() {
    if (analogRead(A1) * (5.0 / 1023.0) >= seuil) {
        // Si le capteur est sur A1, alors passer par A2 avant d'aller à A0
        while (analogRead(A2) * (5.0 / 1023.0) < seuil) {
            // Tant que le capteur n'est pas sur A2
            TranslationArriereJusquaCapteurA2();
        }
    }

    // Maintenant, aller directement à A0 depuis A1 ou A2
    while (analogRead(A0) * (5.0 / 1023.0) < seuil) {
        // Tant que le capteur n'est pas sur A0
        translationAvantJusquaCapteurA0();
    }
}



void frapperUneFois() 
{
    int count_5V = 0;

    moteur(&DigitalOut[3], true); // Active le moteur pour frapper
    delay(50);

    while (count_5V < 2) 
    {
        float tension = analogRead(A8) * (5.0 / 1023.0); // Lecture de la tension sur le capteur A8

        //Serial.print("Tension A8 : ");
        //Serial.println(tension, 2);

        if (tension >= 4.97) 
        {
            count_5V++;
            //Serial.println("Voltage 5V A8");
        } 
        else 
        {
            count_5V = 0; // Réinitialiser le compteur si la tension n'est pas de 5V
        }

        //Serial.print("Nombre de fois à 5V A8 : ");
        //Serial.println(count_5V);

        if (count_5V == 2) 
        {
            delay(550);
            //Serial.println("Moteur coupé A8");
            moteur(&DigitalOut[3], false);
        } 
        else 
        {
            moteur(&DigitalOut[3], true);
        }

        delay(50); // Attendre avant la prochaine lecture de tension
    }

    moteur(&DigitalOut[3], false); // Désactive le moteur après la vérification
}

void battageETrotation() 
{
    int count_5V = 0;

    moteur(&DigitalOut[3], true); // Active le moteur pour frapper
    delay(50);

    while (count_5V < 2) 
    {
        float tension = analogRead(A8) * (5.0 / 1023.0); // Lecture de la tension sur le capteur A8

        //Serial.print("Tension A8 : ");
        //Serial.println(tension, 2);

        if (tension >= 4.97) 
        {
            count_5V++;
            //Serial.println("Voltage 5V A8");
        } 
        else 
        {
            count_5V = 0; // Réinitialiser le compteur si la tension n'est pas de 5V
        }

        //Serial.print("Nombre de fois à 5V A8 : ");
        //Serial.println(count_5V);

        if (count_5V == 2) 
        {
            delay(100);
            rotation_1sur6();
            delay(100);
            //Serial.println("Moteur coupé A8");
            moteur(&DigitalOut[3], false);
        } 
        else 
        {
            moteur(&DigitalOut[3], true);
        }

        delay(50); // Attendre avant la prochaine lecture de tension
    }

    moteur(&DigitalOut[3], false); // Désactive le moteur après la vérification
}


void battageETrotation4() 
{
    int count_5V = 0;

    moteur(&DigitalOut[3], true); // Active le moteur pour frapper
    delay(50);

    while (count_5V < 2) 
    {
        float tension = analogRead(A8) * (5.0 / 1023.0); // Lecture de la tension sur le capteur A8

        //Serial.print("Tension A8 : ");
        //Serial.println(tension, 2);

        if (tension >= 4.97) 
        {
            count_5V++;
            //Serial.println("Voltage 5V A8");
        } 
        else 
        {
            count_5V = 0; // Réinitialiser le compteur si la tension n'est pas de 5V
        }

        //Serial.print("Nombre de fois à 5V A8 : ");
        //Serial.println(count_5V);

        if (count_5V == 2) 
        {
            delay(100);
            rotation_1sur4();
            delay(100);
            //Serial.println("Moteur coupé A8");
            moteur(&DigitalOut[3], false);
        } 
        else 
        {
            moteur(&DigitalOut[3], true);
        }

        delay(50); // Attendre avant la prochaine lecture de tension
    }

    moteur(&DigitalOut[3], false); // Désactive le moteur après la vérification
}

void duree(int temps)
{
   delay(100*temps);
}

void cycle6()
{
  Serial.println("avancer au capteur A1");
  translationAvantJusquaCapteurA1();

    Serial.println("battage+rotation1/6  1");
  battageETrotation(); //1
  duree(1);
    Serial.println("battage+rotation1/6  2");
  battageETrotation(); //2
  duree(1);
    Serial.println("battage+rotation1/6  3");
  battageETrotation(); //3
  duree(1);
    Serial.println("battage+rotation1/6  4");
  battageETrotation(); //4
  duree(1);
    Serial.println("battage+rotation1/6  5");
  battageETrotation(); //5
  duree(1);
    Serial.println("battage+rotation1/6  6");
  frapperUneFois(); //6
  duree(1);

Serial.println("rotation de 1/12");
        duree(1); 
        rotation_1sur12(); 
        delay(100);
         Serial.println("reculer au centre");
        TranslationArriereJusquaCapteurA2();
        duree(2);
         Serial.println("battage central");
        moteur(&DigitalOut[3], true); 
        delay(2500); 
        moteur(&DigitalOut[3], false);
}


void cycle4()
{
    Serial.println("avancer au capteur A0");
    duree(1);
    translationAvantJusquaCapteurA0();
    duree(1);

for (int i = 0; i < 3; i++) 
  {
Serial.println("battage+rotation1/4  1");
    battageETrotation4(); //1
    duree(1);
Serial.println("battage+rotation1/4  2");
    battageETrotation4();//2
    duree(1);
Serial.println("battage+rotation1/4  3");
    battageETrotation4(); //3
    duree(1); 
Serial.println("battage+rotation1/4  4");
    battageETrotation4(); //4
    duree(1);
Serial.println("battage+rotation1/4  5");
    battageETrotation4(); //5
    duree(1);
Serial.println("battage+rotation1/4  6");
    battageETrotation4(); //6 
    duree(1); 
Serial.println("battage+rotation1/4  7");
    battageETrotation4(); //7
    duree(1);  
Serial.println("battage+rotation1/4  8");
    frapperUneFois(); //8
    duree(1);
 
    // Maintenant, effectuer la rotation 1/12
    Serial.println("rotation 1/12");
    rotation_1sur12();
  }
    //mise au centre pour le 25eme coups
    Serial.println("battage central");
    duree(1); 
    TranslationArriereJusquaCapteurA2();
    duree(1); 
    frapperUneFois();
}


void initialiserCompacteur()
{ bool A2_vrai = false;
  duree(1);
  Serial.println("initialisation dame");
  frapperUneFois();
  duree(1);
  unsigned long startTime = millis(); // Enregistre le temps actuel (en millisecondes) au moment où la touche 'C' est pressée.
  Serial.println("retour au centre");
  TranslationArriereJusquaCapteurA2();
}


bool stopManuel = false;
void translationManuAvantJusquaCapteurA1() 
{
  stopManuel = false;
    int count_5V = 0;

    while (count_5V < 3 && !stopManuel) 
    {
        float tension = analogRead(A1) * (5.0 / 1023.0);

        // Ajouter la vérification de la touche pour l'arrêt manuel
          char key = kp4x4.getKey();

        if (key == '2') 
        { // Remplacez 'X' par la touche antagoniste dédiée à l'arrêt manuel
            stopManuel = true;
        }

        if (tension >= 4.97) 
        {
            count_5V++;
        } 
        else 
        {
            count_5V = 0; // Réinitialiser le compteur si la tension n'est pas de 5V
        }

        if (count_5V == 3 || stopManuel) 
        {
            moteur(&DigitalOut[2], false); // Arrêt du moteur
        } 
        else 
        {
            moteur(&DigitalOut[2], true); // Continuer le mouvement
        }

        delay(50); // Attendre avant la prochaine lecture
    }
}

void TranslationManuArriereJusquaCapteurA2() 
{
  stopManuel = false;
    int count_5V = 0;

    while (count_5V < 2 && !stopManuel) 
    {
        float tension = analogRead(A2) * (5.0 / 1023.0);

        // Ajouter la vérification de la touche pour l'arrêt manuel
          char key = kp4x4.getKey();

        if (key == '3') 
        { // Remplacez 'Y' par la touche antagoniste pour l'arrêt manuel en reculant vers A2
            stopManuel = true;
        }

        if (tension >= 4.97) 
        {
            count_5V++;
        } 
        else 
        {
            count_5V = 0; // Réinitialiser le compteur si la tension n'est pas de 5V
        }

        if (count_5V == 2 || stopManuel) 
        {
            moteur(&DigitalOut[1], false); // Arrêt du moteur en reculant
        } 
        else 
        {
            moteur(&DigitalOut[1], true); // Continuer le mouvement
        }

        delay(50); // Attendre avant la prochaine lecture
    }
}

bool moteur0_enMarche = false;

void toggleMoteur0() 
{
    moteur0_enMarche = !moteur0_enMarche; // Basculement (Inversion de l'état)
    if (moteur0_enMarche) 
    {
        // Si le moteur est maintenant censé être en marche, démarrez-le
        moteur(&DigitalOut[0], true); // Démarrer le moteur 0
    } 
    else 
    {
        // Sinon, arrêtez-le
        moteur(&DigitalOut[0], false); // Arrêter le moteur 0
    }
    delay(100); // Délai pour éviter les rebonds de touche
}

bool moteur3_enMarche = false;

void toggleMoteur3() 
{
    moteur3_enMarche = !moteur3_enMarche; // Basculement (Inversion de l'état)
    if (moteur3_enMarche) 
    {
        // Si le moteur est maintenant censé être en marche, démarrez-le
        moteur(&DigitalOut[3], true); // Démarrer le moteur 3
    } 
    else 
    {
        // Sinon, arrêtez-le
        moteur(&DigitalOut[3], false); // Arrêter le moteur 3
    }
    delay(100); // Délai pour éviter les rebonds de touche
}

// interruption porte
const int portDeTest = 20;  
//volatile bool doorOpen = false;
int loopCounter = 0;

/*
void checkDoor()
 {
	while (digitalRead(portDeTest) == HIGH)
	{
        //coupe moteur sécurité
	analogWrite(DigitalOut[0] , false);
    analogWrite(DigitalOut[1] , false);
    analogWrite(DigitalOut[2] , false);
    analogWrite(DigitalOut[3] , false);
	}
}*/

bool porteOuverte = false;

void checkDoor() 
{
    if (digitalRead(portDeTest) == HIGH) 
    {
        // La porte est ouverte
        while (digitalRead(portDeTest) == HIGH) 
        {
            analogWrite(DigitalOut[0], false);
            analogWrite(DigitalOut[1], false);
            analogWrite(DigitalOut[2], false);
            analogWrite(DigitalOut[3], false);

            if (currentMenu == START_cycle1 && !porteOuverte) 
            {
                porteOuverte = true;
                // Affiche "Porte ouverte"
                u8g2.clearBuffer();
                u8g2.drawStr(10, 20, "! PORTE OUVERTE !");
                u8g2.drawStr(10, 45, "veuillez refermer");
                u8g2.drawStr(13, 60, "la porte");
                u8g2.sendBuffer();
            }

            if (currentMenu == START_cycle2 && !porteOuverte) 
            {
                porteOuverte = true;
                // Affiche "Porte ouverte"
                u8g2.clearBuffer();
                u8g2.drawStr(10, 20, "! PORTE OUVERTE !");
                u8g2.drawStr(10, 45, "veuillez refermer");
                u8g2.drawStr(13, 60, "la porte");
                u8g2.sendBuffer();
            }

            if (currentMenu == START_cycle3 && !porteOuverte) 
            {
                porteOuverte = true;
                // Affiche "Porte ouverte"
                u8g2.clearBuffer();
                u8g2.drawStr(10, 20, "! PORTE OUVERTE !");
                u8g2.drawStr(10, 45, "veuillez refermer");
                u8g2.drawStr(13, 60, "la porte");
                u8g2.sendBuffer();
            }

            if (currentMenu == START_cycle4 && !porteOuverte) 
            {
                porteOuverte = true;
                // Affiche "Porte ouverte"
                u8g2.clearBuffer();
                u8g2.drawStr(10, 20, "! PORTE OUVERTE !");
                u8g2.drawStr(10, 45, "veuillez refermer");
                u8g2.drawStr(13, 60, "la porte");
                u8g2.sendBuffer();
            }


            if (currentMenu == INIT_1 && !porteOuverte) 
            {
                porteOuverte = true;
                // Affiche "Porte ouverte"
                u8g2.clearBuffer();
                u8g2.drawStr(10, 20, "! PORTE OUVERTE !");
                u8g2.drawStr(10, 45, "veuillez refermer");
                u8g2.drawStr(13, 60, "la porte");
                u8g2.sendBuffer();
            }

            if (currentMenu == INIT_2 && !porteOuverte) 
            {
                porteOuverte = true;
                // Affiche "Porte ouverte"
                u8g2.clearBuffer();
                u8g2.drawStr(10, 20, "! PORTE OUVERTE !");
                u8g2.drawStr(10, 45, "veuillez refermer");
                u8g2.drawStr(13, 60, "la porte");
                u8g2.sendBuffer();
            }

            if (currentMenu == INIT_3 && !porteOuverte) 
            {
                porteOuverte = true;
                // Affiche "Porte ouverte"
                u8g2.clearBuffer();
                u8g2.drawStr(10, 20, "! PORTE OUVERTE !");
                u8g2.drawStr(10, 45, "veuillez refermer");
                u8g2.drawStr(13, 60, "la porte");
                u8g2.sendBuffer();
            }

            if (currentMenu == INIT_4 && !porteOuverte) 
            {
                porteOuverte = true;
                // Affiche "Porte ouverte"
                u8g2.clearBuffer();
                u8g2.drawStr(10, 20, "! PORTE OUVERTE !");
                u8g2.drawStr(10, 45, "veuillez refermer");
                u8g2.drawStr(13, 60, "la porte");
                u8g2.sendBuffer();
            }
        }
    } 
    else 
    {
        // La porte est fermée
        if (currentMenu == START_cycle1 && porteOuverte) 
        {
            porteOuverte = false;
            displayStart1(); // Affiche à nouveau l'écran StartCycle1
        }

        if (currentMenu == START_cycle2 && porteOuverte) 
        {
            porteOuverte = false;
            displayStart2(); // Affiche à nouveau l'écran StartCycle1
        }

        if (currentMenu == START_cycle3 && porteOuverte) 
        {
            porteOuverte = false;
            displayStart3(); // Affiche à nouveau l'écran StartCycle1
        }

        if (currentMenu == START_cycle3 && porteOuverte) 
        {
            porteOuverte = false;
            displayStart4(); // Affiche à nouveau l'écran StartCycle1
        }

        if (currentMenu == INIT_1 && porteOuverte) 
        {
            porteOuverte = false;
            displayInit1(); // Affiche à nouveau l'écran StartCycle1
        }

        if (currentMenu == INIT_2 && porteOuverte) 
        {
            porteOuverte = false;
            displayInit2(); // Affiche à nouveau l'écran StartCycle1
        }

        if (currentMenu == INIT_3 && porteOuverte) 
        {
            porteOuverte = false;
            displayInit3(); // Affiche à nouveau l'écran StartCycle1
        }

        if (currentMenu == INIT_4 && porteOuverte) 
        {
            porteOuverte = false;
            displayInit4(); // Affiche à nouveau l'écran StartCycle1
        }
    }
}


void setup() 
{
  u8g2.begin();
  u8g2.setFont(u8g2_font_crox4tb_tr);
  u8g2.drawStr(15, 40, "PROVITEQ");  // Affiche "PROVITEQ" aux coordonnées x=15 et y=40
  u8g2.sendBuffer();  // Envoie le contenu du tampon pour l'affichage
  delay(1600);  // Pause de 1300 millisecondes
  u8g2.clearBuffer();  // Efface le contenu de l'écran
  displayMainMenu();  // Affiche le menu principal
  pinMode(LED_BUILTIN, OUTPUT);
      for (int i = 0; i < numOutputs; i++) 
    {
        pinMode(DigitalOut[i], OUTPUT);
    }
    Serial.begin(9600);
    Serial.println(F("Initialize System"));
    Serial.println("Please press the keyboard:");
    analogWrite(DigitalOut[0] , 0);
    analogWrite(DigitalOut[1] , 0);
    analogWrite(DigitalOut[2] , 0);
    analogWrite(DigitalOut[3] , 0);
    pinMode(portDeTest, INPUT_PULLUP);
	attachInterrupt(digitalPinToInterrupt(portDeTest), checkDoor, RISING);     

}



void loop() 
{
	//Serial.println("Loop() " + String(loopCounter));
	//delay(250);
	//loopCounter ++;

    /*
if (doorOpen) {
    Serial.println("La porte est ouverte, le programme est en pause...");
    while (doorOpen) {
      doorOpen = digitalRead(portDeTest) == HIGH;
      delay(100); 
    }
    Serial.println("La porte est fermée, le programme reprend.");
  }
*/
    readKp4x4();

    char key = kp4x4.getKey();

  if (key) 
  {
        if (key == '0') 
        {
      // Go back to the previous menu
      switch (currentMenu) 
      {
        case INFO_MENU:
        case START_MENU:
        case TEST_MENU:
          currentMenu = MAIN_MENU;
          displayMainMenu();
          break;

        case TEST_MOTEUR:
        case TEST_CAPTEUR:
          currentMenu = TEST_MENU;
          displayTestMenu();
          break;

        case PROCTOR_MENU:
        case CBR_MENU:
          currentMenu = START_MENU;
          displayStartMenu();
          break;

        case PROCTOR_NORMAL:
        case PROCTOR_MODIFIE:
        currentMenu = PROCTOR_MENU;
          displayProctorMenu();
          break;

        case CBR_NORMAL:
        case CBR_MODIFIE:
          currentMenu = CBR_MENU;
          displayCbrMenu();
          break;

        case INFO_CYCLE1:
        case INFO_CYCLE2:
        case INFO_CYCLE3:
        case INFO_CYCLE4:
        case START_cycle1:
        case START_cycle2:
        case START_cycle3:
        case START_cycle4:
        case INIT_1:
        case INIT_2:
        case INIT_3:
        case INIT_4:


          // Going back to respective parent menu
          if (currentMenu == INFO_CYCLE1 || currentMenu == START_cycle1 || currentMenu == INIT_1) 
          {
            currentMenu = PROCTOR_NORMAL;
            displayProctorNormal();
          } else if (currentMenu == INFO_CYCLE2 || currentMenu == START_cycle2 || currentMenu == INIT_2) 
          {
            currentMenu = PROCTOR_MODIFIE;
            displayProctorModifie();
          } else if (currentMenu == INFO_CYCLE3 || currentMenu == START_cycle3 || currentMenu == INIT_3) 
          {
            currentMenu = CBR_NORMAL;
            displayCbrNormal();
          } else if (currentMenu == INFO_CYCLE4 || currentMenu == START_cycle4 || currentMenu == INIT_4) 
          {
            currentMenu = CBR_MODIFIE;
            displayCbrModifie();
          }
          break;

        default:
          break;
      }
    } 
    else 
    {
      switch (currentMenu) 
      {
        case MAIN_MENU:
          if (key == '1') 
          {
            currentMenu = INFO_MENU;
            displayInfoMenu();
          } else if (key == '2') 
          {
            currentMenu = START_MENU;
            displayStartMenu();
          } else if (key == '3') 
          {
            currentMenu = TEST_MENU;
            displayTestMenu();
          }
          break;

        case INFO_MENU:
          // Logique pour le menu d'informations
          break;

        case START_MENU:
          if (key == '1') 
          {
            currentMenu = PROCTOR_MENU;
            displayProctorMenu();
          } else if (key == '2') 
          {
            currentMenu = CBR_MENU;
            displayCbrMenu();
          }
          break;

        case TEST_MENU:
        if (key == '1') 
          {
            currentMenu = TEST_MOTEUR;
            displayTestMoteur();
          } else if 
          (key == '2') 
          {
            currentMenu = TEST_CAPTEUR;
            displayTestCapteur();
          }
          break;

        case TEST_MOTEUR:
          // Logique pour le menu de test
          if (key == '1')
          {
            toggleMoteur0();
          }
          if (key == '2')
          {
            translationManuAvantJusquaCapteurA1(); 
          }
          if (key == '3')
          {
            TranslationManuArriereJusquaCapteurA2();
          }
          if (key == 'A')
          {
            toggleMoteur3();
          }

          break;

        case TEST_CAPTEUR:
        if (key == '1')
          {
            TranslationManuArriereJusquaCapteurA2();
          }
          if (key == '2')
          {

           moveA1toA0();
          }
          if (key == '3')
          {
            translationManuAvantJusquaCapteurA1(); 
          }
          break;
        

        case PROCTOR_MENU:
          if (key == '1') 
          {
            currentMenu = PROCTOR_NORMAL;
            displayProctorNormal();
          } 
          else if (key == '2') 
          {
            currentMenu = PROCTOR_MODIFIE;
            displayProctorModifie();
          }
          break;

        case CBR_MENU:
          if (key == '1') 
          {
            currentMenu = CBR_NORMAL;
            displayCbrNormal();
          } 
          else if (key == '2') 
          {
            currentMenu = CBR_MODIFIE;
            displayCbrModifie();
          }
          break;


        case PROCTOR_NORMAL:
  if (key == '1') {
    currentMenu = INFO_CYCLE1;
    displayInfo1();
  } else if (key == '2') {
    cycleCounter = 0;
    currentMenu = START_cycle1;
    displayStart1();
    Serial.println("CYCLE 4 COMMENCÉ");
      cycle4();
      duree(1);
    Serial.println("CYCLE 4 TERMINÉ");  
    currentMenu = CONTINUE_CYCLE_1; // Afficher le menu "CONTINUE_CYCLE_1" après la fin du cycle
    cycleCounter++; // Incrémente le compteur à chaque fois que le cycle est terminé
    displayContinueCycle1();
  } else if (key == '3') {
    currentMenu = INIT_1;
    displayInit1();
    Serial.println("INITIALISATION COMMENCÉE");
    initialiserCompacteur();
    Serial.println("INITIALISATION TERMINÉE");
    currentMenu = PROCTOR_NORMAL;
    displayProctorNormal();
  }
  break;

// Ajoutez ensuite dans la partie où vous gérez CONTINUE_CYCLE_1 pour gérer le compteur et les actions associées
case CONTINUE_CYCLE_1:
  if (key == 'A') 
  {
    cycleCounter = 0; // Remise à zéro du compteur si l'utilisateur annule
    currentMenu = PROCTOR_NORMAL;
    displayProctorNormal();
  } 
  else if (key == '1') 
  {
    currentMenu = START_cycle1;
    displayStart1();
    Serial.println("CYCLE 4 COMMENCÉ");
      cycle4();
      duree(1);
    Serial.println("CYCLE 4 TERMINÉ");
    currentMenu = CONTINUE_CYCLE_1; // Revenir au menu de continuation du cycle
    cycleCounter++; // Incrémente le compteur à chaque fois que le cycle est terminé
    displayContinueCycle1();
    if (cycleCounter >= 3) 
    {
      // Si le compteur atteint 3, passer à un nouveau menu
      currentMenu = FIN_CYCLE_1;
      // Faites les actions nécessaires pour le nouveau menu
      displayFinCycle1();

    }
  }
  break;
        
case FIN_CYCLE_1:
  if (key == 'A') 
  {
    currentMenu = PROCTOR_NORMAL;
    displayProctorNormal();
  }
  break;

case PROCTOR_MODIFIE:
  if (key == '1') {
    currentMenu = INFO_CYCLE2;
    displayInfo2();
  } else if (key == '2') {
    cycleCounter = 0;
    currentMenu = START_cycle2;
    displayStart2();
    Serial.println("CYCLE 4 modifie COMMENCÉ");
      cycle4();
      duree(1);
    Serial.println("CYCLE 4 modifie TERMINÉ");
    currentMenu = CONTINUE_CYCLE_2; // Afficher le menu "CONTINUE_CYCLE_1" après la fin du cycle
    cycleCounter++; // Incrémente le compteur à chaque fois que le cycle est terminé
    displayContinueCycle2();
  } else if (key == '3') {
    currentMenu = INIT_2;
    displayInit2();
    Serial.println("INITIALISATION COMMENCÉE");
    initialiserCompacteur();
    Serial.println("INITIALISATION TERMINÉE");
    currentMenu = PROCTOR_MODIFIE;
    displayProctorModifie();
  }
  break;

// Ajout de la gestion du compteur pour le menu PROCTOR_MODIFIE
case CONTINUE_CYCLE_2:
   if (key == 'A') 
  {
    cycleCounter = 0; // Remise à zéro du compteur si l'utilisateur annule
    currentMenu = PROCTOR_MODIFIE;
    displayProctorModifie();
  } 
  else if (key == '1') 
  {
    currentMenu = START_cycle2;
    displayStart2();
    Serial.println("CYCLE 4 COMMENCÉ");
      cycle4();
      duree(1);
    Serial.println("CYCLE 4 TERMINÉ");
    currentMenu = CONTINUE_CYCLE_2; // Revenir au menu de continuation du cycle
    cycleCounter++; // Incrémente le compteur à chaque fois que le cycle est terminé
    displayContinueCycle2();
  if (cycleCounter >= 5) {
    currentMenu = FIN_CYCLE_2;
    displayFinCycle2();
  }
  break;

case FIN_CYCLE_2:
  if (key == '0') {
    currentMenu = PROCTOR_MODIFIE;
    displayProctorModifie();
  }
  break;



       case CBR_NORMAL:
  if (key == '1') {
    currentMenu = INFO_CYCLE3;
    displayInfo3();
  } else if (key == '2') {
    cycleCounter = 0;
    currentMenu = START_cycle3;
    displayStart3();
    Serial.println("CYCLE 6 COMMENCÉ");
    for (int i = 0; i < 8; i++)
    {
    cycle6();
    duree(1);
    }
    Serial.println("CYCLE 6 TERMINÉ");
    currentMenu = CONTINUE_CYCLE_3; // Afficher le menu "CONTINUE_CYCLE_1" après la fin du cycle
    cycleCounter++; // Incrémente le compteur à chaque fois que le cycle est terminé
    displayContinueCycle3();
  } else if (key == '3') {
    currentMenu = INIT_3;
    displayInit3();
    Serial.println("INITIALISATION COMMENCÉE");
    initialiserCompacteur();
    Serial.println("INITIALISATION TERMINÉ");
    currentMenu = CBR_NORMAL;
    displayCbrNormal();
  }
  break;

case CONTINUE_CYCLE_3:
  if (key == 'A') {
    cycleCounter = 0; // Remise à zéro du compteur si l'utilisateur annule
    currentMenu = CBR_NORMAL;
    displayCbrNormal();
  } else if (key == '1') {
    currentMenu = START_cycle3;
    displayStart3();
    Serial.println("CYCLE 6 COMMENCÉ");
    for (int i = 0; i < 8; i++)
    {
    cycle6();
    duree(1);
    }
    Serial.println("CYCLE 6 TERMINÉ");
    currentMenu = CONTINUE_CYCLE_3; // Revenir au menu de continuation du cycle
    cycleCounter++; // Incrémente le compteur à chaque fois que le cycle est terminé
    displayContinueCycle3();
    if (cycleCounter >= 3) {
      currentMenu = FIN_CYCLE_3;
      displayFinCycle3();
    }
  }
  break;

case FIN_CYCLE_3:
  if (key == '0') {
    currentMenu = CBR_NORMAL;
    displayCbrNormal();
  }
  break;


       case CBR_MODIFIE:
  if (key == '1') {
    currentMenu = INFO_CYCLE4;
    displayInfo4();
  } else if (key == '2') {
    cycleCounter = 0;
    currentMenu = START_cycle4;
    displayStart4();
    Serial.println("CYCLE 4 COMMENCÉ");
    cycle4();
    duree(1);
    Serial.println("CYCLE 4 TERMINÉ");
    currentMenu = CONTINUE_CYCLE_4; // Afficher le menu "CONTINUE_CYCLE_1" après la fin du cycle
    cycleCounter++; // Incrémente le compteur à chaque fois que le cycle est terminé
    displayContinueCycle4();
  } else if (key == '3') {
    currentMenu = INIT_4;
    displayInit4();
    Serial.println("INITIALISATION COMMENCÉE");
    initialiserCompacteur();
    Serial.println("INITIALISATION TERMINÉE");
    currentMenu = CBR_MODIFIE;
    displayCbrModifie();
  }
  break;

case CONTINUE_CYCLE_4:
  if (key == 'A') {
    cycleCounter = 0; // Remise à zéro du compteur si l'utilisateur annule
    currentMenu = CBR_MODIFIE;

    displayCbrModifie();
  } else if (key == '1') {
    currentMenu = START_cycle4;
    displayStart4();
    Serial.println("CYCLE 4 COMMENCÉ");
    cycle4();
    duree(1);
    Serial.println("CYCLE 4 TERMINÉ");
    currentMenu = CONTINUE_CYCLE_4; // Revenir au menu de continuation du cycle
    cycleCounter++; // Incrémente le compteur à chaque fois que le cycle est terminé
    displayContinueCycle4();
    if (cycleCounter >= 5) {
      currentMenu = FIN_CYCLE_4;
      displayFinCycle4();
    }
  }
  break;

case FIN_CYCLE_4:
  if (key == '0') {
    currentMenu = CBR_MODIFIE;
    displayCbrModifie();
  }
  break;
        }// ... (gestion des autres cas des sous-menus)
      }
    }
  }
}

Donc j'ai demandé de l'aide dans le forum et j'ai essayé beaucoup de chose pour résoudre mon problème avec la validation user qui ne se fait pas et on ma conseillé de faire le code entier sous forme d'état (ce que j'ai fais pour l'écran) mais je n'arrive pas a le faire avec tout ses capteurs et moteurs et conditions je suis un peu perdu d'où l'ouverture du sujet.

pour l'écran, dont voici le code (deja envoyé précédement) :

//pas de validation apres interruption porte 
// nouveau keypad



#include <U8g2lib.h>
#include <Keypad.h>
#include <Arduino.h>
#include <avr/io.h>
#include <avr/interrupt.h>

U8G2_ST7920_128X64_F_SW_SPI u8g2(U8G2_R0, /* clock=*/ 13, /* data=*/ 11, /* CS=*/ 10, /* reset=*/ 8);

#define ROWS 4
#define COLS 4

const char kp4x4Keys[ROWS][COLS]  = {{'1', '2', '3', 'A'}, {'4', '5', '6', 'B'}, {'7', '8', '9', 'C'}, {'*', '0', '#', 'D'}};
byte rowKp4x4Pin [4] = {30, 32, 34, 36};
byte colKp4x4Pin [4] = {22, 24, 26, 28};
//fil bleu a gauche vers l'* et sur le 2 (22)

//Variables
Keypad kp4x4  = Keypad(makeKeymap(kp4x4Keys), rowKp4x4Pin, colKp4x4Pin, ROWS, COLS);


//____________________________________ CODE ECRAN _____________________________________________//

enum Menu {
  MAIN_MENU, //0
  INFO_MENU, //1
  START_MENU, //2 
  TEST_MENU, //3

  PROCTOR_MENU, //4
  CBR_MENU, //5 

  PROCTOR_NORMAL, //6
  PROCTOR_MODIFIE,//7

  CBR_NORMAL,//8
  CBR_MODIFIE,//9


  INFO_CYCLE1,//10
  INFO_CYCLE2,//13
  INFO_CYCLE3,//16
  INFO_CYCLE4,//19

  START_cycle1,//11
  START_cycle2,//14
  START_cycle3,//17
  START_cycle4,//20

  INIT_1,//12
  INIT_2,//15
  INIT_3,//18
  INIT_4,//21
  
  CONTINUE_CYCLE_1, //22
  CONTINUE_CYCLE_2, //23 
  CONTINUE_CYCLE_3, //24
  CONTINUE_CYCLE_4, //25

  FIN_CYCLE_1, //26
  FIN_CYCLE_2, //27
  FIN_CYCLE_3, //28
  FIN_CYCLE_4, //29

  TEST_MOTEUR, //30
  TEST_CAPTEUR, //31
};

Menu currentMenu = MAIN_MENU;

void displayMainMenu() 
{  // main menu 0
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_minicute_tr); //
  u8g2.drawButtonUTF8(5,8, U8G2_BTN_INV, u8g2.getDisplayWidth()-2*5,7,1,"      COMPACTEUR");
 
  u8g2.setFont(u8g2_font_unifont_t_symbols);
    u8g2.drawGlyph(90, 29, 0x2192);  
    u8g2.drawGlyph(90, 45, 0x2192);  
    u8g2.drawGlyph(90, 61, 0x2192);  
      u8g2.setFont(u8g2_font_minicute_tr); 
  u8g2.drawStr(17, 26, "Information     1");
  u8g2.drawStr(17, 42, "Demarrer       2");
  u8g2.drawStr(17, 58, "Test machine   3");
  u8g2.sendBuffer();
}

void displayInfoMenu() { //menu 1
  u8g2.clearBuffer();
    u8g2.setFont(u8g2_font_unifont_t_symbols);
    u8g2.drawGlyph(87, 66, 0x2190); //fleche retour
  u8g2.setFont(u8g2_font_minicute_tr); //
  u8g2.drawButtonUTF8(5,8, U8G2_BTN_INV, u8g2.getDisplayWidth()-2*5,7,1,"     INFORMATION");
  // Changer temporairement la taille de la police
   u8g2.setFont(u8g2_font_minicute_tr); // Choix d'une autre taille de police
  u8g2.drawStr(23, 24, "By PROVITEQ");
  // Revenir à la taille de police par défaut
  u8g2.drawStr(18, 39, "- V 1.0.2");
  u8g2.drawStr(1, 50, "01 60 78 99 60 ");
  u8g2.setFont(u8g2_font_04b_03_tr);
  u8g2.drawStr(79, 62, "0    retour ");
  u8g2.sendBuffer();
}

void displayStartMenu() 
{ //menu 2
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_unifont_t_symbols);
    u8g2.drawGlyph(85, 30, 0x2192); 
    u8g2.drawGlyph(85, 45, 0x2192); 
    u8g2.drawGlyph(87, 66, 0x2190); //fleche retour
   u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.drawButtonUTF8(5,8, U8G2_BTN_INV, u8g2.getDisplayWidth()-2*5,7,1,"       DEMARRER");
  u8g2.drawStr(20, 27, "PROCTOR A      1");
  u8g2.drawStr(20, 42, "PROCTOR B      2");
  u8g2.drawStr(28, 52, " (CBR)");
  u8g2.setFont(u8g2_font_04b_03_tr);
  u8g2.drawStr(79, 62, "0    retour");
  u8g2.sendBuffer();
}

void displayTestMenu() 
{ //menu 3
  u8g2.clearBuffer();
    u8g2.setFont(u8g2_font_unifont_t_symbols);
    u8g2.drawGlyph(91, 31, 0x2192); 
    u8g2.drawGlyph(91, 50, 0x2192); 
    u8g2.drawGlyph(87, 66, 0x2190); //fleche retour
  u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.drawButtonUTF8(5,8, U8G2_BTN_INV, u8g2.getDisplayWidth()-2*5,7,1,"   TEST MACHINE");
  u8g2.drawStr(10, 28, "Test Moteurs     1");
  u8g2.drawStr(10, 47, "Test Capteurs    2");
  u8g2.setFont(u8g2_font_04b_03_tr);
  u8g2.drawStr(79, 62, "0    retour");
  u8g2.sendBuffer();
}


void displayProctorMenu() 
{ //menu 4
  u8g2.clearBuffer();
    u8g2.setFont(u8g2_font_unifont_t_symbols);
    u8g2.drawGlyph(100, 31, 0x2192); 
    u8g2.drawGlyph(100, 50, 0x2192); 
    u8g2.drawGlyph(87, 66, 0x2190); //fleche retour
u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.drawButtonUTF8(5,8, U8G2_BTN_INV, u8g2.getDisplayWidth()-2*5,7,1,"   CYCLE PROCTOR A");
  u8g2.drawStr(10, 28, "PROCTOR Normal    1");
  u8g2.drawStr(10, 47, "PROCTOR Modifie   2");
  u8g2.setFont(u8g2_font_04b_03_tr);
  u8g2.drawStr(79, 62, "0    retour");
  u8g2.sendBuffer();
}

void displayCbrMenu()
{ //menu 5
  u8g2.clearBuffer();
    u8g2.setFont(u8g2_font_unifont_t_symbols);
    u8g2.drawGlyph(100, 31, 0x2192); 
    u8g2.drawGlyph(100, 50, 0x2192); 
    u8g2.drawGlyph(87, 66, 0x2190); //fleche retour
u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.drawButtonUTF8(5,8, U8G2_BTN_INV, u8g2.getDisplayWidth()-2*5,7,1,"   CYCLE PROCTOR B");
  u8g2.drawStr(10, 28, "PROCTOR Normal    1");
  u8g2.drawStr(10, 47, "PROCTOR Modifie   2");
  u8g2.setFont(u8g2_font_04b_03_tr);
  u8g2.drawStr(79, 62, "0    retour");
  u8g2.sendBuffer();
}

void displayProctorNormal() 
{ // menu 6
  u8g2.clearBuffer();
      u8g2.setFont(u8g2_font_unifont_t_symbols);
    u8g2.drawGlyph(95, 26, 0x2192); 
    u8g2.drawGlyph(95, 39, 0x2192); 
    u8g2.drawGlyph(95, 53, 0x2192);
    u8g2.drawGlyph(87, 66, 0x2190); //fleche retour
u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.drawButtonUTF8(5,8, U8G2_BTN_INV, u8g2.getDisplayWidth()-2*5,7,1,"  PROCTOR A NORMAL");
  u8g2.drawStr(17, 23, "Info cycle        1");
  u8g2.drawStr(17, 36, "Lancer cycle     2 ");
  u8g2.drawStr(17, 50, "Initialisation    3 ");
  u8g2.setFont(u8g2_font_04b_03_tr);
  u8g2.drawStr(79, 62, "0    retour");
  u8g2.sendBuffer();
}

void displayProctorModifie() 
{ // menu 7
  u8g2.clearBuffer();
      u8g2.setFont(u8g2_font_unifont_t_symbols);
    u8g2.drawGlyph(95, 26, 0x2192); 
    u8g2.drawGlyph(95, 39, 0x2192); 
    u8g2.drawGlyph(95, 53, 0x2192);
    u8g2.drawGlyph(87, 66, 0x2190); //fleche retour
u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.drawButtonUTF8(5,8, U8G2_BTN_INV, u8g2.getDisplayWidth()-2*5,7,1,"  PROCTOR A MODIFIE");
  u8g2.drawStr(17, 23, "Info cycle        1");
  u8g2.drawStr(17, 36, "Lancer cycle     2 ");
  u8g2.drawStr(17, 50, "Initialisation    3 ");
  u8g2.setFont(u8g2_font_04b_03_tr);
  u8g2.drawStr(79, 62, "0    retour");
  u8g2.sendBuffer();
}

void displayCbrNormal() 
{ // menu 8
  u8g2.clearBuffer();
      u8g2.setFont(u8g2_font_unifont_t_symbols);
    u8g2.drawGlyph(95, 26, 0x2192); 
    u8g2.drawGlyph(95, 39, 0x2192); 
    u8g2.drawGlyph(95, 53, 0x2192);
    u8g2.drawGlyph(87, 66, 0x2190); //fleche retour
u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.drawButtonUTF8(5,8, U8G2_BTN_INV, u8g2.getDisplayWidth()-2*5,7,1,"  PROCTOR B NORMAL");
  u8g2.drawStr(17, 23, "Info cycle        1");
  u8g2.drawStr(17, 36, "Lancer cycle     2 ");
  u8g2.drawStr(17, 50, "Initialisation    3 ");
  u8g2.setFont(u8g2_font_04b_03_tr);
  u8g2.drawStr(79, 62, "0    retour");
  u8g2.sendBuffer();
}

void displayCbrModifie() 
{ // menu 9
  u8g2.clearBuffer();
      u8g2.setFont(u8g2_font_unifont_t_symbols);
    u8g2.drawGlyph(95, 26, 0x2192); 
    u8g2.drawGlyph(95, 39, 0x2192); 
    u8g2.drawGlyph(95, 53, 0x2192);
    u8g2.drawGlyph(87, 66, 0x2190); //fleche retour
u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.drawButtonUTF8(5,8, U8G2_BTN_INV, u8g2.getDisplayWidth()-2*5,7,1,"  PROCTOR B MODIFIE");
  u8g2.drawStr(17, 23, "Info cycle        1");
  u8g2.drawStr(17, 36, "Lancer cycle     2 ");
  u8g2.drawStr(17, 50, "Initialisation    3 ");
  u8g2.setFont(u8g2_font_04b_03_tr);
  u8g2.drawStr(79, 62, "0    retour");
  u8g2.sendBuffer();
}


void displayInfo1() 
{ //10
  u8g2.clearBuffer();
        u8g2.setFont(u8g2_font_unifont_t_symbols);
    u8g2.drawGlyph(87, 66, 0x2190); //fleche retour
u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.drawStr(3, 10, "3 couches");
  u8g2.drawStr(3, 23, "25 coups par couche");
  u8g2.drawStr(1, 40, "duree : 1min 10s");
  u8g2.drawStr(1, 50, "(duree / couche)");
  u8g2.setFont(u8g2_font_04b_03_tr);
  u8g2.drawStr(79, 62, "0    retour");
  u8g2.sendBuffer();
}

void displayInfo2() 
{ //13
  u8g2.clearBuffer();
          u8g2.setFont(u8g2_font_unifont_t_symbols);
    u8g2.drawGlyph(87, 66, 0x2190); //fleche retour
u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.drawStr(3, 10, "5 couches");
  u8g2.drawStr(3, 23, "25 coups par couche");
  u8g2.drawStr(1, 40, "duree : 1min 10s");
  u8g2.drawStr(1, 50, "(duree / couche)");
  u8g2.setFont(u8g2_font_04b_03_tr);
  u8g2.drawStr(79, 62, "0    retour");
  u8g2.sendBuffer();
}

void displayInfo3() 
{ //16
  u8g2.clearBuffer();
          u8g2.setFont(u8g2_font_unifont_t_symbols);
    u8g2.drawGlyph(87, 66, 0x2190); //fleche retour
u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.drawStr(3, 10, "3 couches");
  u8g2.drawStr(3, 23, "56 coups par couche");
  u8g2.drawStr(1, 40, "duree : 2min 50s");
  u8g2.drawStr(1, 50, "(duree / couche)");
  u8g2.setFont(u8g2_font_04b_03_tr);
  u8g2.drawStr(79, 62, "0    retour");
  u8g2.sendBuffer();
}

void displayInfo4() 
{ //19
  u8g2.clearBuffer();
          u8g2.setFont(u8g2_font_unifont_t_symbols);
    u8g2.drawGlyph(87, 66, 0x2190); //fleche retour
u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.drawStr(3, 10, "5 couches");
  u8g2.drawStr(3, 23, "56 coups par couche");
  u8g2.drawStr(1, 40, "duree : 2min 50s");
  u8g2.drawStr(1, 50, "(duree / couche)");
  u8g2.setFont(u8g2_font_04b_03_tr);
  u8g2.drawStr(79, 62, "0    retour");
  u8g2.sendBuffer();
}


void displayStart1() 
{ //14
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.drawButtonUTF8(5,8, U8G2_BTN_INV, u8g2.getDisplayWidth()-2*5,7,1,"  PROCTOR A NORMAL");
  u8g2.drawStr(20, 35, "CYCLE EN COURS");
  u8g2.drawStr(2, 54, "ne pas ouvrir la porte");
  u8g2.sendBuffer();
}

void displayStart2() 
{ //14
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.drawButtonUTF8(5,8, U8G2_BTN_INV, u8g2.getDisplayWidth()-2*5,7,1,"  PROCTOR A MODIFIE");
  u8g2.drawStr(20, 35, "CYCLE EN COURS");
  u8g2.drawStr(2, 54, "ne pas ouvrir la porte");
  u8g2.sendBuffer();
}

void displayStart3() 
{ //17
  u8g2.clearBuffer();
u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.drawButtonUTF8(5,8, U8G2_BTN_INV, u8g2.getDisplayWidth()-2*5,7,1,"  PROCTOR B NORMAL");
  u8g2.drawStr(20, 35, "CYCLE EN COURS");
  u8g2.drawStr(2, 54, "ne pas ouvrir la porte");
  u8g2.sendBuffer();
}

void displayStart4() 
{ //20
  u8g2.clearBuffer();
 u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.drawButtonUTF8(5,8, U8G2_BTN_INV, u8g2.getDisplayWidth()-2*5,7,1,"  PROCTOR B MODIFIE");
  u8g2.drawStr(20, 35, "CYCLE EN COURS");
  u8g2.drawStr(2, 54, "ne pas ouvrir la porte");
  u8g2.sendBuffer();
}



void displayInit1() 
{ //12 
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.drawButtonUTF8(5,8, U8G2_BTN_INV, u8g2.getDisplayWidth()-2*5,7,1,"    INITIALISATION");
  u8g2.drawStr(24, 30, "INITIALISATION");
  u8g2.drawStr(40, 41, "EN COURS");
    u8g2.drawStr(2, 58, "ne pas ouvrir la porte");
  u8g2.sendBuffer();
}

void displayInit2() 
{ //15
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.drawButtonUTF8(5,8, U8G2_BTN_INV, u8g2.getDisplayWidth()-2*5,7,1,"    INITIALISATION");
  u8g2.drawStr(24, 30, "INITIALISATION");
  u8g2.drawStr(40, 41, "EN COURS");
    u8g2.drawStr(2, 58, "ne pas ouvrir la porte");
  u8g2.sendBuffer();
}

void displayInit3() 
{ //18
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.drawButtonUTF8(5,8, U8G2_BTN_INV, u8g2.getDisplayWidth()-2*5,7,1,"    INITIALISATION");
  u8g2.drawStr(24, 30, "INITIALISATION");
  u8g2.drawStr(40, 41, "EN COURS");
    u8g2.drawStr(2, 58, "ne pas ouvrir la porte");
  u8g2.sendBuffer();
}

void displayInit4() 
{ //21
  u8g2.clearBuffer();
  u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.drawButtonUTF8(5,8, U8G2_BTN_INV, u8g2.getDisplayWidth()-2*5,7,1,"    INITIALISATION");
  u8g2.drawStr(24, 30, "INITIALISATION");
  u8g2.drawStr(40, 41, "EN COURS");
    u8g2.drawStr(2, 58, "ne pas ouvrir la porte");
  u8g2.sendBuffer();
}


int cycleCounter = 0; 
void displayContinueCycle1() 
{ //22
u8g2.clearBuffer();
        u8g2.setFont(u8g2_font_unifont_t_symbols);
    u8g2.drawGlyph(98, 52, 0x2192); 
    u8g2.drawGlyph(98, 64, 0x2192); 
      u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.drawButtonUTF8(5,8, U8G2_BTN_INV, u8g2.getDisplayWidth()-2*5,7,1,"   COUCHE TERMINE");
 u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.setCursor(30, 32);
  u8g2.print("Couche : ");
  u8g2.print(cycleCounter); // Affiche la valeur du compteur
  u8g2.drawStr(85, 32, "/3");
  u8g2.drawStr(10, 49, "Continuer cycle    1");
  u8g2.drawStr(10, 61, "Annuler cycle      A");
  u8g2.sendBuffer();
}

void displayContinueCycle2() 
{ //23
u8g2.clearBuffer();
        u8g2.setFont(u8g2_font_unifont_t_symbols);
    u8g2.drawGlyph(98, 52, 0x2192); 
    u8g2.drawGlyph(98, 64, 0x2192); 
      u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.drawButtonUTF8(5,8, U8G2_BTN_INV, u8g2.getDisplayWidth()-2*5,7,1,"   COUCHE TERMINE");
 u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.setCursor(30, 32);
  u8g2.print("Couche : ");
  u8g2.print(cycleCounter); // Affiche la valeur du compteur
  u8g2.drawStr(85, 32, "/5");
  u8g2.drawStr(10, 49, "Continuer cycle    1");
  u8g2.drawStr(10, 61, "Annuler cycle      A");
  u8g2.sendBuffer();
}

void displayContinueCycle3() 
{ //24
u8g2.clearBuffer();
        u8g2.setFont(u8g2_font_unifont_t_symbols);
    u8g2.drawGlyph(98, 52, 0x2192); 
    u8g2.drawGlyph(98, 64, 0x2192); 
      u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.drawButtonUTF8(5,8, U8G2_BTN_INV, u8g2.getDisplayWidth()-2*5,7,1,"   COUCHE TERMINE");
 u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.setCursor(30, 32);
  u8g2.print("Couche : ");
  u8g2.print(cycleCounter); // Affiche la valeur du compteur
  u8g2.drawStr(85, 32, "/3");
  u8g2.drawStr(10, 49, "Continuer cycle    1");
  u8g2.drawStr(10, 61, "Annuler cycle      A");
  u8g2.sendBuffer();
}

void displayContinueCycle4() 
{ //25
u8g2.clearBuffer();
        u8g2.setFont(u8g2_font_unifont_t_symbols);
    u8g2.drawGlyph(98, 52, 0x2192); 
    u8g2.drawGlyph(98, 64, 0x2192); 
      u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.drawButtonUTF8(5,8, U8G2_BTN_INV, u8g2.getDisplayWidth()-2*5,7,1,"   COUCHE TERMINE");
 u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.setCursor(30, 32);
  u8g2.print("Couche : ");
  u8g2.print(cycleCounter); // Affiche la valeur du compteur
  u8g2.drawStr(85, 32, "/5");
  u8g2.drawStr(10, 49, "Continuer cycle    1");
  u8g2.drawStr(10, 61, "Annuler cycle      A");
  u8g2.sendBuffer();
}



void displayFinCycle1() 
{ //15
 u8g2.clearBuffer();
         u8g2.setFont(u8g2_font_unifont_t_symbols);
    u8g2.drawGlyph(44, 53, 0x2190); //fleche retour
  u8g2.setFont(u8g2_font_ncenB10_tr);
  u8g2.drawStr(20, 30, "FIN CYCLE");
  u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.drawStr(32, 50, "0    retour");
  u8g2.sendBuffer();
}

void displayFinCycle2() 
{ //15
 u8g2.clearBuffer();
         u8g2.setFont(u8g2_font_unifont_t_symbols);
    u8g2.drawGlyph(44, 53, 0x2190); //fleche retour
  u8g2.setFont(u8g2_font_ncenB10_tr);
  u8g2.drawStr(20, 30, "FIN CYCLE");
   u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.drawStr(32, 50, "0    retour");
  u8g2.sendBuffer();
}

void displayFinCycle3() 
{ //15
 u8g2.clearBuffer();
         u8g2.setFont(u8g2_font_unifont_t_symbols);
    u8g2.drawGlyph(44, 53, 0x2190); //fleche retour
  u8g2.setFont(u8g2_font_ncenB10_tr);
  u8g2.drawStr(20, 30, "FIN CYCLE");
   u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.drawStr(32, 50, "0    retour");
  u8g2.sendBuffer();
}

void displayFinCycle4() 
{ //15
 u8g2.clearBuffer();
         u8g2.setFont(u8g2_font_unifont_t_symbols);
    u8g2.drawGlyph(44, 53, 0x2190); //fleche retour
  u8g2.setFont(u8g2_font_ncenB10_tr);
  u8g2.drawStr(20, 30, "FIN CYCLE");
   u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.drawStr(32, 50, "0    retour");
  u8g2.sendBuffer();
}


void displayTestMoteur() 
{ //menu 33
  u8g2.clearBuffer();
    u8g2.setFont(u8g2_font_unifont_t_symbols);
    //vers gauche 
    u8g2.drawGlyph(12, 27, 0x2190); 
    u8g2.drawGlyph(12, 40, 0x2190); 
    u8g2.drawGlyph(12, 52, 0x2190); 
    u8g2.drawGlyph(12, 64, 0x2190); 
    //vers droite 
    u8g2.drawGlyph(105, 27, 0x2192); 
    u8g2.drawGlyph(105, 40, 0x2192); 
    u8g2.drawGlyph(105, 52, 0x2192); 
    u8g2.drawGlyph(105, 64, 0x2192); 
 u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.drawButtonUTF8(5,8, U8G2_BTN_INV, u8g2.getDisplayWidth()-2*5,7,1,"     TEST MOTEURS");
  u8g2.drawStr(3, 25, "1    Rotation| Stop   1");
  u8g2.drawStr(70, 37, "|");
  u8g2.drawStr(3, 37, "2   Avancer   Stop   2");
  u8g2.drawStr(3, 49, "3   Reculer | Stop   3");
  u8g2.drawStr(4, 61, "A   Battage | Stop   A");
  u8g2.sendBuffer();
}

void displayTestCapteur() 
{ //menu 33
  u8g2.clearBuffer();
    u8g2.setFont(u8g2_font_unifont_t_symbols);
    //vers gauche 
    u8g2.drawGlyph(12, 27, 0x2190); 
    u8g2.drawGlyph(12, 40, 0x2190); 
    u8g2.drawGlyph(12, 52, 0x2190); 
 u8g2.drawGlyph(87, 66, 0x2190); //fleche retour
 u8g2.setFont(u8g2_font_minicute_tr);
  u8g2.drawButtonUTF8(5,8, U8G2_BTN_INV, u8g2.getDisplayWidth()-2*5,7,1,"     TEST CAPTEURS");
  u8g2.drawStr(3, 25, "1    Capteur Centre");
  u8g2.drawStr(3, 37, "2   Capteur Type A");
  u8g2.drawStr(3, 49, "3   Capteur Type B");
  u8g2.setFont(u8g2_font_04b_03_tr);
  u8g2.drawStr(79, 62, "0    retour");
  u8g2.sendBuffer();
}


//____________________________________ CODE COMPACTEUR _____________________________________________//

***********************
***********************
***********************
//---------------------------------------------------
void setup() 
{
  u8g2.begin();
  u8g2.setFont(u8g2_font_crox4tb_tr);
  u8g2.drawStr(15, 40, "PROVITEQ");  // Affiche "PROVITEQ" aux coordonnées x=15 et y=40
  u8g2.sendBuffer();  // Envoie le contenu du tampon pour l'affichage
  delay(1600);  // Pause de 1300 millisecondes
  u8g2.clearBuffer();  // Efface le contenu de l'écran
  displayMainMenu();  // Affiche le menu principal
  pinMode(LED_BUILTIN, OUTPUT);
      for (int i = 0; i < numOutputs; i++) 
    {
        pinMode(DigitalOut[i], OUTPUT);
    }
    Serial.begin(9600);
    Serial.println(F("Initialize System"));
    Serial.println("Please press the keyboard:");
    analogWrite(DigitalOut[0] , 0);
    analogWrite(DigitalOut[1] , 0);
    analogWrite(DigitalOut[2] , 0);
    analogWrite(DigitalOut[3] , 0);
    pinMode(portDeTest, INPUT_PULLUP);
	attachInterrupt(digitalPinToInterrupt(portDeTest), checkDoor, RISING);     

}



void loop() 
{
	//Serial.println("Loop() " + String(loopCounter));
	//delay(250);
	//loopCounter ++;

    /*
if (doorOpen) {
    Serial.println("La porte est ouverte, le programme est en pause...");
    while (doorOpen) {
      doorOpen = digitalRead(portDeTest) == HIGH;
      delay(100); 
    }
    Serial.println("La porte est fermée, le programme reprend.");
  }
*/
    readKp4x4();

    char key = kp4x4.getKey();

  if (key) 
  {
        if (key == '0') 
        {
      // Go back to the previous menu
      switch (currentMenu) 
      {
        case INFO_MENU:
        case START_MENU:
        case TEST_MENU:
          currentMenu = MAIN_MENU;
          displayMainMenu();
          break;

        case TEST_MOTEUR:
        case TEST_CAPTEUR:
          currentMenu = TEST_MENU;
          displayTestMenu();
          break;

        case PROCTOR_MENU:
        case CBR_MENU:
          currentMenu = START_MENU;
          displayStartMenu();
          break;

        case PROCTOR_NORMAL:
        case PROCTOR_MODIFIE:
        currentMenu = PROCTOR_MENU;
          displayProctorMenu();
          break;

        case CBR_NORMAL:
        case CBR_MODIFIE:
          currentMenu = CBR_MENU;
          displayCbrMenu();
          break;

        case INFO_CYCLE1:
        case INFO_CYCLE2:
        case INFO_CYCLE3:
        case INFO_CYCLE4:
        case START_cycle1:
        case START_cycle2:
        case START_cycle3:
        case START_cycle4:
        case INIT_1:
        case INIT_2:
        case INIT_3:
        case INIT_4:


          // Going back to respective parent menu
          if (currentMenu == INFO_CYCLE1 || currentMenu == START_cycle1 || currentMenu == INIT_1) 
          {
            currentMenu = PROCTOR_NORMAL;
            displayProctorNormal();
          } else if (currentMenu == INFO_CYCLE2 || currentMenu == START_cycle2 || currentMenu == INIT_2) 
          {
            currentMenu = PROCTOR_MODIFIE;
            displayProctorModifie();
          } else if (currentMenu == INFO_CYCLE3 || currentMenu == START_cycle3 || currentMenu == INIT_3) 
          {
            currentMenu = CBR_NORMAL;
            displayCbrNormal();
          } else if (currentMenu == INFO_CYCLE4 || currentMenu == START_cycle4 || currentMenu == INIT_4) 
          {
            currentMenu = CBR_MODIFIE;
            displayCbrModifie();
          }
          break;

        default:
          break;
      }
    } 
    else 
    {
      switch (currentMenu) 
      {
        case MAIN_MENU:
          if (key == '1') 
          {
            currentMenu = INFO_MENU;
            displayInfoMenu();
          } else if (key == '2') 
          {
            currentMenu = START_MENU;
            displayStartMenu();
          } else if (key == '3') 
          {
            currentMenu = TEST_MENU;
            displayTestMenu();
          }
          break;

        case INFO_MENU:
          // Logique pour le menu d'informations
          break;

        case START_MENU:
          if (key == '1') 
          {
            currentMenu = PROCTOR_MENU;
            displayProctorMenu();
          } else if (key == '2') 
          {
            currentMenu = CBR_MENU;
            displayCbrMenu();
          }
          break;

        case TEST_MENU:
        if (key == '1') 
          {
            currentMenu = TEST_MOTEUR;
            displayTestMoteur();
          } else if 
          (key == '2') 
          {
            currentMenu = TEST_CAPTEUR;
            displayTestCapteur();
          }
          break;

        case TEST_MOTEUR:
          // Logique pour le menu de test
          if (key == '1')
          {
            toggleMoteur0();
          }
          if (key == '2')
          {
            translationManuAvantJusquaCapteurA1(); 
          }
          if (key == '3')
          {
            TranslationManuArriereJusquaCapteurA2();
          }
          if (key == 'A')
          {
            toggleMoteur3();
          }

          break;

        case TEST_CAPTEUR:
        if (key == '1')
          {
            TranslationManuArriereJusquaCapteurA2();
          }
          if (key == '2')
          {

           moveA1toA0();
          }
          if (key == '3')
          {
            translationManuAvantJusquaCapteurA1(); 
          }
          break;
        

        case PROCTOR_MENU:
          if (key == '1') 
          {
            currentMenu = PROCTOR_NORMAL;
            displayProctorNormal();
          } 
          else if (key == '2') 
          {
            currentMenu = PROCTOR_MODIFIE;
            displayProctorModifie();
          }
          break;

        case CBR_MENU:
          if (key == '1') 
          {
            currentMenu = CBR_NORMAL;
            displayCbrNormal();
          } 
          else if (key == '2') 
          {
            currentMenu = CBR_MODIFIE;
            displayCbrModifie();
          }
          break;


        case PROCTOR_NORMAL:
  if (key == '1') {
    currentMenu = INFO_CYCLE1;
    displayInfo1();
  } else if (key == '2') {
    cycleCounter = 0;
    currentMenu = START_cycle1;
    displayStart1();
    Serial.println("CYCLE 4 COMMENCÉ");
      cycle4();
      duree(1);
    Serial.println("CYCLE 4 TERMINÉ");  
    currentMenu = CONTINUE_CYCLE_1; // Afficher le menu "CONTINUE_CYCLE_1" après la fin du cycle
    cycleCounter++; // Incrémente le compteur à chaque fois que le cycle est terminé
    displayContinueCycle1();
  } else if (key == '3') {
    currentMenu = INIT_1;
    displayInit1();
    Serial.println("INITIALISATION COMMENCÉE");
    initialiserCompacteur();
    Serial.println("INITIALISATION TERMINÉE");
    currentMenu = PROCTOR_NORMAL;
    displayProctorNormal();
  }
  break;

// Ajoutez ensuite dans la partie où vous gérez CONTINUE_CYCLE_1 pour gérer le compteur et les actions associées
case CONTINUE_CYCLE_1:
  if (key == 'A') 
  {
    cycleCounter = 0; // Remise à zéro du compteur si l'utilisateur annule
    currentMenu = PROCTOR_NORMAL;
    displayProctorNormal();
  } 
  else if (key == '1') 
  {
    currentMenu = START_cycle1;
    displayStart1();
    Serial.println("CYCLE 4 COMMENCÉ");
      cycle4();
      duree(1);
    Serial.println("CYCLE 4 TERMINÉ");
    currentMenu = CONTINUE_CYCLE_1; // Revenir au menu de continuation du cycle
    cycleCounter++; // Incrémente le compteur à chaque fois que le cycle est terminé
    displayContinueCycle1();
    if (cycleCounter >= 3) 
    {
      // Si le compteur atteint 3, passer à un nouveau menu
      currentMenu = FIN_CYCLE_1;
      // Faites les actions nécessaires pour le nouveau menu
      displayFinCycle1();

    }
  }
  break;
        
case FIN_CYCLE_1:
  if (key == 'A') 
  {
    currentMenu = PROCTOR_NORMAL;
    displayProctorNormal();
  }
  break;

case PROCTOR_MODIFIE:
  if (key == '1') {
    currentMenu = INFO_CYCLE2;
    displayInfo2();
  } else if (key == '2') {
    cycleCounter = 0;
    currentMenu = START_cycle2;
    displayStart2();
    Serial.println("CYCLE 4 modifie COMMENCÉ");
      cycle4();
      duree(1);
    Serial.println("CYCLE 4 modifie TERMINÉ");
    currentMenu = CONTINUE_CYCLE_2; // Afficher le menu "CONTINUE_CYCLE_1" après la fin du cycle
    cycleCounter++; // Incrémente le compteur à chaque fois que le cycle est terminé
    displayContinueCycle2();
  } else if (key == '3') {
    currentMenu = INIT_2;
    displayInit2();
    Serial.println("INITIALISATION COMMENCÉE");
    initialiserCompacteur();
    Serial.println("INITIALISATION TERMINÉE");
    currentMenu = PROCTOR_MODIFIE;
    displayProctorModifie();
  }
  break;

// Ajout de la gestion du compteur pour le menu PROCTOR_MODIFIE
case CONTINUE_CYCLE_2:
   if (key == 'A') 
  {
    cycleCounter = 0; // Remise à zéro du compteur si l'utilisateur annule
    currentMenu = PROCTOR_MODIFIE;
    displayProctorModifie();
  } 
  else if (key == '1') 
  {
    currentMenu = START_cycle2;
    displayStart2();
    Serial.println("CYCLE 4 COMMENCÉ");
      cycle4();
      duree(1);
    Serial.println("CYCLE 4 TERMINÉ");
    currentMenu = CONTINUE_CYCLE_2; // Revenir au menu de continuation du cycle
    cycleCounter++; // Incrémente le compteur à chaque fois que le cycle est terminé
    displayContinueCycle2();
  if (cycleCounter >= 5) {
    currentMenu = FIN_CYCLE_2;
    displayFinCycle2();
  }
  break;

case FIN_CYCLE_2:
  if (key == '0') {
    currentMenu = PROCTOR_MODIFIE;
    displayProctorModifie();
  }
  break;



       case CBR_NORMAL:
  if (key == '1') {
    currentMenu = INFO_CYCLE3;
    displayInfo3();
  } else if (key == '2') {
    cycleCounter = 0;
    currentMenu = START_cycle3;
    displayStart3();
    Serial.println("CYCLE 6 COMMENCÉ");
    for (int i = 0; i < 8; i++)
    {
    cycle6();
    duree(1);
    }
    Serial.println("CYCLE 6 TERMINÉ");
    currentMenu = CONTINUE_CYCLE_3; // Afficher le menu "CONTINUE_CYCLE_1" après la fin du cycle
    cycleCounter++; // Incrémente le compteur à chaque fois que le cycle est terminé
    displayContinueCycle3();
  } else if (key == '3') {
    currentMenu = INIT_3;
    displayInit3();
    Serial.println("INITIALISATION COMMENCÉE");
    initialiserCompacteur();
    Serial.println("INITIALISATION TERMINÉ");
    currentMenu = CBR_NORMAL;
    displayCbrNormal();
  }
  break;

case CONTINUE_CYCLE_3:
  if (key == 'A') {
    cycleCounter = 0; // Remise à zéro du compteur si l'utilisateur annule
    currentMenu = CBR_NORMAL;
    displayCbrNormal();
  } else if (key == '1') {
    currentMenu = START_cycle3;
    displayStart3();
    Serial.println("CYCLE 6 COMMENCÉ");
    for (int i = 0; i < 8; i++)
    {
    cycle6();
    duree(1);
    }
    Serial.println("CYCLE 6 TERMINÉ");
    currentMenu = CONTINUE_CYCLE_3; // Revenir au menu de continuation du cycle
    cycleCounter++; // Incrémente le compteur à chaque fois que le cycle est terminé
    displayContinueCycle3();
    if (cycleCounter >= 3) {
      currentMenu = FIN_CYCLE_3;
      displayFinCycle3();
    }
  }
  break;

case FIN_CYCLE_3:
  if (key == '0') {
    currentMenu = CBR_NORMAL;
    displayCbrNormal();
  }
  break;


       case CBR_MODIFIE:
  if (key == '1') {
    currentMenu = INFO_CYCLE4;
    displayInfo4();
  } else if (key == '2') {
    cycleCounter = 0;
    currentMenu = START_cycle4;
    displayStart4();
    Serial.println("CYCLE 4 COMMENCÉ");
    cycle4();
    duree(1);
    Serial.println("CYCLE 4 TERMINÉ");
    currentMenu = CONTINUE_CYCLE_4; // Afficher le menu "CONTINUE_CYCLE_1" après la fin du cycle
    cycleCounter++; // Incrémente le compteur à chaque fois que le cycle est terminé
    displayContinueCycle4();
  } else if (key == '3') {
    currentMenu = INIT_4;
    displayInit4();
    Serial.println("INITIALISATION COMMENCÉE");
    initialiserCompacteur();
    Serial.println("INITIALISATION TERMINÉE");
    currentMenu = CBR_MODIFIE;
    displayCbrModifie();
  }
  break;

case CONTINUE_CYCLE_4:
  if (key == 'A') {
    cycleCounter = 0; // Remise à zéro du compteur si l'utilisateur annule
    currentMenu = CBR_MODIFIE;

    displayCbrModifie();
  } else if (key == '1') {
    currentMenu = START_cycle4;
    displayStart4();
    Serial.println("CYCLE 4 COMMENCÉ");
    cycle4();
    duree(1);
    Serial.println("CYCLE 4 TERMINÉ");
    currentMenu = CONTINUE_CYCLE_4; // Revenir au menu de continuation du cycle
    cycleCounter++; // Incrémente le compteur à chaque fois que le cycle est terminé
    displayContinueCycle4();
    if (cycleCounter >= 5) {
      currentMenu = FIN_CYCLE_4;
      displayFinCycle4();
    }
  }
  break;

case FIN_CYCLE_4:
  if (key == '0') {
    currentMenu = CBR_MODIFIE;
    displayCbrModifie();
  }
  break;
        }// ... (gestion des autres cas des sous-menus)
      }
    }
  }
}

voici l'organigramme des menu et sous menu (il y a u certaine modification mais rien de bien méchant)

il serait plutôt intéressant de réfléchir à l'objectif principal sous forme d'une machine à états (cf mon tuto éventuellement)
qui reçoit des évènements

La gestion du menu est une autre machine à état qui permet d'envoyer des évènements (les commandes) à la première machine à états.

votre code de la loop devrait se réduire à

void loop() {
  gestionMenu();
  gestionCompacteur();
}

merci pour votre réponse,
j'ai bien lu votre tuto on me l'avait déjà recommandé il y quelque temps, mais je n'arrive pas bien a l'appliquer pour mon cas.

J'ai du mal a comprendre comment fonctionnera le code si dans le Loop il y a que 2 lignes, et aussi comment cela va-t-il pouvoir résoudre mon problème d'interruption.

Comment les deux machines à états peuvent communiquer entre eux et fonctionner en même temps.

il s'agit juste d'un événement supplémentaire pour la machine à état de gestion du compacteur

Mais arriver à cette architecture nécessite bien sûr de repenser votre programme. Des attentes actives comme

ne sont pas envisageables puisque vous ne faites plus rien d'autre en attendant ces 50ms.

➜ il ne faut aucun delay() dans le code

enum Cycle6State {
  CYCLE6_IDLE,
  CYCLE6_MOVE_TO_A1,
  CYCLE6_BATTAGE_ROTATION,
  CYCLE6_ROTATE_1SUR12,
  CYCLE6_MOVE_TO_A2,
  CYCLE6_BATTAGE_CENTRAL
};

//Cycle6State cycle6State = CYCLE6_IDLE;
int cycle6State = CYCLE6_IDLE;

void cycle6() {
  switch (cycle6State) {
    case CYCLE6_IDLE:
      // Actions à effectuer lorsque le cycle 6 est en attente
      break;

    case CYCLE6_MOVE_TO_A1:
      Serial.println("avancer au capteur A1");
      translationAvantJusquaCapteurA1();
      cycle6State = CYCLE6_BATTAGE_ROTATION; // Passer à l'état suivant
      break;

    case CYCLE6_BATTAGE_ROTATION:
      Serial.println("battage+rotation1/6");
      battageETrotation();
      duree(1);
      cycleCounter++; // Incrémenter le compteur
      if (cycleCounter >= 5) {
        cycle6State = CYCLE6_ROTATE_1SUR12; // Si on a fait le battage+rotation 5 fois, passer à l'état suivant
        cycleCounter = 0; // Réinitialiser le compteur
      }
      break;

    case CYCLE6_ROTATE_1SUR12:
      Serial.println("rotation de 1/12");
      duree(1);
      rotation_1sur12();
      delay(100);
      Serial.println("reculer au centre");
      cycle6State = CYCLE6_MOVE_TO_A2; // Passer à l'état suivant
      break;

    case CYCLE6_MOVE_TO_A2:
      TranslationArriereJusquaCapteurA2();
      duree(2);
      Serial.println("battage central");
      cycle6State = CYCLE6_BATTAGE_CENTRAL; // Passer à l'état suivant
      break;

    case CYCLE6_BATTAGE_CENTRAL:
      moteur(&DigitalOut[3], true);
      delay(2500);
      moteur(&DigitalOut[3], false);
      cycle6State = CYCLE6_IDLE; // Revenir à l'état initial pour le prochain cycle
      break;

    default:
      // Gestion d'erreur ou autre action par défaut
      break;
  }
}

j'ai fais quelque chose comme ca, fonction cycle que j'ai appeler comme avant dans le code, donc évidement que la fonction fonctionne pas..

dans le void :

    case CBR_NORMAL:
  if (key == '1') {
    currentMenu = INFO_CYCLE3;
    displayInfo3();
  } else if (key == '2') {
    cycleCounter = 0;
    currentMenu = START_cycle3;
    displayStart3();
    Serial.println("CYCLE 6 COMMENCÉ");
    for (int i = 0; i < 8; i++)
    {
    cycle6();
    duree(1);
    }
    Serial.println("CYCLE 6 TERMINÉ");
    currentMenu = CONTINUE_CYCLE_3; // Afficher le menu "CONTINUE_CYCLE_1" après la fin du cycle
    cycleCounter++; // Incrémente le compteur à chaque fois que le cycle est terminé
    displayContinueCycle3();
  } else if (key == '3') {

mais ca veut dire que je dois aussi mettre sous forme d'état les sous fonctions car il y a des delay aussi dedans ?

j'avoue avoir un peu de mal a visualiser la ou je me dirige et a voir a quoi va ressembler le code

Tout ce qui crée une attente active dune réalisation de condition qui vous empêche de revenir à la loop est à proscrire si ça prend plus de quelques millisecondes

ok je vais donc tout refaire,

comment je peux passer ce genre d'étape

void TranslationArriereJusquaCapteurA2()
{
    int count_5V = 0;

    while (count_5V < 2) 
    {
        float tension = analogRead(A2) * (5.0 / 1023.0);

        //Serial.print("Tension : ");
        //Serial.println(tension, 2);

        if (tension >= 4.97) 
        {
            count_5V++;
            //Serial.println("Voltage 5V");
        } else {
            count_5V = 0; // Réinitialiser le compteur si la tension n'est pas de 5V
        }

        //Serial.print("Nombre de fois à 5V : ");
        //Serial.println(count_5V);

        if (count_5V == 02) 
        {
            //Serial.println("Moteur coupé");
            moteur(&DigitalOut[1], false);
        } 
        else 
        {
            moteur(&DigitalOut[1], true);
        }

        delay(13); // Attendre avant la prochaine lecture
    }
}

en état ?

Ce while correspond sans doute à un état.

Quand vous revenez dans cet état par La boucle, vous vérifiez la condition avec un if, pas avec un while. Si le if est vérifié vous changez d’état sinon c’est que vous deviez rester dans cet état (correspond à rester dans votre while)

En gros, plus de while bloquant, le while c’est la loop qui tourne. L’état courant sert à savoir où on en est et donc quels sont les événements possibles qui conduisent à un changement d’état. Votre graphe d’état devrait représenter cela.

en gros le moteur fait reculer le plateau sur le capteur A2 donc des que A2 est enclencher il doit arrêter le moteur d'ou le while qui vérifie en permanence (avec plusieurs vérification) le capteur

la je devrais juste mettre "if A2 détecté arrêter moteur " ?

Le souci du while c’est qu’il vous colle à cet endroit du code et donc vous ne pouvez pas vérifier l’ouverture d’une porte ou l’appui sur un bouton ou un envoi de commande etc….

Donc pas de while mais juste un if. Par contre ce if ne peut pas être la seule modification, il ne doit se produire que si vous êtes dans l’état adéquat d’où le besoin de tracer ce graphe d’états

Pouvez vous essayer de décrire quels sont les états de la machine ?

je vais essayer de décrire :
par exemple le cycle 6 autrement appeler cycle CBR 6 pouces ou proctor type B selon la norme :
il part du centre donc le capteur A2 pour aller au capteur A0 dans mon cas pour mettre un coup suivi d'une rotation (la rotation commence lorsque la dame remonte pas avant, pas apres, et ce 7x, pour enfin revenir au capteur centre A2 (avec le code que j'ai envoyer juste avant)

donc les états seraient A2 pas detecté et A2 detecté mais j'arrive toujours pas trop a bien comprendre le systeme detat, je suis un peu lent a la détente désolé.

mais j'imagine qu'il y a plein d'état : état de chaque capteur ou de chaque moteur ou un mélange de deux ? je sais pas

Partez de plus loin, la vous en êtes aux détails techniques qui seront traités beaucoup plus tard

A quoi sert la machine et quelles sont les commandes ?

la machine sert a compacter des matériaux du BTP pour tester plusieurs chose et elle se control a l'aide d'un Keypad 4x4 et un écran
exemple :
lorsqu'on allume le premier ecran affiche 3 choix :
information -> 1
démarré -> 2
test -> 3

sur le keypad tu appuie sur 2 ca ouvre un autre menu etc etc cest comme ca quon le control

Vous confondez l’interface utilisateur avec la ou les fonctions de la machine (et On en revient toujours au même point : Pour que le keypad soit actif en permanence il ne faut pas que le code soit bloqué quelque part.)

Faisons simple

Un état initial : la machine est au REPOS
Elle reçoit un ordre XYZ donc on passe en mode état EXEC_XYZ

Décrivez ce que fait la machine pour faire XYZ en détail.
Décrivez comment on sort de ce mode (est-ce automatique au bout d’un certain temps, quand un capteur dit que c’est fini, quand l’utilisateur envoie un ordre d’arrêt,…. Il peut y avoir plusieurs événements.
Décrivez ce qu’il se passe une fois sorti de XYZ. Est on revenu au mode REPOS ou bien on est dans un autre état ?

Il faut une spécification fonctionnelle détaillée.

ce que tu me dis la est très intéressant, car a la base je voulais faire en sorte qu'un bouton du keypad soit utilisable pendant un cycle pour arrêter ce cycle en cours de route, mais c'était impossible du coup car une fois la fonction lancé je devais attendre 1 minute que tout les étapes soit finit le seul moyen d'arreter etait de reset la carte ou d'ouvrir la porte avec l'interruption

on
donc, l'état initial de la machine (compacteur) est donc repos, elle fait rien n'attend rien, (a ce moment la tout ce passe sur la machine (menu).

Ensuite en fonction de ce qui est fait et choisi sur la machine menu, un ordre XYZ est envoyé a la machine compacteur qui va executer. pour l'éxecuter elle recoit une succession de mouvement a faire et ils se font tous a la suite 1 par 1, chaque mouvement est défini par des capteurs aller de tel point a tel point, battage porte, sauf pour la rotation ou cest une durée définie (avec des delay :smiling_face_with_tear: ).

une fois tout les mouvement réalisé la machine compacteur répasse automatiquement au repos a la meme position quelle l'était début et elle attend une nouvelle instruction de la machine menu. (ex : relance le cycle (car dans la norme le cycle doit etre réalisé plusieurs fois) ou arreter de cycle et revenu a un menu précédent)

tout le programme fonctionne comme ca

etat repos :

  • la dame est révéler a la position du capteur dame
  • et le plateau est au centre

cycle 6 (CBR) :

  1. le plateau se dirige et s'arrête sur le capteur du CBR
  2. la dame met un coup et se relève
  3. rotation de 1/6 de tour (correspond a un delay(340) )
  4. l'étape 2 et 3 sont reproduite 6x, a fin de réaliser 6 coup tangant sur les coter du moule
  5. le plateau retourne au capteur Centre
  6. et la dame met un coup au centre pour conclure le cycle
  7. et le cycle s'arrête et la machine est a la même position qu'au repos prête pou un nouveau cycle

La machine menu dit "lance le cycle 6" et tout ca doit s'exécuter automatiquement a la suite, comment je peux faire ca sous forme d'état ?

dans mon programme en fonction il y a des moments ou la machine compacteur attend une instruction et cest donc a ce moment la que le keybord est débloqué et que l'user peut sen servir

Bonjour,

Je me permet une remarque +/- hors sujet mais qui concerne peut-être un point qui vous serez demandé par les utilisateurs une fois le machine finit.

Sur ce genre de machine, même de labo, il y a un moment où la question "sécurité" vient sur le tapis (on ne peut pas raisonnablement laisser ce genre de machine entre les mains d'étudiants).

Et à ce moment, on va vous demander
1 arrêt d'urgence
1 vérouillage mécanique (par exemple par des gâches électriques à manque de courant (verouillée si pas alimentée).

Ce n'est pas des points difficiles à aborder et rajouter, mais PEUT-ETRE (c'est vous qui voyez) à prévoir dans la machine d'états.

Bonjour, un arrêt d'urgence est bien présent je les câblé directement à la sorti du transformateur qui coupe l'entièreté de la machine. Plus si on ouvre la porte les moteurs se coupent aussi. Pour le deuxième point j'y penserais mais ce n'est pas encore prévu, merci pour la suggestion.