la gestion d'un clavier 4x3 sans utiliser de bibliothèque et en utilisant le moins d'entrée sortie sur la carte arduino.
le clavier utilisé :
-
Pour commencer j'ai branché les 7 fils du clavier à l'arduino uno 3 entrées et 4 sorties
-
ensuite j'ai utilisé juste 3 entrées analogique et quelques résistances.
-
à suivre ...
le fichier zip avec les cablages et les programmes d'exemple
mise à jour des fichiers le 7/10/2015
- simplification du montage utilise 6 résistances de 10kohms et 3 entrées analogique
exemple de gestion du clavier avec menu et lcd 16x2, j'ai essayer de commenter le plus possible
/* Arduino Uno, clavier 4x3 et écran lcd 16x2 i2c
gestion de menus avec le clavier, touche 8 et 2 navigue dans les menus et # entre dans le menu, la touche * remet à zéro les valeurs
===> les données du tableau eclac[] sont donnée à titre d'exemple car le montage du clavier branché sur une seule entrée analogique n'est pas définitif
=> le mot de passe est '2015'
fifi82 2015
*/
#include <Wire.h> // pour la gestion du lcd
#include <LiquidCrystal_I2C.h> // (i2c liaison série le lcd est branché avec 2 fils)
LiquidCrystal_I2C lcd(63,2,1,0,4,5,6,7,3,POSITIVE); //63 c'est l'adresse de mon afficheur
// pour la gestion du clavier
const int eclav[12]={229,389,495,306,486,594,459,647,742,927,976,992}; // valeurs à récupérée sur l'entrée A0
const int tclav[12]={1,2,3,4,5,6,7,8,9,-3,0,-2}; // correspondance des touches suivant les valeurs ci dessus
int mct1, mct2, ct; // état et anti-rebond du clavier, ct est le code touche appuyé sur un seul scan (front montant)
// pour gerer le mot de passe
boolean pass=0; // est à 1 si le mot de passe est bon
// pour la gestion des menus
const byte nbmenu=4; // nombre de menu
char* menu[nbmenu]={"Mot de passe", " Sortie 13 1/0", " Temps 0 en ms", " Temps 1 en ms"}; // nom des menus pour l'affichage
unsigned int data[nbmenu]={0,0,500,500}; // valeurs des données de chaque menu
byte nmenu=0; // choix du menu dans lequel on se trouve, au début 0 c'est le mot de passe qui débloque l'acces à tous les menus
boolean emenu=1; //état du menu si on est dans le menu ou pas, au début on entre dans le menu du mot de passe
// pour la gestion des timer
unsigned int ptimer[2]={(data[2]),(data[3])}; // le preset du timer deux preset, le premier pour led éteinte le deuxieme pour led allumée
unsigned long timer=0; // temporisation pour le clignotement de la led
unsigned long time; // pour stocker le temps qui passe
void setup()
{
lcd.begin (16,2); // configure le l'afficheur en 16x2
lcd.setBacklight(HIGH); // allume l'afficheur
lcd.home (); // init l’afficheur
pinMode(13, OUTPUT); // la led verte
lcd.blink(); // affiche le pointeur carré clignotant
aff(); // rafraîchit l'écran
}
void loop()
{
mct1=clav(); if (mct1!=mct2) ct=mct2=mct1; // lecture du clavier et mémorisation pour l"anti-rebond front montant
time=millis(); // mémorise le temps qui passe ...
if(emenu){ // si on est dans un menu "état menu"
switch (nmenu) { // choix des menus "numéro menu"
case 0: //menu 0 gestion du mot de passe, bloque l’accès aux autres menus
if(ct>-1) {data[nmenu]=data[nmenu]*10+ct; if (data[nmenu]>9999) data[nmenu]=0; } // création du mot de passe ici je bloque les mots de passe de plus de 4 chiffres
if (data[nmenu]==2015 && ct==-2) pass=1; else pass=0; // mot de passe pour déverrouiller les menus "2015" et # ( de 0 à 65535 )
break;
case 1: // menu 1 etat de la sortie 13
if(ct==1) data[nmenu]=1; // touche 1 active le clignotement de la led verte
if(ct==0) data[nmenu]=0; // touche 0 désactive le clignotement de la led verte
break;
case 2: // temps 0 led éteinte
if(ct>- 1) data[nmenu]=data[nmenu]*10+ct; // entre la valeur du clavier
if(ct==-2) {ptimer[0]=(data[2]); timer=time+ptimer[0]; } // enregistre la valeur et init le timer avec '#'
break;
case 3: // temps 1 led allumée
if(ct>- 1) data[nmenu]=data[nmenu]*10+ct; // entre la valeur du clavier
if(ct==-2) {ptimer[1]=(data[3]); timer=time+ptimer[1];} // enregistre la valeur et init le timer avec '#'
break;
}
if(ct==-2) emenu=0; // si la touche # est appuyée on sort du menu
if(ct==-3) data[nmenu]=0; // reset la valeur avec '*'
} else { // si on n'est pas dans un menu, "2" et "8" servent à naviguer et "#" pour entrer dans un menu
if(ct==2 && pass && nmenu < nbmenu-1) nmenu++; // monte d'un niveau de menu si le mot de passe est bon
if(ct==8 && pass && nmenu > 0) nmenu--; // descend d'un niveau de menu si le mot de passe est bon
if(ct==-2) emenu=1; // rentre dans le menu
}
if (ct!=-1) aff(); // raffaichit l'écran si une touche est appuyée
// gestion des données
if(data[1]) { // si dans le menu 1 la valeur est 1 "Sortie 13 1/0"
if (time>timer) if (digitalRead(13)) {digitalWrite(13, 0); timer=time+ptimer[0];}
else {digitalWrite(13, 1); timer=time+ptimer[1];}
}else digitalWrite(13, 0); // éteint la led verte si dans le menu 1 la valeur est 0
ct=-1; // évite le rebond du clavier doit être à la fin de loop()
}
// ****************** gestion du clavier ******************************
int clav() {
int ret=-1, a=analogRead(A0); // lecture de l’entrée analogique
if (a>50) for (int i=0; i <= 11; i++) if (a < eclav[i]+5 && a> eclav[i]-5) ret=tclav[i]; // fourchette de +/-5
return ret; // retourne -1 => pas de touche, -2 => #, -3 => * et de 0 à 9 => 0 à 9
}
// ******************* gestion de l'affichage ***************************
void aff(){
lcd.clear(); // efface l'écran
if (emenu){ // si dans un menu
if (pass) lcd.print(menu[nmenu]); else lcd.print("Code: 0-9 * #"); // pour le 1er menu on affiche "code: o-9 * # sur la premère ligne
lcd.setCursor (0,1); if (!nmenu) lcd.print(data[0]); else lcd.print(data[nmenu]); // deuxième ligne
} else { // si sélection d'un menu
lcd.print(menu[nmenu]); if(!nmenu) if (pass) lcd.print(" on"); else lcd.print(" off"); // 1er ligne affiche le nom du menu ou l'état du mot de passe
lcd.setCursor (0,1);
lcd.print("Choix 2, 8, #"); // 2eme ligne
lcd.setCursor (0,0); // place le curseur en haut de l'écran
}
}