problème avec Switch

Bonjour a tous

Alors voila mon problème j'ai un switch qui me permet de déclencher une fonction identique pour tous

Ce switch contient 16 condition qui dépendent du relais que l'on souhaite modifier mais voila quand j'active la 7ème conditions cela me décale tout d'un niveau j'ai essayer de toute les façons que je voyait avec des pointeurs avec des returns etc... la 7eme condition fait que ce menu plante

voila l'extrait du code qui me pose soucis

     if (Ss_menu==HIGH)
               {
          switch(Sous_sous_menu)
           {
           case 1:
           
                   Serial.print("Sous_sous_menu");
                   Serial.print(Sous_sous_menu);
                   Serial.print("Ss_menu");
                   Serial.print(Ss_menu);
                   delay(500);
            modifyetat(&relay1);
          break;
           case 2:
        modifyetat(&relay2);
          break;
           case 3:  
       modifyetat(&relay3);     
          break;
          case 4:
       modifyetat(&relay4);
          break;
          case 5:
      modifyetat(&relay5);
          break;
          case 6:
         modifyetat(&relay6);
          break;
          
           case 7:
        // modifyetat(&relay7);
            break;
          
            case 8:
           relay8=modifyetat(&relay8);
            break;
            case 9:
          
       //    relay9=modifyetat(relay9);
           break;

           case 10:
        //    relay10=modifyetat(relay10);
           break;
           
           case 11:
       //    relay11= modifyetat(relay11);
           break;
           
           case 12:
      //     relay12= modifyetat(relay12);
           break;
           
           case 13:
      //     relay13= modifyetat(relay13);
           break;
           
           case 14:
       //    relay14= modifyetat(relay14);
           break;
           
           case 15:
        // relay15=   modifyetat(relay15);
              break;
              case 16:
     //    relay16=   modifyetat(relay16);
              break;
          }
             
        }

et le code de la fonction qui va avec

word modifyetat(word *relay)
  {
    Serial.print("relay");
    Serial.println(*relay);
    lcd.setCursor(0,1);
    lcd.print(F("                    "));
    lcd.setCursor(0,3);
    lcd.print(F("                    "));
     switch(*relay)
      {
        case 1:
        lcd.setCursor(0,2);
        lcd.print(F("   automatique      "));
        break;
        
        case 2:
        lcd.setCursor(0,2);
        lcd.print(F("   marche force     "));
        break;
        
        case 3:
        lcd.setCursor(0,2);
        lcd.print(F("   eteint force     "));
        break;
       }
      if (modify_etat==0)
        {
          previousCompteur=Compteur;//vaiable globale
          modify_etat=2;//variable globale
          delay(500);                   
        }
      if( digitalRead(validate)==LOW && (modify_etat=3))
       {
         Ss_menu=LOW;//vaiable globale
         level=1;//vaiable globale
         modify_etat=0;//vaiable globale
         selecteur=Sous_sous_menu;//vaiable globale
          delay(200);
        }  
      if ( modify_etat==2) 
        {
         
          lcd.setCursor(0,3);
        
         
          if( previousCompteur> Compteur)
            {
              *relay=*relay+1;
              previousCompteur=Compteur; //vaiable globale
              
    
            }
          else if( previousCompteur< Compteur)
            {
              *relay=*relay-1;//vaiable globale mais teste fais avec un pointeur
              previousCompteur=Compteur; //vaiable globale
            }
          if (*relay>3)
           {
              *relay=1;
           }
          else if(*relay <1)
           {
             *relay=3;
           }
           if(digitalRead(validate)==LOW ) //Si bouton est activer
             {
                modify_etat=3;
             }
             Serial.print("previousCompteur");
    Serial.println(previousCompteur);
    Serial.print("Compteur");
    Serial.println(Compteur);
     Serial.print("modify_etat");
    Serial.println(modify_etat);
        }
       
 }

j'espère que vous pourrez m'aider car j'ai l'impression que je vais m'arracher les cheveux

Postez tout le code

C’est quoi relay1, relay2,...si c’est juste un entier en lecture, pas la peine de le passer par pointeur...

Appuyez sur Ctrl-T pour indenter le code correctement avant de poster ici, la c’est fouilli à lire sur smartphone

