Go Down

Topic: ouvrir des sous programmes dans un programme avec menu lcd (Read 746 times) previous topic - next topic

printemps

Bonsoir à tous,

Je suis nouveau sur le forum et débutant "avancé" dans le monde arduino. Je suis en train de réaliser un projet avec un afficheur et un menu déroulant. (intervalomètre et traveling avec plusieurs options)

- Le programme avec le menu déroulant --> OK (je me suis bien fait aider par un site web et je comprends à peu près le programme.)
- Mes différents "sous - programmes"  avec les fonctions -->OK (fait maison.)

Mon problème est que je n'arrive pas à envoyer le programme souhaité à l'aide de mon menu. Je dois louper quelque chose que je ne connais pas.

Le menu comporte 4 boutons : ESC, ENTER, LEFT, RIGHT.

Exemple : Mon menu se comporte ainsi :

MAIN MENU
1.1 DECL STATIQUE
1.1.1 Commande manuelle
1.1.2 Laser

2.1 TRAVELING
2.1.1 1ph/min
2.1.2 1ph/10min
2.1.3 Cmd Motorisée

3.1 Scénarios
3.1.1 Scénario 1
3.1.2 Scénario 2
...
Ce que je souhaite c'est que quand j'appuie sur la touche "ENTER" sur un "sous menu", par exemple "2.1.1 1ph/min" cela me déclenche le cycle (donc un sous programme à insérer)de 1ph/min. Si j'appuie sur la touche "ESC", le cycle s'arrête et je retourne au menu principal.
Après moult essais d'insertion de programme est de recherche sur le web je commence à sécher.
Voici le programme du menu déroulant :
Code: [Select]


LiquidCrystal lcd(2, 3, 4, 5, 6, 7);

//Menu variables
MenuBackend menu = MenuBackend(menuUsed,menuChanged);
//initialize menuitems
 MenuItem menu1Item1 = MenuItem("1.Decl Statique ");
 MenuItem menuItem1SubItem1 = MenuItem("1.1 Laser       ");
 MenuItem menuItem1SubItem2 = MenuItem("1.2 Cmd.Manuelle");
 MenuItem menu1Item2 = MenuItem("2.Traveling     ");
 MenuItem menuItem2SubItem1 = MenuItem("2.1 1Ph/Min     ");
 MenuItem menuItem2SubItem2 = MenuItem("2.2 1Ph/10Min   ");
 MenuItem menuItem3SubItem3 = MenuItem("2.3 CmdMotorisee");
 MenuItem menu1Item3 = MenuItem("3.Scenario      ");
 
void setup()
{
  pinMode(buttonPinLeft, INPUT);
  pinMode(buttonPinRight, INPUT);
  pinMode(buttonPinEnter, INPUT);
  pinMode(buttonPinEsc, INPUT);
 
   lcd.begin(16, 2);
lcd.setCursor(0,0);
lcd.print("BONJOUR         ");
delay(3000);
  //configure menu
  menu.getRoot().add(menu1Item1);
  menu1Item1.addRight(menu1Item2).addRight(menu1Item3);
  menu1Item1.add(menuItem1SubItem1).addRight(menuItem1SubItem2);
  menu1Item2.add(menuItem2SubItem1).addRight(menuItem2SubItem2).addRight(menuItem3SubItem3);
  menu.toRoot();
  lcd.setCursor(0,0); 
  lcd.print("CMD TERMINAL    ");

}  // setup()...

void loop()
{

  readButtons();
  navigateMenus();
                 
} //loop()...

void menuChanged(MenuChangeEvent changed){
 
MenuItem newMenuItem=changed.to;
 
lcd.setCursor(0,1);
 
  if(newMenuItem.getName()==menu.getRoot()){
      lcd.print("Main Menu       ");
   }else if(newMenuItem.getName()=="1.Decl Statique "){
     lcd.print("1.Decl Statique ");
   }else if(newMenuItem.getName()=="1.1 Laser       "){
      lcd.print("1.1 Laser       ");
   }else if(newMenuItem.getName()=="1.2 Cmd.Manuelle"){
      lcd.print("1.2 Cmd.Manuelle");
   }else if(newMenuItem.getName()=="2.Traveling     "){
      lcd.print("2.Traveling     ");
   }else if(newMenuItem.getName()=="2.1 1Ph/Min     "){
      lcd.print("2.1 1Ph/Min     ");
     
  }else if(newMenuItem.getName()=="2.2 1Ph/10Min   "){
      lcd.print("2.2 1Ph/10Min   ");
  }else if(newMenuItem.getName()=="2.3 CmdMotorisee"){
     lcd.print("2.3 CmdMotorisee");     
  }else if(newMenuItem.getName()=="3.Scenario      "){
      lcd.print("3.Scenario      ");
  }
}

