Ecran LCD avec menus

Bonjour, j'ai un programme censé afficher sur la première ligne de l'écran, le nom d'un menu et sur la deuxième, la sous-option choisi, en choisissant entre 3 menus et 2 sous-option par menu avec deux boutons poussoirs. Mais il semblerait quand appuyant sur le bouton pour changer les menus, il rempli sa fonction mais, peut-être un peu trop. De temps en temps, sans suivre de logique précise, il change aussi la sous-option en même temps de changer le menu. Et le bouton pour changer la sous-option ne marche pas directement mais change la sous-option pour le menu suivant. Ayant fait des tests en changeant le programme je n'arrive plus a retrouver cette configuration et maintenant le bouton de sous-option change la sous-option, toujours en décalage, des trois menus. J'ai essayé beaucoup de configuration et suis maintenant à cours d'idée, je me tourne donc vers vous, en vous remerciant d'avance pour vos réponses.

#include <LiquidCrystal.h> // on importe la bibliothèque pour LCD

LiquidCrystal monEcran(12, 11, 5, 4, 3, 2); // on crée un objet LCD nommé monEcran en mode 4 bits

const byte bout1 = 8; //constante du pin bouton 1
const byte bout2 = 6; //constante du pin bouton 2


int posMenu = 0 ; //variable de position dans menu principal

int posSousMenu = 0 ; // tableau pour stocker les positions de chaque sous-menu

int modeES = 0;
int modeCB = 0;
int modeDG = 0;

String ligne1[3] = {"Droite/Gauche :        ","Entree/Sortie :        ","Creneau/Bataille :    "}; //tableau de titre du menu principal

String ligne2 = "Droite";


void setup() {
  // put your setup code here, to run once:

  /* Initialise le port série */
  
 pinMode(bout1, INPUT);

  pinMode(bout2, INPUT);

  monEcran.begin(16, 2); //on initialise la communication avec 16 colonnes et 2 lignes

  monEcran.clear(); // on efface l'écran








  


}

void loop() {
  // put your main code here, to run repeatedly:


 
  
   navigation();
 affichage();

}



//fonction de navigation dans le menu

void navigation() {

  //création de variables d'état pour les boutons

  boolean etatBout1 = digitalRead(bout1);

  boolean etatBout2 = digitalRead(bout2);

  //Boucle pour naviguer dans les menus

  

    if (etatBout1 == 1) { // si bouton 1

      posMenu = (posMenu + 1) % 3; //on change le menu principal (3 positions)

    

    if (etatBout2 == 1) { // si bouton 2

      switch (posMenu) { //l'action dépend du menu 1

        case 0: //si menu DG

          modeDG = (modeDG + 1) % 2; 

          break;

        case 1 : //si menu ES

          modeES = (modeES + 1) % 2; 

          break;

        case 2: // si menu CB

          modeCB = (modeCB + 1) % 2;  

          break;
        

         

      
    

    }
    
    }

 delay(200); //attente pour éviter les répétitions

   
  }

}



//fonction de rafraîchissement de l'écran LCD

void affichage() {

  monEcran.setCursor(0, 0); // on positionne le curseur en haut à gauche

  monEcran.print(ligne1[posMenu]); // on écrit le menu de la ligne 1

  monEcran.setCursor(0, 1); // on passe à la ligne suivante

 

  String mDG[2] = {

    "Droite             ",

    "Gauche           ",

  };

   String mES[2] = {
    

    "Entree            ",

    "Sortie          ",
   };

   String mCB[2] = {

    "Creneau            ",

    "Bataille          ",

   };

    switch (posMenu) { // en fonction du menu 1

    case 0: // si menu  Droite ou gauche

      ligne2 = mDG[modeDG]; //titre pris dans tableau mDG

      break;

    case 1: // si menu entrée ou sortie

      ligne2 = mES[modeES]; // appel de la construction de l'affichage

      break;

    case 2: 

      ligne2 = mCB[modeCB];

      break;

  }

  monEcran.print(ligne2); // on affiche la ligne du menu 2 

  }

Ceci n'est pas très efficace s'il y a des rebonds ou si l'opérateur tient le bouton enfoncé trop longtemps

delay(200); //attente pour éviter les répétitions

Il est de loin préférable de tester le relâché du bouton en faisant une boucle qui teste si les boutons sont retournés à zéro.
Remplace le delay par ça:

while(digitalRead(bout1) || digitalRead(bout2)){};   // attend le retour des 2 boutons à zéro