Help with this LCD keypad menu code

Hi guys,

I’ve started writing a code for my reef controller but I’ve encountered a few problems with it.

I have a LCD keypad shield that has 5 buttons.

Basically, I have 2 levels in my menu. Sometimes, it happens that I have to press twice on a button so the action is taken into account.

For example, when at first level, I’ve written the code so that it need a press on Select key to go down to 2nd level. What happens in reality is that I have to press once on Select key and one more time on Select key (or even another button!) so it goes down.

Here’s my code :

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


//Variables//////////////////////////////////////////////////////////////////////////////////////////////////////////////////
char sequenceMenu[4][17] = {"    Main menu   ", " White leds menu", " Blue leds menu", " Tank temp menu"};


int adc_key_val[5] ={30, 150, 360, 535, 760 };
int NUM_KEYS = 5;
int adc_key_in;
int key=-1;
int oldkey=-1;

#define rightKey 0
#define upKey 1
#define downKey 2
#define leftKey 3
#define selectKey 4

// définition variables menu
int General = 0;
int Menu = 0;

int whiteMaxCurrent ; // Percentage
int blueMaxCurrent ; // Percentage


int whiteMax[21] = {0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100};//Pourcentage saisi
int blueMax[21] = {0,5,10,15,20,25,30,35,40,45,50,55,60,65,70,75,80,85,90,95,100};//Pourcentage saisi

int w = 14;
int b = 13;

int tank_fan_on_temp;
int tank_fan_on = 23;

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void setup() {

lcd.begin(16, 2);
  lcd.clear();
  lcd.println("Reef Controller ");
  delay(5000);
  lcd.clear();
  delay(1000);
}

//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
void loop()

{

int key = 0;
adc_key_in = analogRead(0); // read the value from the sensor
key = get_key(adc_key_in); // convert into key press
if (key != oldkey) // if keypress is detected
{
delay(50); // wait for debounce time
adc_key_in = analogRead(0); // read the value from the sensor
key = get_key(adc_key_in); // convert into key press
if (key != oldkey)
{
oldkey = key;
if (key >=0)
{

switch (General){

  
case 0: // 1st level

switch(key){
case upKey:
break;

case downKey:
break;

case rightKey:
lcd.clear();
Menu--;
if (Menu<0)
{Menu = 3;}
lcd.setCursor(0, 0);
lcd.print(sequenceMenu[Menu]);
break;

case leftKey:
lcd.clear();
Menu++;
if (Menu>3)
{Menu = 0;}
lcd.setCursor(0, 0);
lcd.print(sequenceMenu[Menu]);

break;

case selectKey:
General++;
//Choix = 0;
break;
}
break;

case 1: // 2nd level

switch(Menu) {
case 0: // 2nd level "Main"
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("26/01/10");
lcd.setCursor(10, 0);
lcd.print("H:31.1");
lcd.setCursor(0, 1);
lcd.print("19:31:19");
lcd.setCursor(10, 1);
lcd.print("T:27.1");

switch(key){

case upKey:
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(sequenceMenu[0]);


General--;
break;

case downKey:
break;

case rightKey:
break;

case leftKey:
break;

case selectKey:
break;
}
break;

case 1: // 2nd level "White leds"
lcd.setCursor(0, 1);
lcd.print("  Intensity :");
lcd.print(whiteMax[w]);

switch(key){

case upKey:
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(sequenceMenu[1]);
General--;
break;

case downKey:
break;

case rightKey:
w++;
if (w>20){w=20;}
lcd.print(" Intensity :");
lcd.print(whiteMax[w]);
break;

case leftKey:
w--;
if (w<0){w=0;}
lcd.print("  Intensity :");
lcd.print(whiteMax[w]);
break;

case selectKey:
whiteMaxCurrent = whiteMax[w];
break;

}
break;

case 2: // 2nd level "Blue led"
lcd.setCursor(0, 1);
lcd.print("  Intensity :");
lcd.print(blueMax[b]);


switch(key){

case upKey:
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(sequenceMenu[2]);
General--;
break;

case downKey:
break;

case rightKey:
b++;
if (b>20){b=20;}
lcd.print(" Intensity :");
lcd.print(blueMax[b]);
break;

case leftKey:
b--;
if (b<0){b=0;}
lcd.print("  Intensity :");
lcd.print(blueMax[b]);
break;

case selectKey:
blueMaxCurrent = blueMax[b];
break;
}
break;

case 3: // 2nd level "Tank temp"
lcd.setCursor(0, 1);
lcd.print("Fan's on at : ");
lcd.print(tank_fan_on);

switch(key){

case upKey:
lcd.clear();
lcd.setCursor(0, 0);
lcd.print(sequenceMenu[3]);
General--;
break;

case downKey:
break;

case rightKey:
tank_fan_on++;
lcd.print("Fan's on at : ");
lcd.print(tank_fan_on);
break;

case leftKey:
tank_fan_on--;
lcd.print("Fan's on at : ");
lcd.print(tank_fan_on);
break;

case selectKey:
tank_fan_on_temp = tank_fan_on;
break;
}
break;

}
}
}
}
}
}



// Convert ADC value to key number
int get_key(unsigned int input)
{
int k;

for (k = 0; k < NUM_KEYS; k++)
{
if (input < adc_key_val[k])
{

return k;
}
}

if (k >= NUM_KEYS)
k = -1; // No valid key pressed

return k;
}
// ===================================================================
// Lcd tools

void clearLine(int line)
{
lcd.setCursor(0,line);
lcd.print("                ");
lcd.setCursor(0,line);
}

Thanks in advance for your help ! :wink:

Why are you using connecting either/or devices (the switch is either pressed or it isn't) to an analog pin?

Analog pins are for things that result in a voltage between 0 and 5V (typically).

Or, are you actually connecting the switches to digital pins, and using the wrong function to read the digital pins?

key = get_key(adc_key_in); // convert into key press
if (key != oldkey) // if keypress is detected

When using analogue values, it is quite possibly from one read to the next not to get exactly the same value, due to the effects of noise.