Program problem with the LCD Keypad Shield

Hello, I am working on a group project in electrical engineering, and I am doing a test program to help me in my work.

I am using an Arduino AtMega2560 board which is connected with a 16x2 I2C LCD display and an LCD Keypad Shield with 6 RIGHT, LEFT, UP, DOWN, SELECT and RESET buttons.

My goal is to create a program where I have to gradually display the letters of the word "DROITE" (right in French), where:

  • we use the variable "LETTRE" which has for initial value 0

  • when the RIGHT button is pressed for the first time, only the first letter "D" is displayed

  • by pressing the LEFT button, the value of the variable "lettre" is increased by 1, and by pressing the RIGHT button, this additionally displays the following letter.

And so on as the value of the "LETTRE" variable is increased until the complete word is formed.

Here is my code:

// LCD Keypad Shield

#include <LiquidCrystal.h>

// Création de l'objet lcd (avec les différents ports numériques qu'il utilise)
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

// Variables
int lcd_key     = 0;
int adc_key_in  = 0;
char lettre = 0;

// Constantes
#define btnRIGHT  0
#define btnUP     1
#define btnDOWN   2
#define btnLEFT   3
#define btnSELECT 4
#define btnNONE   5

void setup()
{
   
  lcd.begin(16, 2);              // Démarrage de l'écran
  lcd.setCursor(0, 0);           // Positionnement du curseur au début
  lcd.print("Arduino:essentiel"); // Message
}

void loop()
{
  lcd.setCursor(0, 1);           // Positionnement du curseur début de ligne 1
  lcd_key = read_LCD_buttons();  // Lecture des touches

  if (lettre == 0) {
    
    switch (lcd_key)               // Action en cas de touche pressée
    {
      case btnRIGHT:
        {
          lcd.print("D");//affiche la lettre D
          break;
        }
    }
  }

  if (lettre == 1) {

    switch (lcd_key)               // Action en cas de touche pressée
    {
      case btnRIGHT:
        {
          //lcd.setCursor(1, 1); // Positionnement du curseur à la colonne suivante
          lcd.print("DR");//affiche la lettre R
          break;
        }
    }
  }

  if (lettre == 2) {
       
    switch (lcd_key)               // Action en cas de touche pressée
    {
      case btnRIGHT:
        {
          //lcd.setCursor(2, 1); // Positionnement du curseur à la colonne suivante
          lcd.print("DRO");//affiche la lettre O
          break;
        }
    }
  }

  if (lettre == 3) {

    switch (lcd_key)               // Action en cas de touche pressée
    {
      case btnRIGHT:
        {
          //lcd.setCursor(3, 1); // Positionnement du curseur à la colonne suivante
          lcd.print("DROI");//affiche la lettre I
          break;
        }
    }
  }

  if (lettre == 4) {
       
    switch (lcd_key)               // Action en cas de touche pressée
    {
      case btnRIGHT:
        {
          //lcd.setCursor(4, 1); // Positionnement du curseur à la colonne suivante
          lcd.print("DROIT");//affiche la lettre T
          break;
        }
    }
  }

  if (lettre == 5) {

    switch (lcd_key)               // Action en cas de touche pressée
    {
      case btnRIGHT:
        {
          //lcd.setCursor(5, 1); // Positionnement du curseur à la colonne suivante
          lcd.print("DROITE");//affiche la lettre E
          break;
        }
    }
  }

 switch (lcd_key)               // Action en cas de touche pressée
   {
     case btnLEFT:
      {
       lettre++; //incrémente de 1 la valeur de lettre
       delay(100); //delai en millisecondes
       break;
      }
   }
}






// Fonction de lecture des touches
int read_LCD_buttons()
{
  adc_key_in = analogRead(0);   // Lecture du port analogique

  // Les valeurs qui suivent doivent être adaptées au shield
  if (adc_key_in > 1000) return btnNONE;   // En principe 1023 quand aucune touche n'est pressée
  if (adc_key_in < 50)   return btnRIGHT;     // 0
  if (adc_key_in < 195)  return btnUP;        // 99
  if (adc_key_in < 380)  return btnDOWN;      // 255
  if (adc_key_in < 555)  return btnLEFT;      // 409
  if (adc_key_in < 790)  return btnSELECT;    // 640

  return btnNONE;
}

However, I have a problem after compiling my code.

When I press the RIGHT button, the first letter "D" shows up as expected, but after pressing the LEFT button and pressing the RIGHT button again, the screen shows 2 more letters instead of one !

Also, after pressing the LEFT and RIGHT buttons again, it will display either 2 letters or 3 letters.

I have the impression that my program is displaying the letters randomly.

Could someone help me fix the problem please?

thank you in advance

I suspect what is happening is that you are holding down the button for more than 100ms and it is registering it two or three times thus causing lettre to increment multiple times.

You could solve this by modifying your code to detect that the button has changed from not pressed to pressed rather than just checking that the button is pressed. In other words, don't try to read another button until you detect that no button is pressed.

You can also simplify your code a lot by using the fact you know how many letters have already been printed

// LCD Keypad Shield

#include <LiquidCrystal.h>

// Création de l'objet lcd (avec les différents ports numériques qu'il utilise)
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

// Constantes
#define btnRIGHT  0
#define btnUP     1
#define btnDOWN   2
#define btnLEFT   3
#define btnSELECT 4
#define btnNONE   5

char message[] = "DROITE";
const int messageLen = sizeof(message) / sizeof(message[0]);
char lettre = 1;

void setup()
{
  lcd.begin(16, 2);              // Démarrage de l'écran
  lcd.setCursor(0, 0);           // Positionnement du curseur au début
  lcd.print("Arduino: essentiel"); // Message
}

void loop()
{
  bool wait = false;
  lcd.setCursor(0, 1);           // Positionnement du curseur début de ligne 1
  int lcd_key = read_LCD_buttons();  // Lecture des touches

  switch ( lcd_key ) {

    case btnRIGHT:
      for ( int i = 0; i < lettre; ++i ) {
        lcd.print(message[i]);
      }
      wait = true;
      break;

    case btnLEFT:
      lettre++; //incrémente de 1 la valeur de lettre
      if ( lettre == messageLen ) lettre--;
      wait = true;
      break;
  }
  if ( wait == true ) {
    while ( read_LCD_buttons() != btnNONE ) {
      delay(10); //delai en millisecondes
    }
  }
}

// Fonction de lecture des touches
int read_LCD_buttons()
{
  int adc_key_in = analogRead(0);   // Lecture du port analogique

  // Les valeurs qui suivent doivent être adaptées au shield
  if (adc_key_in > 1000) return btnNONE;   // En principe 1023 quand aucune touche n'est pressée
  if (adc_key_in < 50)   return btnRIGHT;     // 0
  if (adc_key_in < 195)  return btnUP;        // 99
  if (adc_key_in < 380)  return btnDOWN;      // 255
  if (adc_key_in < 555)  return btnLEFT;      // 409
  if (adc_key_in < 790)  return btnSELECT;    // 640

  return btnNONE;
}

I tried to run the program you proposed me and it works !

Thank you a lot, blh64 ! It will be really useful for my project !

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.