Pilotage relais suivant code clavier

Bonsoir bonsoir,

J'avais dans l'espoir de faire un petit bout de code pour piloter des relais suivant le "code" saisie sur le clavier matriciel mais cependant je bloque assez vite sur un soucis de boucle un peu folle ^^ (ou d'initialisation, à cette heure je suis un peu dans le brouillard)

Je poste donc mon code (inspiré d'un sketch de code PIN que j'ai recup sur la toile il a un moment) en espérant que quelqu’un pourra me sauver la mise :slight_smile:

#include <LiquidCrystal.h> // Inclusion de la librairie pour afficheur LCD 
#include <Keypad.h> // inclusion de la librairie pour clavier matriciel 
// --- constantes des broches ---

const int L4=35; //declaration constante de broche 
const int L3=37; //declaration constante de broche 
const int L2=39; //declaration constante de broche 
const int L1=41; //declaration constante de broche

const int C4=43; //declaration constante de broche 
const int C3=45; //declaration constante de broche 
const int C2=47; //declaration constante de broche 
const int C1=49; //declaration constante de broche



//--- Const pour Afficheur LCD 16x2 ----
const int RS=32;
const int E=30;

const int D4=28;
const int D5=26;
const int D6=24;
const int D7=22;


//--- Constantes utilisées avec le clavier 4x4
const byte LIGNES = 4; // 4 lignes
const byte COLONNES = 4; //4 colonnes

char touches[LIGNES][COLONNES] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}};
  
// tableaux de lignes et colonnes
byte BrochesLignes[LIGNES] = {L1, L2, L3, L4}; //connexions utilisées pour les broches de lignes du clavier
byte BrochesColonnes[COLONNES] = {C1, C2, C3, C4}; //connexions utilisées pour les broches de colonnes du clavier

char touche; // variable de stockage valeur touche appuyée

Keypad clavier = Keypad( makeKeymap(touches), BrochesLignes, BrochesColonnes, LIGNES, COLONNES );
LiquidCrystal lcd(RS, E, D4, D5, D6, D7);// Création d'un objet LiquidCrystal = initialisation LCD en mode 4 bits 


char attempt[6]={0,0,0,0,0,0}; // used for comparison
int z=0;
int w=0;

char INTER1ON[6]={'A','B','C','D','1','1'}; 
char INTER1OFF[6]={'A','B','C','D','1','0'};
char INTER2ON[6]={'A','B','C','D','2','1'};
char INTER2OFF[6]={'A','B','C','D','2','0'};

int INTER1ONvalue=0; 
int INTER1OFFvalue=0;
int INTER2ONvalue=0;
int INTER2OFFvalue=0;

void setup()
{
lcd.begin(16,2); // Initialise le LCD avec 20 colonnes x 4 lignes 
Serial.begin(115200);
delay(10); // pause rapide pour laisser temps initialisation

// Test du LCD

lcd.print("LCD OK") ; // affiche la chaîne texte - message de test
delay(2000); // pause de 2 secondes

lcd.clear(); // // efface écran et met le curseur en haut à gauche
delay(1000); // pour laisser temps effacer écran
lcd.print("  Entrer Code...");
}
void initialisation(){

int INTER1ONvalue=0; 
int INTER1OFFvalue=0;
int INTER2ONvalue=0;
int INTER2OFFvalue=0;
}