le code est trop gros pour être affiché sur ce site je le mets donc en pièces jointes les fichiers que j'ai omis sont commenter donc d'aucune utilité

automate_version2beta0.1.ino (12 KB)

Fonctions_modifier.h (11.2 KB)

selecteur.h (1.97 KB)

affichage.h (5.51 KB)

affichage_menu.h (31.5 KB)

En virant le code pour ne conserver que le squelette des enchaînements (spaghettis !! :)) ) ça donne ça

else if (menu == HIGH ) { //Si menu est activé
  if (level == 0) {
    switch (pages) { // selectionne la page de niveau 1
      case 1: break;
      case 2: break;
      case 3: break;
    }

    if (digitalRead(validate) == LOW) {  // selectionne le menu croissance flo ou flo1
      if (Sous_menu == 1 or Sous_menu == 2 or Sous_menu == 3 or Sous_menu == 5 or Sous_menu == 6) {}
      else if ( Sous_menu == 4 ) {}
      else if ( Sous_menu == 7 ) {}
    }
  }

  else if (level == 1) {
    if ( S_menu == 2 or S_menu == 3 ) // menu flo 1 ou flo2
    {
      if (S_menu == 2) {}
      else if (S_menu == 3) {}
      switch (pages)
      {
        case 1: break;
        case 2: break;
        case 3: break;
        case 4: break;
      }
      if (digitalRead(validate) == LOW && selecteur != nombremenu) {}
      else if (digitalRead(validate) == LOW && selecteur == nombremenu) {}
    }
    else if ( S_menu == 1 ) {} // menu croissance
    else if (S_menu == 5 ) // Menu forcer état
    {
      switch (pages)
      {
        case 1: break;
        case 2: break;
        case 3: break;
        case 4: break;
        case 5: break;
        case 6: break;
      }

      if (digitalRead(validate) == LOW && Sous_sous_menu != nombremenu) {}
      else if (digitalRead(validate) == LOW && Sous_sous_menu == nombremenu) {}
    } //fin
    else if (( S_menu == 6 )) {} // selection activation mode
  }

  else if (level == 2) {
    switch (S_menu) {
      case 6: break;//si sous menu 3 est activer
      case 1: break;//si sous menu 1 est activer
      case 2: //si sous menu 2 est activer (floraison)
        Ss_menu = HIGH;
        if (Ss_menu == HIGH) {
          switch (Sous_sous_menu) {
            case 1: break;
            case 2: break;
            case 3: break;
            case 4: break;
            case 5: break;
            case 6: break;
            case 7: break;
              /* case 8: break;*/
          }
        }
        break;

      case 3: break;//si sous menu 3 est activer

      case 5: //si sous menu 3 est activer
        Ss_menu = HIGH;
        if (Ss_menu == HIGH) {
          switch (Sous_sous_menu) {
            case 1: break;
            case 2: break;
            case 3: break;
            case 4: break;
            case 5: break;
            case 6: break;
            case 7: break;
            case 8: break;
            case 9: break;
            case 10: break;
            case 11: break;
            case 12: break;
            case 13: break;
            case 14: break;
            case 15: break;
            case 16: break;
          }
        }
        break;
    }
    if ((selecteur == nombremenu) and ( digitalRead(validate) == LOW)) {} //gestion du return
  }
}

c'est compliqué à suivre, tous les cas ne sont pas testés, y'a pas de default dans les switch etc mais le squelette se tient, il ne manque pas de break.

pourquoi faites vous

[color=red]        Ss_menu = HIGH;[/color]
...
[color=red]        if (Ss_menu == HIGH)[/color]

vous venez de le mettre à HIGH...

Que dit le compilateur au niveau de la mémoire disponible ? vous avez des tonnes de chaînes de caractères, il faudrait utiliser la macro F() pour minimiser l'impact sur la RAM. il se peut que ça fasse partie de votre problème

J-M-L:
pourquoi faites vous

[color=red]        Ss_menu = HIGH;[/color]

...
        if (Ss_menu == HIGH)




vous venez de le mettre à HIGH...

oui ok aucun intérêt :confused:

