projet avec menu lcd problème

Portrait de gael

Bonjour,

Je suis nouveau sur ce forum, j'espère trouver une aide adéquat au sujet de mon problème.

Je suis en train de créer un intervalomètre sur barre traveling et plusieurs options. J'ai déja construis tous les programmes qui correspondent à chaque fonctions dans mon projet.

Mon problème  : J'ai établis un menu avec un écran LCD (je me suis fais aider)utilisant la librairie MenuBackend. Je n'arrive pas à lancer un cycle qui correspond à un item de mon menu. Puis je avoir de l'aide ?

Je ne remercie d'avance.

Portrait de brossden

Bonjour gael

Je pense que tu comprendras facilement qu'il nous faut en savoir un peu plus sur ton projet. En quoi consiste il, quels sont tes codes et que désires tu obtenir ? Comment veux que l'on t'aide autrement. Il faut que je te précise que je suis actuellement en Andalousie et que je ne serai pas très rapide à te dépanner mais je ferai de mon mieux.

Bonne journée à tous

Portrait de gael

Tout d'abord merci pour ta réactivité ! Voila ce que je souhaite exactement:

Je posséde 4 boutons : ENTER, ESC, LEFT, RIGHT

Tu auras compris que ENTER permet de sélectionner l'item désiré, ESC de revnir en arrière et LEFT RIGHT de naviguer dans le menu.

Le 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 

------et ainsi de suite--------(il y en aura d'autre au fur et à mesure)

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" (Une photo par minute) cela me déclenche le cycle (donc un "sous programme", une fonction à insérer)de 1ph/min. Si j'appuie sur la touche "ESC", le cycle s'arrête et je retourne au menu principal.

Voici le code du MENU qui me convient parfaitement : 

#include <MenuBackend.h>    //bibliothèque menu backend
#include <LiquidCrystal.h>  //bibliothèque de l'écran lcd

const int buttonPinLeft = 8;      // pin Up button
const int buttonPinRight = 9;    // pin Down button
const int buttonPinEsc = 10;     // pin Esc button
const int buttonPinEnter = 11;   // pin Enter button

int lastButtonPushed = 0;

int lastButtonEnterState = LOW;   // the previous reading from the Enter input pin
int lastButtonEscState = LOW;   // the previous reading from the Esc input pin
int lastButtonLeftState = LOW;   // the previous reading from the Left input pin
int lastButtonRightState = LOW;   // the previous reading from the Right input pin

long lastEnterDebounceTime = 0;  // the last time the output pin was toggled
long lastEscDebounceTime = 0;  // the last time the output pin was toggled
long lastLeftDebounceTime = 0;  // the last time the output pin was toggled
long lastRightDebounceTime = 0;  // the last time the output pin was toggled
long debounceDelay = 500;    // the debounce time

static void menuUsed(MenuUseEvent used);
static void menuChanged(MenuChangeEvent changed);

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

//Menu variables
MenuBackend menu = MenuBackend(menuUsed,menuChanged);
//initialize menuitems
      MenuItem menu1Item1 = MenuItem("1.Decl Statique ");//Item 1
      MenuItem menuItem1SubItem1 = MenuItem("1.1 Laser       ");//Item1SubItem1
      MenuItem menuItem1SubItem2 = MenuItem("1.2 Cmd.Manuelle");//Item1SubItem2
      MenuItem menu1Item2 = MenuItem("2.Traveling     ");//Item2
      MenuItem menuItem2SubItem1 = MenuItem("2.1 1Ph/Min     ");//Item2SubItem1
      MenuItem menuItem2SubItem2 = MenuItem("2.2 1Ph/10Min   ");//menuItem2SubItem2
      MenuItem menuItem3SubItem3 = MenuItem("2.3 CmdMotorisee");//menuItem3SubItem3
      MenuItem menu1Item3 = MenuItem("3.Scenario      ");
  

void setup()
{
  pinMode(buttonPinLeft, INPUT);
  pinMode(buttonPinRight, INPUT);
  pinMode(buttonPinEnter, INPUT);
  pinMode(buttonPinEsc, INPUT);
  pinMode(led, OUTPUT);
  
  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();  //I splitted button reading and navigation in two procedures because 
  navigateMenus();  //in some situations I want to use the button for other purpose (eg. to change some settings)

}

} //loop()... 