void checkCODE()
{
  for (int q=0; q<6; q++)
  {
    if (attempt[q]==INTER1ON[q]){
      INTER1ONvalue++;
    }
    if (attempt[q]==INTER1OFF[q]){
      INTER1OFFvalue++;
    }
    if (attempt[q]==INTER2ON[q]){
      INTER2ONvalue++;
    }
    if (attempt[q]==INTER2OFF[q]){
      INTER2OFFvalue++;
    }
  }
  if (INTER1ONvalue==6){
    Serial.println("INTER1ON_value");
  }
  if(INTER1OFFvalue==6){
    Serial.println("INTER1OFF_value");
  }
  if(INTER2ONvalue==6){
    Serial.println("INTER2ON_value");
  }
  if(INTER2OFFvalue==6){
    Serial.println("INTER2OFF_value");
  }
  for (int w=0; w<6; w++){
    attempt[w]=0;
  }
  
 Serial.println(INTER1ONvalue);
 Serial.println(INTER1OFFvalue);
 Serial.println(INTER2ONvalue);
 Serial.println(INTER2OFFvalue);
 Serial.println("Suivant OK");
   initialisation();
}
void readKeypad()
{
  char touche = clavier.getKey();
  if (touche != NO_KEY)
  {
    if(touche=='*'){
      z=0;
    }
    else if(touche=='#'){
      delay(100); // for extra debounce
      lcd.clear();
      checkCODE();
    }
    else{
      attempt[z]=touche;
      z++;
    }//fin else
  }// fin if
}// fin void

void loop()
{
  readKeypad();
}

Je vous glisse aussi ce que je recup sur le port série pour le debug

INTER2OFF_value
4
5
5
6
Suivant OK
INTER2OFF_value
17218
12868
49
6
Suivant OK

On remarque que pour le premier il n'y a aucun soucis mais qu'ensuite tout devient un peu étrange ^^
Si quelqu'un a une piste je suis preneur,

Bonne nuit a tous

Amicalement,
Trigger

Je peux pas trop t'aider désolé, mais moi j'ai utilisé un programme lui ressemblant sur mon-club-elec et il fonctionne très bien :wink:

Salut,

Merci pour ta réponse mais le soucis avec le code du club elec c'est que je ne pourrai pas commander plus de 14 relais
( clavier 16 auquel on enlève # et * )

Si quelqu'un a une autre proposition je suis tout ouïe :slight_smile:
Amicalement,
Trigger

salut, c'est dans cette partie là du code que çà fonctionne pas :

void initialisation(){

int INTER1ONvalue=0; 
int INTER1OFFvalue=0;
int INTER2ONvalue=0;
int INTER2OFFvalue=0;
}

Ce sont des variables locales à la fonction ! donc invisibles de l'exterieur.

ce qu'il faut c'est juste virer les int comme cela :

void initialisation(){

INTER1ONvalue=0; 
INTER1OFFvalue=0;
INTER2ONvalue=0;
INTER2OFFvalue=0;
}

Ca remetra les variables globales (car définies à l'exterieur) à 0 !

Bonjour et merci de ta réponse, j'ai bien appliqué les changements que tu m'as suggérés mais j'obtiens un résultat un peu étrange.
Mes variables ne bougent plus :s

INTER1OFF_value
0
0
0
0
Suivant OK
0
0
0
0
Suivant OK

Continuons :

Eneleve le mot char dans :

char touche = clavier.getKey();

Pour que ca devienne :

touche = clavier.getKey();

En effet char touche est déjà défini en global, pas besoin de le définir alors en local.

On avance...

Sinon que se passe t il si tu tappes plus de 6 touches (disons 10) avant de presser sur '#' ?

Je te laisse y reflechir.

Merci pour tes conseils :slight_smile:

Je gratte ce code depuis deux jours ^^ En enlevant le char cela semble ne pas changer le déroulement du code cependant j'obtiens des valeurs étranges au niveau du comptage :

INTER1OFF_value
5
6
4
5
Suivant OK
0
0
17475
12338
Suivant OK

Ces chiffres ne semblent correspondre à rien (ni en ASCII, ni autre codage)

Je commence à sécher un peu ...

je repost mon code en entier avec les différentes modifications apportées

#include <LiquidCrystal.h> // Inclusion de la librairie pour afficheur LCD 
#include <Keypad.h> // inclusion de la librairie pour clavier matriciel 
// --- constantes des broches ---

const int L4=35; //declaration constante de broche 
const int L3=37; //declaration constante de broche 
const int L2=39; //declaration constante de broche 
const int L1=41; //declaration constante de broche

const int C4=43; //declaration constante de broche 
const int C3=45; //declaration constante de broche 
const int C2=47; //declaration constante de broche 
const int C1=49; //declaration constante de broche



//--- Const pour Afficheur LCD 16x2 ----
const int RS=32;
const int E=30;

const int D4=28;
const int D5=26;
const int D6=24;
const int D7=22;


//--- Constantes utilisées avec le clavier 4x4
const byte LIGNES = 4; // 4 lignes
const byte COLONNES = 4; //4 colonnes

char touches[LIGNES][COLONNES] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}};
  
