LCD Keypad Shield program buttons problem

Hello, I am working on a group project in electrical engineering, and I made a program as part of my group project

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, and also a TCS3200 Programmable
Color Light-to-Frequency Converter.

My goal is to make a program that detects 3 colors in a certain order and moves on to the next when the detected color is true. Indeed, 1 corresponds to the color BLACK, 2 to the RED, 3 to the GREEN and 4 to the BLUE.

// LCD Keypad Shield

#include <LiquidCrystal.h> //Cette bibliothèque permet à une carte Arduino de contrôler les écrans LiquidCrystal (LCD)

// 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;

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

//Capteur couleur
#define S0 19
#define S1 18
#define S2 17
#define S3 16
#define sensorOut 15
int frequency = 0; //valeur de fréquence des couleurs
int ValeurR = 0; //valeur de la longueur d'onde de la couleur ROUGE
int ValeurG = 0; //valeur de la longueur d'onde de la couleur VERT
int ValeurB = 0; //valeur de la longueur d'onde de la couleur BLEU
char* message[] = {"T1:", "V ", "F ", "T2:", "V ", "F ", "T3:", "V ", "F ", "-"}; //Affiche les différents charactères
char Etat_cle = 0; //la clé est dans l'état REPOS
char tour = 0; // numéro de l'étape de détection des couleurs
char couleur_detectee = 0; //valeur de la couleur détectée
char place1 = 2; //assigne la première couleur à détecter
char place2 = 4; //assigne la deuxième couleur à détecter
char place3 = 3; //assigne la troisième couleur à détecter



void setup() {
  pinMode(S0, OUTPUT);  //Relie les broches des entrées du capteur couleur aux pins de la carte Arduino
  pinMode(S1, OUTPUT);
  pinMode(S2, OUTPUT);
  pinMode(S3, OUTPUT);
  pinMode(sensorOut, INPUT);

  // Réglage de la mise à l'échelle de fréquence à 20%
  digitalWrite(S0, HIGH);
  digitalWrite(S1, LOW);

  Serial.begin(9600); //Fixe le débit de communication en nombre de caractères par seconde (l'unité est le baud) pour la communication série

  lcd.begin(16, 2);              // Démarrage de l'écran
  lcd.setCursor(0, 0);           // Positionnement du curseur au début
  lcd.print("Placer les tubes"); // Message
}

