Utilisation d'un LCD KeyPad en saisie et Codage de la saisie !

Portrait de brossden

Le module LCD KeyPad Schield utilisé ici se "Plug" se directement sur un Arduino

UNO Ou MEGA !

Le programme qui suit donne un exemple de comment saisir un texte avec un lcd qui comporte des boutons.

Le caractère qui est en saisie clignote ce qui permet de savoir ou se fait la saisie ou modification du texte avec en plus pour donner un caractère supplémentaire à ce programme un système de codage par décalage de trois caractères à droite du texte saisie ou, si celui ci est a décoder décodage par décalage à gauche cette fois de chaque caractère du texte saisi ! Vous pourrez remarquer que la tempo qui fait clignoter le caractère n'affecte en rien la vitesse de saisie des boutons !

Voici la démo.

Pour vos idées, vos critiques et commentaires diverses préférez les laisser dans cette Rubrique  pour ne par surcharger cette rubrique, par avance Merci !

Pour le code il est ci dessous l dans le code et dans la vidéo "EXEMPLE" est uniquement là pour gagner du temps

// Librairie
#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

//Variables
String Alpha  = " ABCDEFGHIJKLMNOPQRSTUVWXYZ";
String Action = "  Saisie Texte  ";
String Texte = "EXEMPLE         ";
String Codee ;
String Decodee ;
int Pos = 0;
int Caract = 0;
char BP = '_';
double Tempo ;
// Setup
void setup() {
  lcd.begin(16, 2);
  lcd.clear();
  lcd.print(Action);
}

//Loop
void loop() {
  BP = '_';
  while (BP == '_') {
    if (Tempo < millis()) // Ce système de Tempo n'interrompt pas le programme dans la saisie des BP
      if  (Action == "  Saisie Texte  ")
        CursorBlink(Pos); // Clignottement du carctère en saisie
    BP = QuelBoutonPresse();
    
  }

  //Caract = Alpha.indexOf(Texte[Pos]);
  switch (BP) { // Action selon le BP préssé

    case '_':
      ; // On ne fait rien
      break;

    case 'H': // BP Haut
      if (Action == "  Saisie Texte  ") {
        Caract++;
        if (Caract > 26) {
          Caract = 0;
        }
      }
      break;

    case 'B': //BP BAS
      if (Action == "  Saisie Texte  ") {
        Caract--;
        if (Caract < 0)
          Caract = 26;
      }

      break;

    case 'G':// BP GAUCHE
      if (Action == "  Saisie Texte  ") {
        Pos--;
        if (Pos < 0)
          Pos = 0;
        Caract = Alpha.indexOf(Texte[Pos]);
      }
      else {
        Decode();
        lcd.setCursor(0, 0);
        lcd.print("         Code ->");
        lcd.setCursor(0, 1);
        lcd.print(Decodee);
      }
      break;

    case 'D': //BP DROIT
      if (Action == "  Saisie Texte  ") {
        Pos++;
        if (Pos > 15)
          Pos = 15;
        Caract = Alpha.indexOf(Texte[Pos]);
      }
      else
      {
        Code();
        lcd.setCursor(0, 0);
        lcd.print("<- Decode        ");
        lcd.setCursor(0, 1);
        lcd.print(Codee);
      }
      break;

    case 'S': //BP SELECT
      lcd.setCursor(0, 0);
      if (Action == "  Saisie Texte  ")
        Action = "<-Decode Code ->";
      else
        Action = "  Saisie Texte  ";
      lcd.print(Action);
      lcd.setCursor(0, 1);
      lcd.print(Texte);
      break;

  }

  Texte[Pos] = Alpha[Caract];
  Tempo = millis();
  delay(200);
}

char QuelBoutonPresse() { // Attibution du nom du bouton préssé à BP
  int value = analogRead(A0);
  if (value < 50)
    return 'D';
  else if (value < 150)
    return 'H';
  else if (value < 350)
    return 'B';
  else if (value < 550)
    return 'G';
  else if (value < 850)
    return 'S';
  else
    return '_';

  delay(100);
  Tempo = millis() + 100; // Ce système de Tempo n'interrompt pas le programme dans la saisie des BP
}
void Code() { // Codage de Texte
  Codee = "";
  for (int C = 0; C < 16; C++) {
    int Index = Alpha.indexOf(Texte[C]);
    if (Index < 1) {
      Index = -3 ;
    }
    else if (Index > 23) {
      Index = Index - 26;
    }
    Codee = Codee + Alpha[Index + 3];
  }
}
void Decode() { // Décodage de Texte
  Decodee = "";
  for (int C = 0; C < 16; C++) {
    int Index = Alpha.indexOf(Texte[C]);

    if (Index < 1) {
      Index = 3 ;
    }
    else if (Index < 4) {
      Index = Index + 26;
    }
    Decodee = Decodee + Alpha[Index - 3];
  }
}