// tableaux de lignes et colonnes
byte BrochesLignes[LIGNES] = {L1, L2, L3, L4}; //connexions utilisées pour les broches de lignes du clavier
byte BrochesColonnes[COLONNES] = {C1, C2, C3, C4}; //connexions utilisées pour les broches de colonnes du clavier

char touche; // variable de stockage valeur touche appuyée

Keypad clavier = Keypad( makeKeymap(touches), BrochesLignes, BrochesColonnes, LIGNES, COLONNES );
LiquidCrystal lcd(RS, E, D4, D5, D6, D7);// Création d'un objet LiquidCrystal = initialisation LCD en mode 4 bits 


char attempt[6]={0,0,0,0,0,0}; // used for comparison
int z=0;

char INTER1ON[6]={'A','B','C','D','1','1'}; 
char INTER1OFF[6]={'A','B','C','D','1','0'};
char INTER2ON[6]={'A','B','C','D','2','1'};
char INTER2OFF[6]={'A','B','C','D','2','0'};

int INTER1ONvalue; 
int INTER1OFFvalue;
int INTER2ONvalue;
int INTER2OFFvalue;

void setup()
{
lcd.begin(16,2); // Initialise le LCD avec 20 colonnes x 4 lignes 
Serial.begin(115200);
delay(10); // pause rapide pour laisser temps initialisation

// Test du LCD

lcd.print("LCD OK") ; // affiche la chaîne texte - message de test
delay(2000); // pause de 2 secondes

lcd.clear(); // // efface écran et met le curseur en haut à gauche
delay(1000); // pour laisser temps effacer écran
lcd.print("  Entrer Code...");
}

void initialisation(){
INTER1ONvalue=0; 
INTER1OFFvalue=0;
INTER2ONvalue=0;
INTER2OFFvalue=0;
}

void checkCODE()
{

  for (int q=0; q<6; q++)
  {
    if (attempt[q]==INTER1ON[q]){
      INTER1ONvalue++;
    }
    if (attempt[q]==INTER1OFF[q]){
      INTER1OFFvalue++;
    }
    if (attempt[q]==INTER2ON[q]){
      INTER2ONvalue++;
    }
    if (attempt[q]==INTER2OFF[q]){
      INTER2OFFvalue++;
    }
  }
  if (INTER1ONvalue==6){
    Serial.println("INTER1ON_value");
  }
  if(INTER1OFFvalue==6){
    Serial.println("INTER1OFF_value");
  }
  if(INTER2ONvalue==6){
    Serial.println("INTER2ON_value");
  }
  if(INTER2OFFvalue==6){
    Serial.println("INTER2OFF_value");
  }
  for (int w=0; w<6; w++){
    attempt[w]=0;

  }

 Serial.println(INTER1ONvalue); // pour debug
 Serial.println(INTER1OFFvalue);
 Serial.println(INTER2ONvalue);
 Serial.println(INTER2OFFvalue);
 Serial.println("Suivant OK");
 initialisation();
 Serial.println(INTER1ONvalue); // vérifie si l'initialisation fonctionne
 Serial.println(INTER1OFFvalue);
 Serial.println(INTER2ONvalue);
 Serial.println(INTER2OFFvalue);
}
void readKeypad()
{
  touche = clavier.getKey();
  if (touche != NO_KEY)
  {
    if(touche=='*'){
      z=0;
    }
    else if(touche=='#'){
      delay(100); // for extra debounce
      lcd.clear();
      checkCODE();
    }
    else{
      attempt[z]=touche;
      z++;
    }//fin else
  }// fin if

}// fin void