void menuChanged(MenuChangeEvent changed){
  
  MenuItem newMenuItem=changed.to; //get the destination menu
  
  lcd.setCursor(0,1); //set the start position for lcd printing to the second row
  
  if(newMenuItem.getName()==menu.getRoot()){
      lcd.print("Main Menu       ");

      
  }else if(newMenuItem.getName()=="1.Decl Statique "){
      lcd.print("1.Decl Statique ");//Item1

      
  }else if(newMenuItem.getName()=="1.1 Laser       "){
  lcd.print("1.1 Laser       ");//Item1SubItem1
     

  }else if(newMenuItem.getName()=="1.2 Cmd.Manuelle"){
      lcd.print("1.2 Cmd.Manuelle");//Item1SubItem2

      
  }else if(newMenuItem.getName()=="2.Traveling     "){
      lcd.print("2.Traveling     ");//Item2

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

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

      
  }else if(newMenuItem.getName()=="2.3 CmdMotorisee"){
      lcd.print("2.3 CmdMotorisee");//Item2SubItem3

      
  }else if(newMenuItem.getName()=="3.Scenario      "){
      lcd.print("3.Scenario      ");//Item3
  }
}

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(){  //read buttons status
  int reading;
  int buttonEnterState=LOW;             // the current reading from the Enter input pin
  int buttonEscState=LOW;             // the current reading from the input pin
  int buttonLeftState=LOW;             // the current reading from the input pin
  int buttonRightState=LOW;             // the current reading from the input pin

  //Enter button
                  // read the state of the switch into a local variable:
                  reading = digitalRead(buttonPinEnter);

                  // check to see if you just pressed the enter button 
                  // (i.e. the input went from LOW to HIGH),  and you've waited 
                  // long enough since the last press to ignore any noise:  
                
                  // If the switch changed, due to noise or pressing:
                  if (reading != lastButtonEnterState) {
                    // reset the debouncing timer
                    lastEnterDebounceTime = millis();
                  } 
                  
                  if ((millis() - lastEnterDebounceTime) > debounceDelay) {
                    // whatever the reading is at, it's been there for longer
                    // than the debounce delay, so take it as the actual current state:
                    buttonEnterState=reading;
                    lastEnterDebounceTime=millis();
                  }
                  
                  // save the reading.  Next time through the loop,
                  // it'll be the lastButtonState:
                  lastButtonEnterState = reading;
                  

    //Esc button               
                  // read the state of the switch into a local variable:
                  reading = digitalRead(buttonPinEsc);

                  // check to see if you just pressed the Down button 
                  // (i.e. the input went from LOW to HIGH),  and you've waited 
                  // long enough since the last press to ignore any noise:  
                
                  // If the switch changed, due to noise or pressing:
                  if (reading != lastButtonEscState) {
                    // reset the debouncing timer
                    lastEscDebounceTime = millis();
                  } 
                  
                  if ((millis() - lastEscDebounceTime) > debounceDelay) {
                    // whatever the reading is at, it's been there for longer
                    // than the debounce delay, so take it as the actual current state:
                    buttonEscState = reading;
                    lastEscDebounceTime=millis();
                  }
                  
                  // save the reading.  Next time through the loop,
                  // it'll be the lastButtonState:
                  lastButtonEscState = reading; 
                  
                     
   //Down button               
                  // read the state of the switch into a local variable:
                  reading = digitalRead(buttonPinRight);

                  // check to see if you just pressed the Down button 
                  // (i.e. the input went from LOW to HIGH),  and you've waited 
                  // long enough since the last press to ignore any noise:  
                
                  // If the switch changed, due to noise or pressing:
                  if (reading != lastButtonRightState) {
                    // reset the debouncing timer
                    lastRightDebounceTime = millis();
                  } 
                  
                  if ((millis() - lastRightDebounceTime) > debounceDelay) {
                    // whatever the reading is at, it's been there for longer
                    // than the debounce delay, so take it as the actual current state:
                    buttonRightState = reading;
                   lastRightDebounceTime =millis();
                  }
                  
                  // save the reading.  Next time through the loop,
                  // it'll be the lastButtonState:
                  lastButtonRightState = reading;                  
                  
                  
    //Up button               
                  // read the state of the switch into a local variable:
                  reading = digitalRead(buttonPinLeft);

                  // check to see if you just pressed the Down button 
                  // (i.e. the input went from LOW to HIGH),  and you've waited 
                  // long enough since the last press to ignore any noise:  
                
                  // If the switch changed, due to noise or pressing:
                  if (reading != lastButtonLeftState) {
                    // reset the debouncing timer
                    lastLeftDebounceTime = millis();
                  } 
                  
                  if ((millis() - lastLeftDebounceTime) > debounceDelay) {
                    // whatever the reading is at, it's been there for longer
                    // than the debounce delay, so take it as the actual current state:
                    buttonLeftState = reading;
                    lastLeftDebounceTime=millis();;
                  }
                  
                  // save the reading.  Next time through the loop,
                  // it'll be the lastButtonState:
                  lastButtonLeftState = reading;  

                  //records which button has been pressed
                  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())){  //if the current menu has a child and has been pressed enter then menu navigate to item below
        menu.use();
      }else{  //otherwise, if menu has no child and has been pressed enter the current menu is used
        menu.moveDown();
       } 
      break;
    case buttonPinEsc:
      menu.toRoot();  //back to main
      break;
    case buttonPinRight:
      menu.moveRight();
      break;      
    case buttonPinLeft:
      menu.moveLeft();
      break;      
  }
  
  lastButtonPushed=0; //reset the lastButtonPushed variable
}