int CursorBlink(int C) { // Cette Fonction fait clignoté le Caractère en saisie
  lcd.setCursor(0, 1);
  lcd.print(Texte);
  static uint8_t state = 0; // état du char - static -> initialisation une seul fois lors du 1er appel de la fonction
  lcd.setCursor(C, 1);
  char CTexte = Texte[C];
  lcd.write(state ? CTexte : '_'); // on affiche le char
  state = !state; // on inverse l'état du char
  Tempo = millis() + 300;
}

N.B : J'ai corrigé un petit bug qui empêchait le bon fonctionnement de la saisie, notamment dans Alpha deux fois le 'H' , le deuxième à la place du 'K' et une ligne mal placée dans une boucle !

Dans cette version les boutons droit et gauche code ou décode le texte qui a été saisie. C'est à dire qu'avec se code lorsque on a "EXEMPLE" les boutons code ou decode le texte saisi  >> "EXEMPLE" et non le dernier Affichage.

Suite à une question le vous propose une seconde version qui elle code ou décode à l'infini le dernier texte affiché et non le dernier texte saisi.

Il suffit de créer une nouvelle variable 'Source' dans mon cas et de faire le codage décodage sur cette dernière ! Mais le fait de retourner en saisie rappel le dernier texte saisi ici : "EXEMPLE".

De plus il devient donc possible de coder ou décoder avec un décalage  de 3,6,9,12 ..  à droite ou a gauche !

Voici le Code :

// Librairie
#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

//Variables
String Alpha  = " ABCDEFGHIJKLMNOPQRSTUVWXYZ";
String Action = "  Saisie Texte  ";
String Texte = "EXEMPLE         ";
String Codee ;
String Decodee ;
String Source;
int Pos = 0;
int Caract = 0;
char BP = '_';
double Tempo ;
// Setup
void setup() {
  lcd.begin(16, 2);
  lcd.clear();
  lcd.print(Action);
}

//Loop
void loop() {
  BP = '_';
  while (BP == '_') {
    if (Tempo < millis()) // Ce système de Tempo n'interrompt pas le programme dans la saisie des BP
      if  (Action == "  Saisie Texte  ")
        CursorBlink(Pos); // Clignottement du carctère en saisie
    BP = QuelBoutonPresse();

  }

  //Caract = Alpha.indexOf(Texte[Pos]);
  switch (BP) { // Action selon le BP préssé

    case '_':
      ; // On ne fait rien
      break;

    case 'H': // BP Haut
      if (Action == "  Saisie Texte  ") {
        Caract++;
        if (Caract > 26) {
          Caract = 0;
        }
      }
      break;

    case 'B': //BP BAS
      if (Action == "  Saisie Texte  ") {
        Caract--;
        if (Caract < 0)
          Caract = 26;
      }

      break;

    case 'G':// BP GAUCHE
      if (Action == "  Saisie Texte  ") {
        Pos--;
        if (Pos < 0)
          Pos = 0;
        Caract = Alpha.indexOf(Texte[Pos]);
      }
      else {
        Decode();
        lcd.setCursor(0, 1);
        lcd.print(Decodee);
      }
      break;

    case 'D': //BP DROIT
      if (Action == "  Saisie Texte  ") {
        Pos++;
        if (Pos > 15)
          Pos = 15;
        Caract = Alpha.indexOf(Texte[Pos]);
      }
      else
      {
        Code();
        lcd.setCursor(0, 1);
        lcd.print(Codee);
      }
      break;

    case 'S': //BP SELECT
      lcd.setCursor(0, 0);
      if (Action == "  Saisie Texte  ") {
        Action = "<-Decode Code ->";
        Source = Texte;
      }
      else
        Action = "  Saisie Texte  ";
      lcd.print(Action);
      lcd.setCursor(0, 1);
      lcd.print(Texte);
      break;

  }

  Texte[Pos] = Alpha[Caract];
  Tempo = millis();
  delay(200);
}