void loop()
{
  readKeypad();
}

Pour de ce qui est du dépassement des 6 touches normalement le code ne prend que les 6 dernières ... je dis bien normalement ...

Amicalement,
Trigger

"Pour de ce qui est du dépassement des 6 touches normalement le code ne prend que les 6 dernières ... je dis bien normalement ..."

Ben non justement...

ton tableau attempt est defini par une taille de 6.

Si tu appuies 10 fois sur une touche le code va donner :

attempt[10]=touche

Dans ce cas tu débordes tu tableau et CA c'est PAS DU TOUT BIEN, en tout cas en langage C.

il faut que tu fasse un test sur la valeur de z du genre :

Si z==6
affiche 'oups trop de touches appuyées, remise à zéro'
z=0
for (int i=0; i++; i<6) attempt*=0;*
Fin si
Un debordement de tableau ou de memoie peut avoir des conséquences impreviibles et planter le prgramme voir reseter l'arduino.
Il faut toujours controler les effets de bords.
Tu avances, tu va trouver !

Je te donne un coup de pouce afin de t'aider.

Affiche la valeur de z chaque fois que t'appuie sur une touche, tu devrais découvrir des choses bizarres à mon sens.

Dis moi ce que trouves.

Ok je me lance :slight_smile:

En tous cas grand merci pour ton aide dans cette chasse à la boulette :wink:

@Grag38 : Tu es un chef !

voila le nouveau code :

#include <LiquidCrystal.h> // Inclusion de la librairie pour afficheur LCD 
#include <Keypad.h> // inclusion de la librairie pour clavier matriciel 
// --- constantes des broches ---

const int L4=35; //declaration constante de broche 
const int L3=37; //declaration constante de broche 
const int L2=39; //declaration constante de broche 
const int L1=41; //declaration constante de broche

const int C4=43; //declaration constante de broche 
const int C3=45; //declaration constante de broche 
const int C2=47; //declaration constante de broche 
const int C1=49; //declaration constante de broche



//--- Const pour Afficheur LCD 16x2 ----
const int RS=32;
const int E=30;

const int D4=28;
const int D5=26;
const int D6=24;
const int D7=22;


//--- Constantes utilisées avec le clavier 4x4
const byte LIGNES = 4; // 4 lignes
const byte COLONNES = 4; //4 colonnes

char touches[LIGNES][COLONNES] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}};
  
// tableaux de lignes et colonnes
byte BrochesLignes[LIGNES] = {L1, L2, L3, L4}; //connexions utilisées pour les broches de lignes du clavier
byte BrochesColonnes[COLONNES] = {C1, C2, C3, C4}; //connexions utilisées pour les broches de colonnes du clavier

char touche; // variable de stockage valeur touche appuyée

Keypad clavier = Keypad( makeKeymap(touches), BrochesLignes, BrochesColonnes, LIGNES, COLONNES );
LiquidCrystal lcd(RS, E, D4, D5, D6, D7);// Création d'un objet LiquidCrystal = initialisation LCD en mode 4 bits 


char attempt[6]={0,0,0,0,0,0}; // used for comparison
int z=0;

char INTER1ON[6]={'A','B','C','D','1','1'}; 
char INTER1OFF[6]={'A','B','C','D','1','0'};
char INTER2ON[6]={'A','B','C','D','2','1'};
char INTER2OFF[6]={'A','B','C','D','2','0'};

int INTER1ONvalue; 
int INTER1OFFvalue;
int INTER2ONvalue;
int INTER2OFFvalue;

void setup()
{
lcd.begin(16,2); // Initialise le LCD avec 20 colonnes x 4 lignes 
Serial.begin(115200);
delay(10); // pause rapide pour laisser temps initialisation

// Test du LCD

lcd.print("LCD OK") ; // affiche la chaîne texte - message de test
delay(2000); // pause de 2 secondes

lcd.clear(); // // efface écran et met le curseur en haut à gauche
delay(1000); // pour laisser temps effacer écran
lcd.print("  Entrer Code...");
}

