voici le code que j'ai écrit pour le menu mais je n arrive toujours pas a entrée dans le sous menu
#include <LiquidCrystal.h>
#include <Adafruit_Keypad.h>
// initialize the library by associating any needed LCD interface pin
// with the arduino pin number it is connected to
const int rs = A0, en = A2, d4 = A3, d5 = A4, d6 = A5, d7 = A6;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);
const byte ROWS = 4; // rows
const byte COLS = 4; // columns
uint8_t rowPins[] = { 13, 12, 11, 10 };
uint8_t colPins[] = {9, 8, 7, 6};
//define the symbols on the buttons of the keypads
char keys[ROWS][COLS] = {
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
byte rowsPins[ROWS] = {13, 12, 11, 10}; //connect to the row pinouts of the keypad
byte colsPins[COLS] = {9, 8, 7, 6}; //connect to the column pinouts of the keypad
//initialize an instance of class NewKeypad
Adafruit_Keypad customKeypad = Adafruit_Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS);
const byte LCD_A = 0x3F; // adresse du LCD en 0x3F
const byte LCD_L = 4; // 4 Lignes
const byte LCD_C = 16; // de 20 caractères
/* GESTION SIMPLE D'UN MENU */
/* un menu est composé de plusieurs lignes de commandes /
/ chaque ligne présente un texte, à une touche d'activation et une fonction à appeler /
struct t_LigneMenu {
const charvalide; // le texte à afficher
const char A; // la touche du keypad à appuyer
void (*action)(char); // la fonction a apppeler en cas d'appui, avec en paramètre la touche de commande
};
struct t_menu {
const uint8_t nbLignes; // le nombre de lignes actives dans le menu
t_LigneMenu menu[LCD_L]; // les lignes, au maximum le nombre de lignes du LCD
};
// on a la notion de menu actif, celui qui s'affiche quand
// on appele la fonction afficheMenu()
// si ce menuActif est NULL c'est qu'on n'a pas de menu à afficher.
t_menu* menuActif = NULL;
// on a deux fonctions utilitaires, une pour afficher le menu en cours
// l'autre pour gérer les interactions avec le Menu (s'il est non NULL)
// retourne true si un menu était à afficher
bool afficheMenu()
{
if (menuActif == NULL) return false; // pas de menu
// sinon on efface l'écran et présente le menu
lcd.clear();
for (uint8_t c = 0; c < menuActif->nbLignes; c++) {
lcd.setCursor(0, c);
lcd.print(menuActif->menu[c].valide);
}
return true;
}
// retourne true si un menu a été déclenché, la fonction aura été appelée
bool gestionMenu()
{
if (menuActif == NULL) return false; // pas de menu
// sinon on regarde si elle correspond à une touche autorisée
bool executionMenu = false;
for (uint8_t c = 0; c < menuActif->nbLignes; c++) {
executionMenu = true; // on dit qu'on a effectué une action
break; // pas la peine d'aller voir plus loin, on sort du for
}
}
// ***********************************************************
// le menu appelle des fonctions qui sont de signature 'void f(char) {...}'
// on pré-définit ces fonctions pour pouvoir déclarer les menus
void actionsSousMenu(char c);
void actionsA(char c);
void actionsB(char c);
// maintenant on définit les menus
t_menu menuPrincipal = {
3, // 2 entrées actives
{
{"[A] DEMINAGE", 'key A', actionsSousMenu},
{"[B] MISSILE", 'key B', actionsSousMenu},
{NULL, '\0', NULL},
{NULL, '\0', NULL},
}
};
t_menu sousMenuA = {
3, // 3 entrées actives
{
{"[1] fonction A1", '1', actionsA},
{"[2] fonction A2", '2', actionsA},
{"[3] fonction A3", '3', actionsA},
{NULL, '\0', NULL}
}
};
t_menu sousMenuB = {
4, // 4 entrées actives
{
{"[1] fonction B1", '1', actionsB},
{"[2] fonction B2", '2', actionsB},
{"[3] fonction B3", '3', actionsB},
{"[4] fonction B4", '4', actionsB}
}
};
t_menu sousMenuC = {
4, // 4 entrées actives
{
{"[1] fonction B1", '1', actionsB},
{"[2] fonction B2", '2', actionsB},
{"[3] fonction B3", '3', actionsB},
{"[4] fonction B4", '4', actionsB}
}
};
// On définit ce que doivent faire les fonctions.
// ici le menu principal (A/B) affiche un sous menu associé
// qui appelleront soit la fonction actionsA ou actionsB
// avec en paramètre la touche de déclenchement ce qui permet de savoir quoi faire
void actionsSousMenu(char c)
{
Serial.print(F("Appel sous menu, touche ["));
Serial.write(c);
Serial.println(F("]"));
switch (c) {
case 'A':
menuActif = &sousMenuA; // on choisit le prochain menu
break;
case 'B':
menuActif = &sousMenuB; // on choisit le prochain menu
break;
default: // ne devrait pas arriver on conserve le même menu
break;
}
}
void actionsA(char c)
{
Serial.print(F("Actions A — choix ["));
Serial.write(c);
Serial.println(F("]"));
menuActif = &menuPrincipal; // on revient au menu principal
}
void actionsB(char c)
{
Serial.print(F("Actions B — choix ["));
Serial.write(c);
Serial.println(F("]"));
menuActif = &menuPrincipal; // on revient au menu principal
}
// ----------------------
void setup()
{
lcd.begin(16, 2);
Serial.begin(9600);
lcd.clear();
Serial.begin(9600);
customKeypad.begin();
menuActif = &menuPrincipal; // on dit quel est le menu actif
afficheMenu(); // et on l'affiche
}
void loop()
{
if (gestionMenu()) afficheMenu();// si un déclenchement a été fait, il y a peut-être un nouveau menu
// ici on peut faire autre chose
// ne pas toucher l'affichage si un menu est actif bien sûr (sinon le menu disparait)
{
// put your main code here, to run repeatedly:
customKeypad.tick();
while(customKeypad.available()){
keypadEvent e = customKeypad.read();
Serial.print((char)e.bit.KEY);
if(e.bit.EVENT == KEY_JUST_PRESSED) Serial.println(" pressed");
else if(e.bit.EVENT == KEY_JUST_RELEASED) Serial.println(" released");
}
delay(10);
}
}