J-M-L:
Que dit le compilateur au niveau de la mémoire disponible ? vous avez des tonnes de chaînes de caractères, il faudrait utiliser la macro F() pour minimiser l'impact sur la RAM. il se peut que ça fasse partie de votre problème

Le croquis utilise 20566 octets (8%) de l'espace de stockage de programmes. Le maximum est de 253952 octets.
Les variables globales utilisent 1565 octets (19%) de mémoire dynamique, ce qui laisse 6627 octets pour les variables locales. Le maximum est de 8192 octets.

je viens de rajouter la macro (F("")) sur les chaines manquante cela ne change rien

bon je continue a chercher après avoir ajouté la macro F un peu partout le programme plante toujours. je viens de faire un teste en supprimant les chaine de caractères dans le switch et cela fonctionne sans trop de surprise d'ailleurs
quelqu'un aurais une idée de comment utiliser un grand nombre de string sans bouffer toute la ram?
j'ai entendu parler de progmem mais le résultat est a première vu le même qu'avec la macro F

la macro F() met en flash et ne mange pas la RAM

essayez de tracer où ça plante.

faites une variable globale unsigned int DEBUG_CPT = 0;et ensuite dans la partie suspecte insérez entre chaque ligne

Serial.println(DEBUG_CPT++); Serial.flush();

ça vous donnera une idée de ce qu'il se passe.

alors comment expliquer ce décalages systématique en gros dans le sous_menu floraison si je décommente la 7eme condition cela me décale tout d'un cran dans le menu forcer état.
donc en faite je peux accéder à état lampe cro mais en sélectionnant etat lampe flo et ainsi de suite
par contre si je sélectionne Etat lampe cro la carte redémarre

J-M-L:
essayez de tracer où ça plante.

faites une variable globale unsigned int DEBUG_CPT = 0;et ensuite dans la partie suspecte insérez entre chaque ligne

Serial.println(DEBUG_CPT++); Serial.flush();

ça vous donnera une idée de ce qu'il se passe.

je ne sais pas ce que ce code fait et surtout comment peut il m'aidez a debugger pouvez vous m'expliquer?

Bonjour,

Une simple variable est incrémentée puis envoyée sur le moniteur.
En plaçant cette instruction judicieusement, vous allez détecter la ligne qui fait rebooter le micro.
Il suffira ensuite de regarder la dernière valeur envoyée sur le moniteur pour retrouver la ligne problématique en calculant les incrementations.

Ça veut dire quoi exactement

si je décommente la 7eme condition cela me décale tout d'un cran dans le menu forcer état.

Vous nous montrez une photo du décalage ?

dans affichage_menu.h si je décommente la condition 7 ligne 675 ou une des conditions qui suit
le programme plante au niveau du switch ligne 777 j'ai placé une variable a cette endroit et elle s'affiche a zero pas moyen de rentrer dans ce switch ligne 777

par contre si je commente la ligne 675 jusqu'a la ligne 700 je rentre dans le switch ligne 777 sans aucun problème

Je suis sur mon mobile donc des Nos de ligne ça ne me parle pas...

Montrez le code avec votre variable de test
Ça plante ou ça part en boucle infinie ?

video avec conditions 7 et suivante commenté

video avec conditions 7 et/ou suivante décommenté

les photos demandé

les photos:

c'est difficile de vous aider sans avoir votre montage et code sous la main.

désactivez tout appel 'applicatif', regardez si juste la navigation menu fonctionne histoire de ne pas être impacté par un bug dans une des autres fonctions appelée par le menu

j'ai deja fais des test de ce genre le problème est le même si je desactive l'appel au fonction(je viens de le refaire) la seul fonction qui me reste est selecteurmenu dans selecteur.h qui me permet de positionner le "#" dans le menu

pour mon montage c'est un simple lcd sur arduino mega avec encoder rotatifs le reste de la carte n'est pas actif car alimenter en usb il me faut du 12v pour les relais 2 uln2803 font l'intermédiare entre l'arduino et les 16 relays

modifiez le code des fonctions appelées pour qu'il fasse juste une impression sur la console.

ça permet de tester tout le process
si ça fonctionne c'est qu'un appel de fonction crée le bazar...