MENU LCD

Bonjour,
étant novice sur Arduino, j'aurais besoin d'aide pour afficher un menu sur un LCD 64*128.
Je ne sais vraiment pas par ou commencer...
j'arrive bien a afficher une image et du texte lors de l'initialisation mais je n'arrive pas à créer ce menu.
Je voudrais faire:
Un menu principal, avec des sous menus États, Valeurs,Configuration et information.
Dans lesquels, on trouvera des messages dans états, des valeurs dans le menu valeurs, des variables a modifier dans Configuration et du texte dans information
Pour gérer tout ça, j'ai 4 boutons poussoirs OK,ESC,Haut,Bas.
Pouvez vous m'aider un peu.
Merci d'avance
Cordialement
Arnaud

Bonjour,

Grosso modo, tu peux parfaitement utiliser la fonction switch/case pour établir et contraindre tes menus et sous-menus à réaliser les actions que tu désires. Avec un peu de logique et en rafraichissant l'écran à chaque manipulation, tu devrais pouvoir faire quelque chose de fonctionnel. Il n'y a rien de bien compliqué en fait.

tu définis en premier lieu tes calques qui afficheront soit des sous-menus, soit des valeurs.

calque_1 -> menu principal
calque_2 -> sous-menu 1
calque_3 -> sous-menu 2
calque_4 -> valeurs du sous-menu 1
etc.

Chacun des calques contiendront les routines textes/géométries/valeurs que tu veux.

Ensuite, dans ta boucle principale, tu écoutes les boutons et gères les opérations adéquates en manipulant des variables de gestion comme la position du curseur, sa limite, sa déstination, etc.
C'est ici que la fonction switch/case peut devenir intéressante.

switch(menu) {
  case(0) : calque_1; break;
  case(1) : calque_2; break;
  ...
  }

C'est une possibilité parmis tant d'autres, tout dépend de ton programme et de sa complexité.

@+

Zoroastre.

Bonjour,
Merci de votre réponse par contre, je n'arrive pas à sélectionner les menus, j'ai bien mes calques qui fonctionnent mais je ne trouve pas comment se déplacer dans les menus.
N'avez vous pas un bout de code que je pourrais travailler ou un début de quelque chose...
Merci d'avance

Une piste comme une autre :

tu dessines une flèche pour montrer la ligne en cours de selection qui s'affiche en fonction d'une variable qui est incrémentée ou décrémentée suivant que tu appuis sur les bouton haut et bas. Puis quand tu appuis sur valider, suivant la position de la flèche tu passes à un menu ou à un autre

bonjour,
Le résultat de mes essais est le plantage du programme...
N'avez vous pas un exemple, je n'arrive pas a sélectionner un menu, ni créer une flèche qui se déplace...
Merci d'avance

Bonjour,
J'ai un petit peu avancé, j'arrive a faire apparaitre des Menus mais je ne comprend pas comment faire un sous menu avec des variables a modifier a l’écran pour être réutilisées dans le programme. Pouvez vous me dire comment l'on fait un sous menu avec des variables a modifier.
Merci d'avance de votre aide

Bonjour,

L'idéal serait que tu nous proposes ton code pour que l'on puisse travailler dessus ensemble. A ce stade, on ne peut que te proposer des conseils.

Tu dois avoir une ou plusieurs fonctions pour effacer l'écran je suppose, elles doivent être appeler à chaque pilotage que tu fais. Normalement, le rafraichissement doit être invisible.

Je peux te proposer en lecture un code perso que j'avais réalisé lors de mon tout premier projet domotique, utilisation d'un écran tactile. La classe "Objet", "IHM", les feuilles de style "Layer" et les quelques variables qui tournent autour peuvent peut-être t'orienter.