char QuelBoutonPresse() { // Attibution du nom du bouton préssé à BP
  int value = analogRead(A0);
  if (value < 50)
    return 'D';
  else if (value < 150)
    return 'H';
  else if (value < 350)
    return 'B';
  else if (value < 550)
    return 'G';
  else if (value < 850)
    return 'S';
  else
    return '_';

  delay(100);
  Tempo = millis() + 100; // Ce système de Tempo n'interrompt pas le programme dans la saisie des BP
}
void Code() { // Codage de Texte
  Codee = "";
  for (int C = 0; C < 16; C++) {
    int Index = Alpha.indexOf(Source[C]);
    if (Index < 1) {
      Index = -3 ;
    }
    else if (Index > 23) {
      Index = Index - 26;
    }
    Codee = Codee + Alpha[Index + 3];
  }
  Source = Codee;

}
void Decode() { // Décodage de Texte
  Decodee = "";
  for (int C = 0; C < 16; C++) {
    int Index = Alpha.indexOf(Source[C]);

    if (Index < 1) {
      Index = 3 ;
    }
    else if (Index < 4) {
      Index = Index + 26;
    }
    Decodee = Decodee + Alpha[Index - 3];
  }
   Source = Decodee;
}

int CursorBlink(int C) { // Cette Fonction fait clignoté le Caractère en saisie
  lcd.setCursor(0, 1);
  lcd.print(Texte);
  static uint8_t state = 0; // état du char - static -> initialisation une seul fois lors du 1er appel de la fonction
  lcd.setCursor(C, 1);
  char CTexte = Texte[C];
  lcd.write(state ? CTexte : '_'); // on affiche le char
  state = !state; // on inverse l'état du char
  Tempo = millis() + 300;
}

Bonne journée à tous

Portrait de brossden

Après un peu de réflexion j'ai optimisé le code en gagnant 64 lignes de code :

// Librairie
#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

//Variables
String Action = "  Saisie Texte  ";
String Texte = "EXEMPLE         ";
int Pos = 0;
int Code = 3;
int Decode = -3;
int value;

void setup() {
  lcd.begin(16, 2);
  lcd.clear();
  lcd.print(Action);
  lcd.setCursor(0, 1);
  lcd.print(Texte);
  lcd.setCursor(Pos, 1);
  lcd.blink();
}

void loop() {
  value = analogRead(A0);
  if (value < 50) { // BP Droite
    if (Action == "  Saisie Texte  ") {
      Pos++;
      if (Pos > 15)
        Pos = 0;
    }
    else
    {
      Fonction(Code);
    }
    goto Fin ;
  }
  else if (value < 150) { // BP Haut
    if (Action == "  Saisie Texte  ") {
      if (Texte[Pos] == 'Z')
        Texte[Pos] = 31;
      if (Texte[Pos] == ' ')
        Texte[Pos] = 64;
      Texte[Pos] = Texte[Pos] + 1;
    }
    goto Fin;
  }
  else if (value < 350) { // BP Bas
    if (Action == "  Saisie Texte  ") {
      if (Texte[Pos] == ' ')
        Texte[Pos] = 91;
      if (Texte[Pos] == 'A')
        Texte[Pos] = 33;
      Texte[Pos] = Texte[Pos] - 1;
    }
    goto Fin;
  }
  else if (value < 550) { //BP Gauche
    if (Action == "  Saisie Texte  ") {
      Pos--;
      if (Pos < 0)
        Pos = 0;
    }
    else {
      Fonction(Decode);
    }
    goto Fin;
  }
  else if (value < 850) {//BP Selection
    lcd.setCursor(0, 0);
    if (Action == "  Saisie Texte  ")
      Action = "<-Decode Code ->";
    else {
      Action = "  Saisie Texte  ";
    }
    lcd.print(Action);
  }
Fin:
  while (value < 1000)  { // Attente que tous les boutons soient relachés
    lcd.setCursor(0, 1);
    lcd.print(Texte);
    if (Action == "  Saisie Texte  ") {
      lcd.setCursor(Pos, 1);
      lcd.blink();
    }
    value = analogRead(A0);
  }
}

void Fonction(int X) { // Codage de Texte si X =3 décodage de Texte si X = -3
  for (int C = 0; C < 16; C++) {
    if (Texte[C] != ' ') {
      if ((Texte[C] < 'X' && X == 3 ) || (Texte[C] > 'C' && X == -3 ))
        Texte[C] += X;
      else if (Texte[C] < 'D' && X == -3 )
        Texte[C] += 23;
      else if (Texte[C] > 'W' && X == +3 )
        Texte[C] -= 23;
    }
  }
}

Bonne journée à tous