Et voici un "sous programme" que je souhaite insérer lorsque je clique sur 1ph/min par exemple 

const int RELAIS_1 = A0;// Relais indépendant géré par la fonction milli()
const int RELAIS_2 = A1;//Relais gérer par le delay

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);
    

}

Franchement j'ai essayé en long en large et en travers et je bloque depuis quelques semaines.

Si tu penses avoir une solution à mon problème ca me ferait vraiment plaisir!

Portrait de brossden

Super merci de m'avoir donner ces explications

Ton programme à l'air assez complexe et il va me falloir un certain temps pour le digérer mais tout de suite il faut que tu saches qu'il ne faut jamais que l'un de tes sous programmes ne court circuit le le loop() puisse c'est lui qui te fait scruter tes boutons entre autre !

Alors dans ton suis programme 1 photo toutes les minutes par exemple il ne faut surtout pas mettre un delay (1 minute ) sinon tu ne scruteras plus tes boutons pendant toute cette minute .... et dur dur pour bloquer ce dernier pile à la fin de cette minute qui se répétera pratiquement tout de suite !

Je ne sais pas si je me suis bien fait comprendre ?

Dans ce cas il faut soit utiliser une base de temps externe si tu veux de la précision soit estimer le temps de cycle de l'Arduino et incrémenter un compteur qui une fois multiplié par le temps du cycle te donnera la minute.

A+

Bon ne journée à tous

Portrait de gael

Broosden,

Je suis tellement content de tomber sur quelqu'un qui veut m'aider (dur dur sur le net et dans l'entourage)!

En fait ce que je comprends c'est qu'il faut que je créé une fonction dans la loop comme 

void loop(){

1ph_min();    //par exemple

}

et ensuit que j'introduise un "if" avec la loop de mon sous programme qui est :

void 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);
  

}

Mais je ne sais pas ou le placer et comment.

Portrait de brossden

GAEL pour le simulateur dont nous avons parlé au téléphone c'est :

https://circuits.io/

Bonne soirée

Portrait de gael

Merci on se recontacte bientot, passe un bon sejour dans le sud!

Portrait de brossden

Merci GAEL je suis sur de pouvoir te dépanner d'ici quelques jours !

Portrait de gael

J'ai vu quelque chose d'intéressant, c'est la fonction callback. Mais il faut que je refasse tout mon menu avec la bibliothèque menusystem.h.

Portrait de brossden

Salut Gael

Je viens de rentrer et sur mon PC c'est plus facile.

Je viens de voir une grosse erreur de ta part !!