void menuUsed(MenuUseEvent used){
  lcd.setCursor(0,0); 
  lcd.print(" Cycle en cours ");
  lcd.setCursor(0,1);
  lcd.print(used.item.getName());
  delay(3000);  //delay to allow message reading
  lcd.setCursor(0,0); 
  lcd.print("CMD TERMINAL    ");
  menu.toRoot();  //back to Main
}
void  readButtons(){
  int reading;
  int buttonEnterState=LOW;
  int buttonEscState=LOW;
  int buttonLeftState=LOW;
  int buttonRightState=LOW;

  //Enter button
                 reading = digitalRead(buttonPinEnter);
                               
                   if (reading != lastButtonEnterState) {
   
                    lastEnterDebounceTime = millis();
                  }
               
                  if ((millis() - lastEnterDebounceTime) > debounceDelay) {
                       buttonEnterState=reading;
                    lastEnterDebounceTime=millis();
                  }
                 
                  // save the reading.  Next time through the loop,
                  // it'll be the lastButtonState:
                  lastButtonEnterState = reading;
                 

    //Esc button               
                     reading = digitalRead(buttonPinEsc);
   
                  if (reading != lastButtonEscState) {
   
                    lastEscDebounceTime = millis();
                  }
                 
                  if ((millis() - lastEscDebounceTime) > debounceDelay) {
   
                    buttonEscState = reading;
                    lastEscDebounceTime=millis();
                  }
                 
                  // save the reading.  Next time through the loop,
                  // it'll be the lastButtonState:
                  lastButtonEscState = reading;
                 
                     
   //Down button               
   
   reading = digitalRead(buttonPinRight);

                     if (reading != lastButtonRightState) {
                    // reset the debouncing timer
                    lastRightDebounceTime = millis();
                  }
                 
                  if ((millis() - lastRightDebounceTime) > debounceDelay) {
                       buttonRightState = reading;
                   lastRightDebounceTime =millis();
                  }
                 
                  // save the reading.  Next time through the loop,
                  // it'll be the lastButtonState:
                  lastButtonRightState = reading;                 
                 
                 
    //Up button               
                 
  reading = digitalRead(buttonPinLeft);

  the Down button
             
   if (reading != lastButtonLeftState) {
      lastLeftDebounceTime = millis();
                 }
                 
                  if ((millis() - lastLeftDebounceTime) > debounceDelay) {
                       buttonLeftState = reading;
                    lastLeftDebounceTime=millis();;
                  }
             
                        lastButtonLeftState = reading; 

                     if (buttonEnterState==HIGH){
                    lastButtonPushed=buttonPinEnter;

                  }else if(buttonEscState==HIGH){
                    lastButtonPushed=buttonPinEsc;

                  }else if(buttonRightState==HIGH){
                    lastButtonPushed=buttonPinRight;

                  }else if(buttonLeftState==HIGH){
                    lastButtonPushed=buttonPinLeft;

                  }else{
                    lastButtonPushed=0;
                  }                 
}

void navigateMenus() {
  MenuItem currentMenu=menu.getCurrent();
 
  switch (lastButtonPushed){
    case buttonPinEnter:
      if(!(currentMenu.moveDown())){ 
        menu.use();
      }else{
        menu.moveDown();
       }
      break;
    case buttonPinEsc:
      menu.toRoot();  //back to main
      break;
    case buttonPinRight:
      menu.moveRight();
      break;     
    case buttonPinLeft:
      menu.moveLeft();
      break;     
  }
 
  lastButtonPushed=0;
}


Et voici le sous programme que je souhaite activer lorsque l'on appuie sur "1ph/10min par exemple :
Code: [Select]

const int RELAIS_1 = 8;
const int RELAIS_2 = 9;
int relaisState = LOW;
unsigned long previousMillis = 0;     
const long interval = 1000;       
void setup() {
  pinMode(RELAIS_1, OUTPUT);
  pinMode(RELAIS_2, OUTPUT);
}

void loop() {
   unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;
     if (relaisState == LOW) {
      relaisState = HIGH;
    } else {
      relaisState = LOW;
    }
    digitalWrite(RELAIS_1, relaisState);
    delay(300);
  }
    digitalWrite(RELAIS_2, HIGH);
    delay(1500);
    digitalWrite(RELAIS_2, LOW);
    delay(1500);
    }

P-S : J'ai enlevé les variables, les fonctions et les commentaires car sinon c'est trop lourd pour le topic, s'il manque quelque chose faites le moi savoir.

Si quelqu'un peut m'aider en me débloquant la chose, cela me ferait réellement plaisir car j'ai passé trop de Week end et de soirée sur ce truc

Je vous remercie d'avance.

J-M-L

Il ne peut y avoir qu'un seul setup (et qu'une seule loop) dans votre programme. Il n'y a pas de notion de sous programme - juste des fonctions

Il faut donc restructurer le code pour prendre cela en compte
Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums
Pas de messages privés SVP

printemps

J-M-L