void initialisation(){
INTER1ONvalue=0; 
INTER1OFFvalue=0;
INTER2ONvalue=0;
INTER2OFFvalue=0;
}

void checkCODE()
{

  for (int q=0; q<6; q++)
  {
    if (attempt[q]==INTER1ON[q]){
      INTER1ONvalue++;
    }
    if (attempt[q]==INTER1OFF[q]){
      INTER1OFFvalue++;
    }
    if (attempt[q]==INTER2ON[q]){
      INTER2ONvalue++;
    }
    if (attempt[q]==INTER2OFF[q]){
      INTER2OFFvalue++;
    }
  }
  if (INTER1ONvalue==6){
    Serial.println("INTER1ON_value");
  }
  if(INTER1OFFvalue==6){
    Serial.println("INTER1OFF_value");
  }
  if(INTER2ONvalue==6){
    Serial.println("INTER2ON_value");
  }
  if(INTER2OFFvalue==6){
    Serial.println("INTER2OFF_value");
  }
  for (int w=0; w<6; w++){
    attempt[w]=0;

  }

 Serial.println(INTER1ONvalue); // pour debug
 Serial.println(INTER1OFFvalue);
 Serial.println(INTER2ONvalue);
 Serial.println(INTER2OFFvalue);
 Serial.println("Suivant OK");
 initialisation();
 Serial.println(INTER1ONvalue); // vérifie si l'initialisation fonctionne
 Serial.println(INTER1OFFvalue);
 Serial.println(INTER2ONvalue);
 Serial.println(INTER2OFFvalue);
}
void readKeypad()
{
  touche = clavier.getKey();
  if (touche != NO_KEY)
  {
    if(touche=='*'){
      z=0;
    }
    else if(touche=='#'){
      delay(100); // for extra debounce
      lcd.clear();
      checkCODE();
    }
    else{
      Serial.print("touche z = ");
      Serial.println(z);
     if(z<=6){ 
      attempt[z]=touche;
      z++;
     }  
     if(z==6){
      Serial.println("oups trop de touches appuyees, remise à zero");
      z=0;
      for (int i=0; i++; i<6) attempt[i]=0;
     }
    }//fin else
  }// fin if

}// fin void

void loop()
{
  readKeypad();
}

et voila le résultat :

touche z = 0
touche z = 1
touche z = 2
touche z = 3
touche z = 4
touche z = 5
oups trop de touches appuyees, remise à zero
INTER1OFF_value
5
6
4
5
Suivant OK
0
0
0
0
touche z = 0
touche z = 1
touche z = 2
touche z = 3
touche z = 4
touche z = 5
oups trop de touches appuyees, remise à zero
INTER1ON_value
6
5
5
4
Suivant OK
0
0
0
0

On remarque maintenant grâce à Grag38 il n'y a plus de débordement tableau :slight_smile:

Je ne gratte pas plus le code aujourd'hui car sinon le repas de ce soir ne sera jamais prêt ^^

Encore merci et passe de bonnes fetes :wink:

Amicalement,
Trigger

Bravo tu as presque trouvé je pense...

En fait il faut débouncer toutes les touches appuyées et pas seulement le '#'.

Le Serial.print('oupssss'); joue un peu le role de debounceur car cela prend du temps pour afficher le texte.

Tu devrait inserer un delay dès que tu as lu une touche, genre apres : if (touche != NO_KEY) { delay(100); .....

Sinon une toute petite erreur encore :

if(z<=6){ 
      attempt[z]=touche;
      z++;
     }

doit être transformé en :

if(z<6){ 
      attempt[z]=touche;
      z++;
     }

car attempt[6] n'existe pas ! car l'indice du tableau commence à 0

Bonnes fêtes à toi et au forum.

Rendez vous probable en 2012 !