Il y a deux " void loop() "! ( ce n'est pas possible pas possible !)

A+

Portrait de brossden

Gael  > Chose promise chose due ! Je te ferais une vidéo de mon montage pour que tu comprennes bien sont foctionnement !

Tu remarqueras aussi que j'utilise une pseudo base de donnée ! Tous est expliqué en commentaires !

#include <LiquidCrystal.h>
//Déclarations des variables

LiquidCrystal lcd(8, 9, 4, 5, 6, 7); /* Attention ce sont des valeurs pour mon LCD !!!! */

int LED = 51; /* Port que j'utilise pour ma Led qui Clignote */

int unsigned Menu = 0; /* Cette variable est incrémentée de 10 en 10 et permet

d'afficher  les Menus sans sous Menu possibilité ici de 10 menu mais tu peux monter à

100 ou plus */

int unsigned SousMenu = 0 ; /* Cette variable permet d'afficher les sous menus

associés  à chaque menu (ici de 1 à 9 donc neuf sous menu par menu */

double DelaiON; /* Temps durant lequel la LED reste Allumée */
double DelaiOFF; /* Temps durant lequel la LED reste Éteinte */

int Clignote = 0; /* Cette variable permet d'activer ou  désactiver le sous programme

de  clignotement. J'en profite dans ce programme pour déterminer le temps de

clignotement */

typedef struct{ /* Une structure permet de faire une liste de variables qui pourront être

appelées avec un index numérique. */
 
  String Menu;} /* Définition du ou des champs de la structure */
  TypeMenu; /*Nom de la Structure */

TypeMenu NumMenu[100]; /* Limitation du nombre d'enregistrements de la base de

donnée NumMenu  ayant comme champs les mêmes que la structure TypeMenu */

void Initialisation() { /* Création de la base de donnée, tu remarqueras que les dizaines

avec  pour unité "0" correspondent au Menu ! et les autre aux sous Menus !  */

  NumMenu[10] = (TypeMenu) {"1 DECL STATIQUE"}; /*10, 11 ,12 ... correspondent à

l'index  */
  NumMenu[11] = (TypeMenu) {"1.1 Cde manuelle"};
  NumMenu[12] = (TypeMenu) {"1.2 Laser"};
  NumMenu[20] = (TypeMenu) {"2 TRAVELING"};
  NumMenu[21] = (TypeMenu) {"2.1 1ph/50 msec"};
  NumMenu[22] = (TypeMenu) {"2.2 1ph/500 msec"};
  NumMenu[23] = (TypeMenu) {"2.3 Cmd Motorisee"};
  NumMenu[30] = (TypeMenu) {"3 Scenarios"};
  NumMenu[31] = (TypeMenu) {"3.1 Scenario 1"};
  NumMenu[32] = (TypeMenu) {"3.2 Scenario 2"};
}

void setup() { /* Ici rien de bien compliqué !  */
  pinMode(LED, OUTPUT);
  digitalWrite(13, HIGH);
  Serial.begin(115200);
  Initialisation();
  lcd.begin(16, 2);
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("   * DBSoft *   ");
  lcd.setCursor(0, 1);
  lcd.print("Programme Camera");
  delay(1000);
}

void loop() { /* Lancement de tous les sous programmes qui ne s'executeront que si une

variable les y autorises ici la variables Clignote pour le sous programme

LedClignotante ! */
  LedClignotante(); /* Sous programme pour le Led */
  Boutons(); /* Sous programme lecture des Boutons */
}

void Boutons() { /* Mon afficheur LCD comporte 6 boutons qui agissent  sur l'entrée

Analogique "A0". A chaque crénaux de valeur correspond un touche (Select, Up, Down,

Left, Right, Reset)   à toi de modifier ce programme pour les entrées digitales que tu

utilises !  */

  int Analog = analogRead (0);
  delay(5);
  while (Analog <1000){
  if (Analog < 100) { /* Bouton Left  */
    SousMenu++;
    AfficheMenu();
  } else if (Analog < 200) { /* Bouton Down  */
    Menu = Menu - 10;
    SousMenu = 0 ;
    AfficheMenu();
  } else if (Analog < 400) { /* Bouton Up */
    Menu = Menu + 10;
    SousMenu = 0;
    AfficheMenu();

  } else if (Analog < 500) { /* Bouton Right  */
    SousMenu--;
    AfficheMenu();

  } else if (Analog < 800) { /* Bouton Select */
    switch (Menu + SousMenu) {
      case  21 :
        if (!(Clignote == 50)) /* Quand cette variable est différente de "0" le programme

LedClignotante  est activé avec ici la valeur de 50  */
          Clignote = 50;
        else
          Clignote = 0 ;
        digitalWrite(LED, LOW);
        break;
      case  22 :
        if (!(Clignote == 500)) /* Idem qu'un peu plus haut mais avec une valeur ici de

500  */
          Clignote = 500;
        else
          Clignote = 0 ; /* Arrêt du programme LedClignotante!  */
        digitalWrite(LED, LOW); /* Forçage de l'extiction de la Led  */
        break;
    }
  } else if (Analog == 1023) { /* Ne fait Rien lorque aucun bouton n'est activé ! */
  }
  delay(250); /* Délai pour faire défiler les menus et sous menus  */
  Analog = analogRead (0);} /* Ici pour éviter que les selections ne se fassent trop vite */
   
}

void AfficheMenu() { /* Les Index avec "0" comme unité affichés sur la ligne du haut */
  if (Menu == 0 )
    Menu = 30;
  if (Menu == 40 )
    Menu = 10;
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(NumMenu[Menu].Menu);
  lcd.setCursor(0, 1);
  if ( SousMenu < 0 )
    SousMenu = 0;
  if (NumMenu[Menu + SousMenu].Menu == "") /* Détection de la fin des sous menu

pour un menu Selectionné */

    SousMenu = 0;
  if (Menu + SousMenu > Menu)
    lcd.print(NumMenu[Menu + SousMenu].Menu); /* Les Index avec autre que "0" comme unité affichés sur la ligne du bas */
}

void LedClignotante() { /* L'utilisation de Millis() permet de ne pas interrompre le

cycle  du "loop()" (Boucle) qui te permet de lire en permanence l'état des boutons voir

  d'exécuter d'autres sous programmes simultanément  */
  if (Clignote > 0) {
    if ((digitalRead(LED) == HIGH & DelaiOFF < millis())) {
      DelaiON = millis() + Clignote;
      digitalWrite(LED , LOW);
    }
    if ((digitalRead(LED) == LOW) & ( DelaiON < millis())) {
      DelaiOFF = millis() + Clignote;
      digitalWrite(LED , HIGH);
    }
  }
}
/* Voilà, j'espère avoir été clair dans mon programme et les commentaires associés  tu

peux toujours me poser des questions si tu ne comprends pas tel ou tels points  que

j'aurais mal expliqué(s)  */
 

Je pense que cette façon de faire est plus claire que la librairie de " MenuBackend " que tu as utilisé de plus, ainsi tu es maître de l'ensemble de ton programme qui en plus est plus concis !

Portrait de brossden

Voici mon LCD qui se plug directement sur l"Arduino Mega ou Uno  Tu peux voir les boutons et bas a gauche !

menuphoto2.jpg

Portrait de brossden

Bonjour Gael

Voici le lien qui te permettra de voir la vidéo que j'ai faite avec le module LCD KeyPad Shield et un Arduino Mega :

Menu.wmv

J'espère que cette vidéo t'expliquera clairement le mode de fonctionnement de ce montage.

Bonne Journée à tous

Portrait de brossden

Gael

Comme mon programme ne me satisfaisait pas lors du maintient d'une touche appuyée je l'ai modifié pour le rendre insensible à ce problème je laisse l'ancien code pour que tu puisses voir la différence

#include <LiquidCrystal.h>
//Déclarations des variables

LiquidCrystal lcd(8, 9, 4, 5, 6, 7); /* Attention ce sont des valeurs pour mon LCD !!!! */
int LED = 51; /* Port que j'utilise pour ma Led qui Clignote */
int unsigned Menu = 0; /* Cette variable est incrémentée de 10 en 10 et permet
  d'afficher  les Menus sans sous Menu possibilité ici de 10 menu mais tu peux monter à
  100 ou plus */

int unsigned SousMenu = 0 ; /* Cette variable permet d'afficher les sous menus
  associés  à chaque menu (ici de 1 à 9 donc neuf sous menu par menu */

double DelaiON; /* Temps durant lequel la LED reste Allumée */
double DelaiOFF; /* Temps durant lequel la LED reste Éteinte */
int Analog ; /* Valeur de l'ntrée Analogique A0 */
double Tempo = millis(); /* Delai entre deux lectures des boutons */
int Clignote = 0; /* Cette variable permet d'activer ou  désactiver le sous programme
  de  clignotement. J'en profite dans ce programme pour déterminer le temps de
  clignotement */

typedef struct {
  /* Une structure permet de faire une liste de variables qui pourront être
    appelées avec un index numérique. */
  String Menu;  
}
/* Définition du ou des champs de la structure */
TypeMenu; /*Nom de la Structure */
TypeMenu NumMenu[100]; /* Limitation du nombre d'enregistrements de la base de
  donnée NumMenu  ayant comme champs les mêmes que la structure TypeMenu */

void Initialisation() { /* Création de la base de donnée, tu remarqueras que les dizaines
    avec  pour unité "0" correspondent au Menu ! et les autre aux sous Menus !  */

  NumMenu[10] = (TypeMenu) {
    "1 DECL STATIQUE"}; /*10, 11 ,12 ... correspondent à l'index  */
  NumMenu[11] = (TypeMenu) {"1.1 Cde manuelle"};
  NumMenu[12] = (TypeMenu) {"1.2 Laser"};
  NumMenu[20] = (TypeMenu) {"2 TRAVELING"};
  NumMenu[21] = (TypeMenu) {"2.1 1ph/50 msec"};
  NumMenu[22] = (TypeMenu) {"2.2 1ph/500 msec"};
  NumMenu[23] = (TypeMenu) {"2.3 Cmd Motorisee"};
  NumMenu[30] = (TypeMenu) {"3 Scenarios"};
  NumMenu[31] = (TypeMenu) {"3.1 Scenario 1"};
  NumMenu[32] = (TypeMenu) {"3.2 Scenario 2"};
}

void setup() { /* Ici rien de bien compliqué !  */
  pinMode(LED, OUTPUT);
  digitalWrite(13, HIGH);
  Serial.begin(115200);
  Initialisation();
  lcd.begin(16, 2);
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("   * DBSoft *   ");
  lcd.setCursor(0, 1);
  lcd.print("Programme Camera");
  delay(1000);
}

void loop() { /* Lancement de tous les sous programmes qui ne s'executeront que si une
    variable les y autorises ici la variables Clignote pour le sous programme
    LedClignotante ! */
  LedClignotante(); /* Sous programme pour le Led */
  Boutons(); /* Sous programme lecture des Boutons */
}

void Boutons() {
  /* Mon afficheur LCD comporte 6 boutons qui agissent  sur l'entrée
    Analogique "A0". A chaque crénaux de valeur correspond un touche (Select, Up, Down,
    Left, Right, Reset)   à toi de modifier ce programme pour les entrées digitales que tu
    utilises !  */

  if ( millis() > Tempo )/* Si une touche a été appuyée on attent que Tempo soit repassé
  en dessous de millis()  pour éviter que les selections ne se fassent trop vite */
  {
    Analog = analogRead (0);
    delay(5);
    if (Analog < 1000) {
      Tempo = millis() + 500; /*Une toche a été appuyée donc on rend Tempo supérieur à millis()*/

      if (Analog < 100) { /* Bouton Left  */
        SousMenu++;
        AfficheMenu();
      } else if (Analog < 200) { /* Bouton Down  */
        Menu = Menu - 10;
        SousMenu = 0 ;
        AfficheMenu();
      } else if (Analog < 400) { /* Bouton Up */
        Menu = Menu + 10;
        SousMenu = 0;
        AfficheMenu();

      } else if (Analog < 500) { /* Bouton Right  */
        SousMenu--;
        AfficheMenu();

      } else if (Analog < 800) { /* Bouton Select */
        switch (Menu + SousMenu) {
          case  21 :
            if (!(Clignote == 50)) /* Quand cette variable est différente de "0" le programme

  LedClignotante  est activé avec ici la valeur de 50  */
              Clignote = 50;
            else
              Clignote = 0 ;
            digitalWrite(LED, LOW);
            break;
          case  22 :
            if (!(Clignote == 500)) /* Idem qu'un peu plus haut mais avec une valeur ici de
  500  */
              Clignote = 500;
            else
              Clignote = 0 ; /* Arrêt du programme LedClignotante!  */
            digitalWrite(LED, LOW); /* Forçage de l'extiction de la Led  */
            break;
       }
      } else if (Analog == 1023) { /* Ne fait Rien lorque aucun bouton n'est activé ! */
     }
   }
    Analog = 1023; /* Réinitialise Analog" */
  }

}

void AfficheMenu() { /* Les Index avec "0" comme unité affichés sur la ligne du haut */
  if (Menu == 0 )
    Menu = 30;
  if (Menu == 40 )
    Menu = 10;
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(NumMenu[Menu].Menu);
  lcd.setCursor(0, 1);
  if ( SousMenu < 0 )
    SousMenu = 0;
  if (NumMenu[Menu + SousMenu].Menu == "") /* Détection de la fin des sous menu

  pour un menu Selectionné */

    SousMenu = 0;
  if (Menu + SousMenu > Menu)
    lcd.print(NumMenu[Menu + SousMenu].Menu); /* Les Index avec autre que "0" comme unité affichés sur la ligne du bas */
}

void LedClignotante() {
  /* L'utilisation de Millis() permet de ne pas interrompre le

    cycle  du "loop()" (Boucle) qui te permet de lire en permanence l'état des boutons voir

    d'exécuter d'autres sous programmes simultanément  */
  if (Clignote > 0) {
    if ((digitalRead(LED) == HIGH & DelaiOFF < millis())) {
      DelaiON = millis() + Clignote;
      digitalWrite(LED , LOW);
    }
    if ((digitalRead(LED) == LOW) & ( DelaiON < millis())) {
      DelaiOFF = millis() + Clignote;
      digitalWrite(LED , HIGH);
    }
  }

}
/* Voilà, j'espère avoir été clair dans mon programme et les commentaires associés  tu

  peux toujours me poser des questions si tu ne comprends pas tel ou tels points  que

  j'aurais mal expliqué(s)  */

Bonne Journée à tous

Portrait de brossden

Salut Gael

Pour gérer tes moteurs pas à pas je te conseille de voir mon post gerer-un-moteur-puissant-pas-pas

Bonne journée à tous

Portrait de gael

Je suis en train d'adapter le programme en premier lieu avec mes boutons. Je t'avoue que j'ai beaucoup de mal. C'est un niveau de C assez complexe pour moi.

J'ai compris le principe de "Analog" dans le programme.

J'ai tout d'abord déclaré mes boutons comme :

CONST INT SELECT = A0;

CONST INT UP = A1 et ainsin de suite.

Ensuite je les déclare en entrée dans le set up.

Comme : pinMode(SELECT, INPUT);

digitalWrite(SELECT, LOW);

etc....

Ensuite de void Boutons()

Je remplace "Analog" par le bouton correspondant "SELECT" par exemple. Je sais qu'il faut que je remplace les valeurs analogiques "100", "200"......mais je ne sais pas quoi mettre à la place.

J'ai bien compris le système de lancement du sous programme avec la valeur "50" "500", le bouton SELECT et la "case" qui correspond à la sélection du sous item.

J'ai une fois vérifier le programme, juste avec mes déclarations des boutons, et le set up et il me dit que LedClignotant n'est pas déclaré.

Je sens que ca va être dur pour moi.

Portrait de brossden

C'est normal tu ne doit pas tu ne dois pas utiliser Analog pour tes boutons car c'est spécifique à mon afficheur mais la syntaxe classique

int BoutonGauche = 3 ; // J'ai pris trois comme exemple dans les déclarations

pinMode(BoutonGauche, INPUT_PULLUP); // Dans le void setup()

if (digitalRead(BoutonGauche) == LOW) {

/// La suite de ton code ... dans le void Boutons() ;

Voilà !

Bonne journée à tous

Portrait de gael

Voici le programme avec les modifs de boutons 

Portrait de brossden

Voici le programme corrigé sketch_jul12a.ino

Attention verifie bien les paramètres de : LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

pour qu'ils soit compatible avec ton module LCD !

Je crois que pour toi c'est LiquidCrystal lcd(2, 3, 4, 5, 6, 7);  si je me réfère à ton programme tout au début de ce sujet

Portrait de gael

Du nouveau, j'ai terminé (je sais il est tard) un programme qui permet à l'APN de se déplacer et de prendre une photo. Maintenant je dois le rajouter dans mon menu. Qu'en penses-tu du programme? (je sais que le delay n'est pas forcément la bienvenue).

A bientôt et bonne soirée à tous!

Portrait de gael

J'ai incorporé la commande manuelle dedans, cool!

Portrait de brossden

Tant mieux si tu as d'autres problème n'hésite pas !

Bonne Journée à tous