Merci pour ta réponse. Mais ou insérer la loop de mes programmes? J'ai fais pleins d'essai, rien  ne marche, je m'y prend mal.

J-M-L

La loop doit gérer le menu comme dans votre premier programme
Quand un menu est choisi il appele une fonction qui fait ce que vous voulez
Si ce soit être répétitif alors il faudra bâtir une machine à états
Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums
Pas de messages privés SVP

printemps

Une fois j'avais tenté quelque chose comme ceci :

 
Code: [Select]

}else if(newMenuItem.getName()=="2.1 1Ph/Min     "){
      lcd.print("2.1 1Ph/Min     ");

 unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;
     if (relaisState == LOW) {
      relaisState = HIGH;
    } else {
      relaisState = LOW;
    }
    digitalWrite(RELAIS_1, relaisState);
    delay(300);
  }
    digitalWrite(RELAIS_2, HIGH);
    delay(1500);
    digitalWrite(RELAIS_2, LOW);
    delay(1500);
    }

[\code]

Il me lançait bien la boucle mais qu'une seule fois!!rrrrrrr

Je suis perdu


manumanu

Bonjour;
L idéal est que tu te face ton propre programme. Avec ton propre menu.
Imagine ton menu sur papier atribu une valeur pour chaque fenêtres. Active tes fenêtres en fonction de ces valeurs attribué. Exemple. La 1er fenêtre de présentation = 1 un appui sur entré et tu incrémente +1 pour afficher la seconde fenêtre = 2 un appui sur un bouton retour et tu retourne à 1 en chargent cette valeur dans une variable prévu pour l activation de chaque fenêtres .
Salutations.
"Apprends moi ce que tu sais je t'apprendrais ce que je sais en nous serons intelligent"

J-M-L

@Printemps

Jetez un coup d'œil à mon tuto sur les machines à état si vous voulez

Les événements qui pilotent votre machine sont les choix sans les menus et le temps qui passe
La classe que vous utilisez pour votre menu est aussi en elle même une machine à états (un peu comme dans mon exemple avec la librairie des boutons et les callbacks simpleclick et double click)
Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums
Pas de messages privés SVP

printemps

Bonjour;
L idéal est que tu te face ton propre programme. Avec ton propre menu.
Imagine ton menu sur papier atribu une valeur pour chaque fenêtres. Active tes fenêtres en fonction de ces valeurs attribué. Exemple. La 1er fenêtre de présentation = 1 un appui sur entré et tu incrémente +1 pour afficher la seconde fenêtre = 2 un appui sur un bouton retour et tu retourne à 1 en chargent cette valeur dans une variable prévu pour l activation de chaque fenêtres .
Salutations.
Bonjour,

En fait le programme des menus me convient parfaitement, ce que je souhaite maintenant, c'est de pouvoir lancer un cycle (loop) en appuyant sur l'item demandé dans le menu de mon écran.

J-M-L

Quote
En fait le programme des menus me convient parfaitement, ce que je souhaite maintenant, c'est de pouvoir lancer un cycle (loop) en appuyant sur l'item demandé dans le menu de mon écran.
si vous lancez une boucle, votre menu n'aura plus jamais la main... ce que lance le menu ne doit pas être bloquant
Please do not PM me for help,  others will benefit as well if you post your question publicly on the forums
Pas de messages privés SVP

manumanu

Bonjour;
Quote
En fait le programme des menus me convient parfaitement,
Quote
- Le programme avec le menu déroulant --> OK (je me suis bien fait aider par un site web et je comprends à peu près le programme.)
- Mes différents "sous - programmes"  avec les fonctions -->OK (fait maison.)

Mon problème est que je n'arrive pas à envoyer le programme souhaité à l'aide de mon menu. Je dois louper quelque chose que je ne connais pas.
Le copier coller c'est bien mais on y trouve vite des limites d'exploitation.

Quote
Ce que je souhaite c'est que quand j'appuie sur la touche "ENTER" sur un "sous menu", par exemple "2.1.1 1ph/min" cela me déclenche le cycle (donc un sous programme à insérer)de 1ph/min. Si j'appuie sur la touche "ESC", le cycle s'arrête et je retourne au menu principal.
Après moult essais d'insertion de programme est de recherche sur le web je commence à sécher.
Voici le programme du menu déroulant
:
Ce dont tu as besoins tu peux le monter en suivant tes propre questions. Les menus sont tous différents et ne répondent pas aux même cahiers des charges.

Crée déjà ton propre menu. ensuite attache y les fonctions qui te permettrons d'activer l'exécution que tu souhaite.
Et je rejoint J-M-L 
Quote
Il ne peut y avoir qu'un seul setup (et qu'une seule loop) dans votre programme. Il n'y a pas de notion de sous programme - juste des fonctions

Il faut donc restructurer le code pour prendre cela en compte
Salutations.
"Apprends moi ce que tu sais je t'apprendrais ce que je sais en nous serons intelligent"

Go Up