void loop() {
  // Réglage des photodiodes rouges filtrées à lire
  digitalWrite(S2, LOW);
  digitalWrite(S3, LOW);
  // Lecture de la fréquence de sortie
  frequency = pulseIn(sensorOut, LOW);
  //Remappage de la valeur de la fréquence au modèle RVB de 0 à 255
  ValeurR = map(frequency, 25, 72, 255, 0);
  // Impression de la valeur sur le moniteur série
  Serial.print("R= ");//nom d'impression
  Serial.print(ValeurR);//impression de la fréquence de couleur ROUGE
  Serial.print("  "); //ajout d'un espace
  delay(100); //delai en millisecondes

  // Réglage des photodiodes vertes filtrées à lire
  digitalWrite(S2, HIGH);
  digitalWrite(S3, HIGH);
  // Lecture de la fréquence de sortie
  frequency = pulseIn(sensorOut, LOW);
  //Remappage de la valeur de la fréquence au modèle RVB de 0 à 255
  ValeurG = map(frequency, 30, 90, 255, 0);
  // Impression de la valeur sur le moniteur série
  Serial.print("G= ");//nom d'impression
  Serial.print(ValeurG);//impression de la fréquence de couleur VERT
  Serial.print("  "); //ajout d'un espace
  delay(100); //delai en millisecondes

  // Réglage des photodiodes bleues filtrées à lire
  digitalWrite(S2, LOW);
  digitalWrite(S3, HIGH);
  // Lecture de la fréquence de sortie
  frequency = pulseIn(sensorOut, LOW);
  //Remappage de la valeur de la fréquence au modèle RVB de 0 à 255
  ValeurB = map(frequency, 25, 70, 255, 0);
  // Impression de la valeur sur le moniteur série
  Serial.print("B= ");//nom d'impression
  Serial.print(ValeurB);//impression de la fréquence de couleur BLEU
  delay(100); //delai en millisecondes

  //on ajoute pas d'espace afin de revenir à la ligne une fois la valeur B détectée

  if (ValeurR <= 0 && ValeurG <= 0 && ValeurB <= 0)
  {
    Serial.print("NOIR ");//affiche NOIR sur le moniteur série
    couleur_detectee = 1;//assigne la couleur NOIR au numéro 1
    delay(100); //delai en millisecondes
  }
  else if (ValeurR > ValeurG && ValeurR > ValeurB)
  {
    Serial.print("ROUGE ");//affiche ROUGE sur le moniteur série
    couleur_detectee = 2;//assigne la couleur ROUGE au numéro 2
    delay(100); //delai en millisecondes
  }
  else if (ValeurG > ValeurR && ValeurG > ValeurB)
  {
    Serial.print("VERT ");//affiche VERT sur le moniteur série
    couleur_detectee = 3;//assigne la couleur VERT au numéro 3
    delay(100); //delai en millisecondes
  }
  else if (ValeurB > ValeurR && ValeurB > ValeurG)
  {
    Serial.print("BLEU ");//affiche BLEU sur le moniteur série
    couleur_detectee = 4;//assigne la couleur BLEU au numéro 4
    delay(100); //delai en millisecondes
  }
  
  bool wait = false;  //variable boléenne pour attendre la pression d'un bouton
  lcd.setCursor(0, 1);           // Positionnement du curseur début de ligne 1
  lcd_key = read_LCD_buttons();  // Lecture des touches

  
  switch ( lcd_key ) { //action en cas de bouton appuyé

    case btnRIGHT:  //pression du bouton gauche
      if ( tour == 0 ) //durant le tour 0 initial
      { 
        Etat_cle++; //la clé passe dans l'état AMORCE
        lcd.print(message[0]); //affiche "T1: "
        tour++;//passe au prochain tour
      }
      else if (tour == 1 ) //durant le tour 1
      {
        lcd.setCursor(3, 1); //déplace le curseur
        if (couleur_detectee == place1) 
        {
          lcd.print(message[1]); //affiche "V"
          delay (1000);  //Délai d'une seconde
          tour++; //passe au prochain tour
          lcd.setCursor(5, 1); //déplace le curseur
          lcd.print(message[3]); //affiche "T2: "
        }
        else 
        {
          lcd.print(message[2]); //affiche "F"
          delay (1000);  //Délai d'une seconde
        }
      }
      else if (tour == 2 ) //durant le tour 2
      {
        lcd.setCursor(8, 1); //déplace le curseur
        if (couleur_detectee == place2) 
        {
          lcd.print(message[4]); //affiche "V"
          delay (1000);  //Délai d'une seconde
          tour++; //passe au prochain tour
          lcd.setCursor(10, 1); //déplace le curseur
          lcd.print(message[6]); //affiche "T3: "
        }
        else 
        {
          lcd.print(message[5]);  //affiche "F"
          delay (1000);  //Délai d'une seconde
        }
      }
      else if (tour == 3 ) //durant le tour 3
      {
        lcd.setCursor(13, 1); //déplace le curseur
        if (couleur_detectee == place3) 
        {
          lcd.print(message[7]); //affiche "V"
          delay (1000); //Délai d'une seconde
          Etat_cle++;  //La clé passe dans l'état DESAMORCE
        }
        else
        {
          lcd.print(message[8]); //affiche "F"
          delay (1000);  //Délai d'une seconde
        }
      }
      wait = true;// on attend que le bouton soit appuyé
      break;
  }
  if ( wait == true ) {
    while ( read_LCD_buttons() != btnNONE )
    { //tant qu'un bouton est appuyé
      delay(10); //delai en millisecondes
    }
  }
  
}

// 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;
}

It is then sufficient to press the RIGHT button to confirm the detected color, and you can rewrite the program to choose the colors to be detected.

The program works, but the problem is that the RIGHT button has difficulty performing the ordered action and I often have to press it several times.

Could someone help me to fix this button problem?

thank you in advance

When I used a shield like that, I first determined the min. and max. values for buttons so I could finetune.
Maybe

  if (adc_key_in < 50)   return btnRIGHT;     // 0

works better with

  if (adc_key_in < 70)   return btnRIGHT;     // 0

The value of 70 is just an example; experimenbt with it.

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