J'étais à mes tout début, c'est donc peu conventionnel mais ça fonctionnait pas trop mal. (Faut faire le ménage avec tout ce qui ne t'ai pas utile...)

Autrement, je crois qu'il existe une librairie qui propose de faciliter la création de menu à travers l'arduino. Je vais essayer de la retrouver.

@+

Zoroastre.

Bonjour,
Je vais mieux expliquer ce que je veux faire...
Je voudrais faire un menu avec ses sous menus afin d'y afficher des variables, de pouvoir les modifier afin qu'elle soient réutilisable dans le programme.
MENU: États avec des messages qui apparaitront.
MENU: Valeurs, avec des valeurs actuelles
MENU: Configuration,
SOUS MENU: variables de configuration à enregistrer dans le programme.
Les Boutons poussoirs sont montés sur un PCA8574 (Expander I2C) et sont lus lors d'une interruption généré par le PCA. Mon LCD 128*64 est connecté au microcontrôleur en mode 8 Bits
Voila mon code.

// --- Inclusion des librairies utilisées ---
#include <Wire.h>
#include <glcd.h>
#include "fonts/allFonts.h" // system and arial14 fonts are used
#include "bitmaps/allBitmaps.h" // all images in the bitmap dir

#include "TimerOne.h"

// 8574A Address range is 0x38-0x3F
#define PCA8574A_Adr 0x38 // Adresse du CI de gestion des BP
#define PCA9551_Adr 0x60 // Adresse du CI de gestion des DEL

Image_t icon;

gText textArea; // a text area to be defined later in the sketch
gText textAreaArray[3]; // an array of text areas
gText countdownArea = gText(GLCD.CenterX,GLCD.CenterY,1,1,Arial_14); // text area for countdown digits

// --- Déclaration des constantes ---
unsigned long startMillis;
unsigned int loops = 0;
unsigned int iter = 0;
int theDelay = 20;

// --- constantes des broches ---
// Pin 13 has an Led connected on most Arduino boards.
// give it a name:

// --- Déclaration des variables globales ---
int Del_R_Buz = 17;
int Del_J = 3;
// int Int_BP = 0; // interruption INT0, pin 2

volatile unsigned long button_time = 0;
volatile unsigned long last_button_time = 0;
int debounce = 250; // debounce latency in ms

volatile int Etat = LOW; // Variable volatile car entre dans une interruption. Toute valeur
// modifiée à l’intérieur de la routine d’interruption devra être déclarée comme volatile,
// afin que le processeur aille chercher la valeur en mémoire et ne se fie pas à ce qui se
// trouve dans ses registres qui étaient gelés au moment de l’interruption.

volatile byte Data;

volatile byte Menu;

volatile byte Int0_Active;

byte Ligne_Up;
byte Ligne_Down;

byte Clignotement;

byte Valeur1;
byte Valeur2;
byte Valeur3;
byte Valeur4;
byte Valeur5;
byte Valeur6;
byte Valeur7;
byte Valeur8;
byte Valeur9;
byte Valeur10;

byte Etat_Del_Rouge;
byte Etat_Del_Orange;

byte Entree1;
byte Entree2;
byte Entree3;
byte Entree4;

void setup() {
// --- ici instructions à exécuter au démarrage ---

// ------- Broches en sortie -------

pinMode(Del_R_Buz, OUTPUT);
pinMode(Del_J, OUTPUT);

// ------- Broches en entrée -------
// ------- Activation du rappel au + interne des broches en entrée si nécessaire -------

digitalWrite(Del_R_Buz, LOW);
digitalWrite(Del_J, LOW);

Etat_Del_Rouge = 0x00;
Etat_Del_Orange = 0x00;

// initialisation du port série 9600 bits par seconde:
Serial.begin(9600);

// Initialisation de l'I2C
Wire.begin(); // join i2c bus (address optional for master)

// Initialisation Timer 1
Timer1.initialize(300000); // initialize timer1, and set a 300mS
Timer1.attachInterrupt(Interruption_Timer1); // attaches Interruption_Timer1() as a timer overflow interrupt

// Initialisation Interruption INT0 sur PD2
// Fonction attachInterrupt (param1, param2, param3)
// param1 : numéro d’interruption à utiliser (0 ou 1);
// param2 : fonction à exécuter lors de l’interruption; elle ne peut avoir de paramètres et ne retourne rien.
// param3 : le type de déclenchement de l’interruption; il y a 4 types de déclenchements possible
// LOW : l’entrée est au niveau bas;
// RISING : l’entrée passe du niveau bas au niveau haut;
// FALLING : l’entrée passe du niveau haut au niveau bas;
// CHANGE : l’entrée a changé de niveau.
// attachInterrupt(Int_BP, Interruption_Int0, RISING); // FALLING

// attachInterrupt(0, Interruption_Int0, FALLING); // FALLING
attachInterrupt(0, Interruption_Int0, FALLING); // FALLING

// Initialisation du LCD.
GLCD.Init(); // initialise the library, non inverted writes pixels onto a clear screen
icon = DOMOTIQUE64x128; // the 64 pixel high icon
// introScreen();
GLCD.DrawBitmap(icon, 0,0); //draw the bitmap at the given x,y position

delay(2000);

GLCD.ClearScreen();

} // Fin du void setup()

void loop()
{
// --- ici instructions à exécuter par le programme principal ---

digitalWrite(Del_R_Buz, Etat_Del_Rouge); // la LED reflète l'état de la variable
digitalWrite(Del_R_Buz, Etat_Del_Orange); // la LED reflète l'état de la variable

Update_BP();

Update_Menus();

// digitalWrite(Del_J, LOW);

// --- Fin programme ---

} // fin de la fonction loop() - le programme recommence au début de la fonction loop sans fin
// *********************************************************************************************

void Update_BP()
{
if (Int0_Active == 0x01) // Si interruption Int0 est active
{
delay (100); // Gestion Anti Rebonds

Wire.requestFrom(PCA8574A_Adr, 1); // Demander un bit à l'esclave I2C #
// while(Wire.available()) // slave may send less than requested
// {
Data = Wire.read();
Wire.endTransmission();
Serial.print("0x");
Serial.println(Data,HEX);
// }

if (Data != 0xFF) // Si Data est différent de 0xFF
{

switch (Data)
{
case (0xFE) : // BP OK // Si BP OK activé, affiche le menu principal.
Serial.println("BP_OK");
delay (100) ; // Gestion Anti Rebonds

if (Menu == 0x00) // Si On est sur la page d'acceuil alors selectionner le menu principal (Si Menu = 0x00)
{
Menu = 0x01; // Afficher Menu Principal
} // Fin du if (Menu == 0x00)

if (Menu == 0x05) // Si On est sur la page Configuration (Si Menu = 0x05)
{
Menu = 0x06; // Afficher Menu Configuration Actions
Menu_Configuration2();
} // Fin du if (Menu == 0x05)

break ;

case (0xFD) : // BP UP
Serial.println("BP_UP");
delay (100) ; // Gestion Anti Rebonds
if ( Menu != 0x00) // Si on est sur la page d'acceuil
{
Menu = Menu - 1;
Ligne_Up = Ligne_Up - 1;
break ;
} // Fin du if ( Menu == 0x00)

case (0xFB) : // BP DOWN
Serial.println("BP_DOWN");
delay (100) ; // Gestion Anti Rebonds
if ( Menu != 0x00) // Si on est sur la page d'acceuil
{
Menu = Menu + 1;
Ligne_Down = Ligne_Down + 1;
break ;
} // Fin du if ( Menu == 0x00)

case (0xF7) : // BP ESC
Serial.println("BP_ESC");
delay (100) ; // Gestion Anti Rebonds
Menu = 0x00;
break ;

case (0xEF) : // BP RESET
Serial.println("BP_RESET");
delay (100) ; // Gestion Anti Rebonds
break ;

case (0xDF) : // BP ON
Serial.println("BP_ON");
delay (100) ; // Gestion Anti Rebonds
break ;

case (0xBF) : // BP OFF
Serial.println("BP_OFF");
delay (100) ; // Gestion Anti Rebonds
break ;

// case (0xFF) : // Aucun BP appuyés
// Serial.println("NONE");
// break ;

// default :
// Serial.println("DEFAUT");

} // Fin du switch (Data)

} // Fin du if (Data != 0xFF)

} // Fin du if (Int0_Active == 0x01)

Int0_Active = 0x00;

} // Fin du void Update_BP()

void Update_Menus()
{

if (Int0_Active = 0x01)
{

if (Data != 0xFF) // Si Data est différent de 0xFF
{

if (Menu > 5)
{
Menu = 0;
}

switch (Menu)
{
case (0x00) : //
Menu_Acceuil();
break ;

case (0x01) : //
Menu_Principal();
break ;

case (0x02) : //
Menu_Etat();
break ;

case (0x03) : //
Menu_Valeurs();
break ;

case (0x04) : //
Menu_Informations();
break ;

case (0x05) : //
Menu_Configuration();
break ;

// case (0x06) : //
// Menu_Configuration2();
// break ;

} // Fin du switch (Menu)
} // Fin du if (Data != 0xFF)
} // Fin du if (Int0_Active = 0x01)
} // Fin du void Update_Menus()

// INTERRUPTIONS:
void Interruption_Timer1()
{
// Serial.println("Interruption_Timer1");

Clignotement = !Clignotement; // inverse l'état de la variable
} // Fin du void Interruption_Timer1()

// Traitement de l'Interruption INTO sur pin D2
void Interruption_Int0()
{
cli(); // arrêt des interruptions
// Serial.println("Interruption_Int0");
Int0_Active = 0x01;
// Serial.println(Int0_Active);
sei(); // autorisation des interruptions

} // Fin du void Interruption_Int0()

// Suite

// Gestion des Menus du LCD

void Menu_Acceuil()
{
// Efface l'écran
GLCD.ClearScreen();
// Selectionne la fonte suivante
GLCD.SelectFont(System5x7,BLACK );
// Place le curseur à l'endroit indiqué (x,y)
GLCD.CursorToXY(10,28);
// Ecrit
GLCD.print("CENTRALE DOMOTIQUE");
} // Fin du void Menu_Acceuil()

void Menu_Principal()
{
Serial.println("Menu_Principal");

// Efface l'écran
GLCD.ClearScreen();
// Trace et Remplit l'interieur d'un rectangle(x,y,Largeur,Hauteur,BLACK/WHITE)
GLCD.FillRect(0,0,127,10,BLACK);
// Selectionne la fonte suivante
GLCD.SelectFont(System5x7,WHITE );
// Place le curseur à l'endroit indiqué (x,y)
GLCD.CursorToXY(47,2);
// Ecrit
GLCD.print("MENU");

// Trace et Remplit l'interieur d'un rectangle(x,y,Largeur,Hauteur,BLACK/WHITE)
GLCD.FillRect(0,13,127,10,BLACK);
// Selectionne la fonte suivante
GLCD.SelectFont(System5x7,WHITE);
// Place le curseur à l'endroit indiqué (x,y)
GLCD.CursorToXY(44,15);
// Ecrit
GLCD.print("ETATS");

// Trace et Remplit l'interieur d'un rectangle(x,y,Largeur,Hauteur,BLACK/WHITE)
GLCD.FillRect(0,26,127,10,BLACK);
// Selectionne la fonte suivante
GLCD.SelectFont(System5x7, WHITE);
// Place le curseur à l'endroit indiqué (x,y)
GLCD.CursorToXY(12,28);
// Ecrit
GLCD.print("VALEURS ACTUELLES");

// Trace et Remplit l'interieur d'un rectangle(x,y,Largeur,Hauteur,BLACK/WHITE)
GLCD.FillRect(0,39,127,10,BLACK);
// Selectionne la fonte suivante
GLCD.SelectFont(System5x7, WHITE);
// Place le curseur à l'endroit indiqué (x,y)
GLCD.CursorToXY(22,41);
// Ecrit
GLCD.print("INFORMATIONS");

// Trace et Remplit l'interieur d'un rectangle(x,y,Largeur,Hauteur,BLACK/WHITE)
GLCD.FillRect(0,52,127,10,BLACK);
// Selectionne la fonte suivante
GLCD.SelectFont(System5x7, WHITE);
// Place le curseur à l'endroit indiqué (x,y)
GLCD.CursorToXY(24,54);
// Ecrit
GLCD.print("CONFIGURATION");
} // Fin du void Menu_Principal()

void Menu_Etat()
{
Serial.println("Menu_Etats");
// Efface l'écran
GLCD.ClearScreen();
// Trace et Remplit l'interieur d'un rectangle(x,y,Largeur,Hauteur,BLACK/WHITE)
GLCD.FillRect(0,0,127,10,BLACK);
// Selectionne la fonte suivante
GLCD.SelectFont(System5x7,WHITE);
// Place le curseur à l'endroit indiqué (x,y)
GLCD.CursorToXY(44,2);
// Ecrit
GLCD.print("ETATS");

// Selectionne la fonte suivante
GLCD.SelectFont(System5x7,BLACK);
// Place le curseur à l'endroit indiqué (x,y)
GLCD.CursorToXY(0,15);
// Ecrit
GLCD.print("ETAT DEL ROUGE:");
GLCD.print(Etat_Del_Rouge);

// Place le curseur à l'endroit indiqué (x,y)
GLCD.CursorToXY(0,30);
// Ecrit
GLCD.print("ETAT DEL ORANGE:");
GLCD.print(Etat_Del_Orange);

} // Fin du void Menu_Etat()

void Menu_Valeurs()
{
Serial.println("Menu_Valeurs");
// Efface l'écran
GLCD.ClearScreen();
// Trace et Remplit l'interieur d'un rectangle(x,y,Largeur,Hauteur,BLACK/WHITE)
GLCD.FillRect(0,0,127,10,BLACK);
// Selectionne la fonte suivante
GLCD.SelectFont(System5x7,WHITE);
// Place le curseur à l'endroit indiqué (x,y)
GLCD.CursorToXY(12,2);
// Ecrit
GLCD.print("VALEURS ACTUELLES");

// Selectionne la fonte suivante
GLCD.SelectFont(System5x7,BLACK);
// Place le curseur à l'endroit indiqué (x,y)
GLCD.CursorToXY(0,15);
// Ecrit
GLCD.print(Valeur1);

// Place le curseur à l'endroit indiqué (x,y)
GLCD.CursorToXY(0,28);
// Ecrit
GLCD.print(Valeur2);

// Place le curseur à l'endroit indiqué (x,y)
GLCD.CursorToXY(0,41);
// Ecrit
GLCD.print(Valeur3);

// Place le curseur à l'endroit indiqué (x,y)
GLCD.CursorToXY(0,54);
// Ecrit
GLCD.print(Valeur4);
} // Fin du void Menu_Valeurs()

void Menu_Informations()
{
Serial.println("Menu_Informations");
// Efface l'écran
GLCD.ClearScreen();
// Trace et Remplit l'interieur d'un rectangle(x,y,Largeur,Hauteur,BLACK/WHITE)
GLCD.FillRect(0,0,127,10,BLACK);
// Selectionne la fonte suivante
GLCD.SelectFont(System5x7,WHITE);
// Place le curseur à l'endroit indiqué (x,y)
GLCD.CursorToXY(24,2);// Ecrit
GLCD.print("INFORMATIONS");

// Selectionne la fonte suivante
GLCD.SelectFont(System5x7,BLACK );
// Place le curseur à l'endroit indiqué (x,y)
GLCD.CursorToXY(35,20);
// Ecrit
GLCD.print("COPYRIGHT");

// Selectionne la fonte suivante
GLCD.SelectFont(System5x7,BLACK );
// Place le curseur à l'endroit indiqué (x,y)
GLCD.CursorToXY(20,35);
// Ecrit
GLCD.print("2014");

// Selectionne la fonte suivante
GLCD.SelectFont(System5x7,BLACK );
// Place le curseur à l'endroit indiqué (x,y)
GLCD.CursorToXY(20,50);
// Ecrit
GLCD.print("FIRMWARE V1.1.3");
} // Fin du void Menu_Informations()

void Menu_Configuration()
{
Serial.println("Menu_Configuration");
// Efface l'écran
GLCD.ClearScreen();
// Trace et Remplit l'interieur d'un rectangle(x,y,Largeur,Hauteur,BLACK/WHITE)
GLCD.FillRect(0,0,127,10,BLACK);
// Selectionne la fonte suivante
GLCD.SelectFont(System5x7,WHITE);
// Place le curseur à l'endroit indiqué (x,y)
GLCD.CursorToXY(22,2);
// Ecrit
GLCD.print("CONFIGURATION");

// Selectionne la fonte suivante
GLCD.SelectFont(System5x7,BLACK);
// Place le curseur à l'endroit indiqué (x,y)
GLCD.CursorToXY(0,22);
// Ecrit
GLCD.print("CONFIGUREZ LES DELS");

// Place le curseur à l'endroit indiqué (x,y)
GLCD.CursorToXY(0,32);
// Ecrit
GLCD.print("DEL ROUGE:");

// Place le curseur à l'endroit indiqué (x,y)
GLCD.CursorToXY(0,42);
// Ecrit
GLCD.print("DEL ORANGE:");

// Selectionne la fonte suivante
GLCD.SelectFont(System5x7,BLACK);
// Place le curseur à l'endroit indiqué (x,y)
GLCD.CursorToXY(70,32);
// Ecrit
GLCD.print(Etat_Del_Rouge);

// Place le curseur à l'endroit indiqué (x,y)
GLCD.CursorToXY(70,42);
// Ecrit
GLCD.print(Etat_Del_Orange);

} // Fin du void Menu_Configuration()

void Menu_Configuration2()
{
Serial.println("Menu_Configuration2");

// Efface l'écran
GLCD.ClearScreen();
// Trace et Remplit l'interieur d'un rectangle(x,y,Largeur,Hauteur,BLACK/WHITE)
GLCD.FillRect(0,0,127,10,BLACK);
// Selectionne la fonte suivante
GLCD.SelectFont(System5x7,WHITE);
// Place le curseur à l'endroit indiqué (x,y)
GLCD.CursorToXY(22,2);
// Ecrit
GLCD.print("CONFIGURATION");

// Selectionne la fonte suivante
GLCD.SelectFont(System5x7,WHITE);
// Place le curseur à l'endroit indiqué (x,y)
GLCD.CursorToXY(0,22);
// Ecrit
GLCD.print("CONFIGUREZ LES DELS");

// Place le curseur à l'endroit indiqué (x,y)
GLCD.CursorToXY(0,32);
// Ecrit
GLCD.print("DEL ROUGE:");

// Place le curseur à l'endroit indiqué (x,y)
GLCD.CursorToXY(0,42);
// Ecrit
GLCD.print("DEL ORANGE:");

// if (Clignotement == 0x01)
// {
// Selectionne la fonte suivante
GLCD.SelectFont(System5x7,WHITE);
// Place le curseur à l'endroit indiqué (x,y)
GLCD.CursorToXY(70,32);
// Ecrit
GLCD.print(Etat_Del_Rouge);

// Place le curseur à l'endroit indiqué (x,y)
GLCD.CursorToXY(70,42);
// Ecrit
GLCD.print(Etat_Del_Orange);

} // Fin du void Menu_Configuration2

Regardes là : http://playground.arduino.cc/Main/LibraryList#menu

Bonjour,
cela est bien mais ne propose pas d'enregistrer un état modifié sur le lcd pour l'enregistrer en tant que variable...

En fin de compte, la question porte sur un problème de menu ou un problème de sauvegarde de valeurs?

Au début, c’était pour faire des menus... Actuellement, je ne parviens pas a sélectionner une variable et à la modifier sur le LCD afin de pouvoir interagir avec le programme...

je n'arrive pas non plus a faire des sous menus...

Personne ???