lcd keypad menu newbiee

Hi everyone,

new to ardunio and building first project but I am having problems getting Menu system working correctly i have been using kiwix code from a example on this forum http://arduino.cc/forum/index.php/topic,44144.0.html
which works only with the up/down navigation the left/right into submenus is not working, i am using ardunio 0022 and post says to patch LiquidCrystal but i my one i dont think it matches from updates so i have left this.

I have another sketch that displays 2 temps on the lcd from ds18b20's and turns 2 relays on and off for temp control I am looking to butcher both skeches together and use menu system to changed defined values for relay's temp on/off threshold.

but i can run kiwx sketch and navigate up and down but not left right into submenus. any ideas about this code i am unsure if it because it defines a custom char and i havent modified the LiquidCrystal (unsure cant find code in it mentioned in post) any help appreciated

// ===================================================================
// Example for LCD Keypad Shield from http://www.nuelectronics.com/
// -------------------------------------------------------------------
// * Modified to use a patched LiquidCrystal library
// * Alternative routine to detect keys
// ===================================================================
#include <stdio.h>
#include <LiquidCrystal.h>
LiquidCrystal lcd(8, 9, 4, 5, 6, 7);
// ===================================================================
// hardware settings
#define rightKey 0
#define upKey 1
#define downKey 2
#define leftKey 3
#define selectKey 4
#define NUM_KEYS 5
// ===================================================================
// Program parameters
#define minOpt1 5
#define maxOpt1 999
int valueOpt1 = 15;

#define minOpt2 1
#define maxOpt2 99
int valueOpt2 = 10;

#define programMode1 0
#define programMode2 1
#define programMode3 2
int programMode = programMode1;

boolean inMainProgram = false;

int programmSequence = 0;
#define sequenceModeSelect 0
#define sequenceModeOption 1
#define sequenceModeProgram 2

// first menu line - description of menu level
char sequenceHeader[3][17] = {"Mode select ", "Option select ", "Program start "};

// second menu line - mode select
char sequenceModes[3][17] = {" Mode 1 >", "< Mode 2 >", "< Mode 3 "};
// second menu line - options settings
char sequenceOptions[3][17] = {"Option 1: ", "Option 2: ", "no options "};

void setup()
{

// initial lcd display while initialize and pc detection
lcd.clear();
lcd.print("testing menu");

programmSequence = sequenceModeSelect;
inMainProgram = false;

delay(2000);
updateScreen();
}

// ===================================================================
// main loop with new key detection
int keyEvent = -1;
int lastEvent = -1;
int countEvent = 0;

//Key message
char msgs[5][3] = {
"> ",
"^ ",
"v ",
"< ",
"* " };

void updateScreen()
{
lcd.clear();
lcd.print(sequenceHeader[programmSequence]);
lcd.setCursor(0,1);
switch(programmSequence)
{
case sequenceModeSelect:
menuModeSelect(keyEvent);
break;
case sequenceModeOption:
menuOptionSelect(keyEvent);
break;
case sequenceModeProgram:
break;
}
}

void loop()
{
int keyEvent = detectKey();
if (keyEvent >= 0)
{
switch (keyEvent)
{
case rightKey:
if (!inMainProgram)
{
if (programmSequence > sequenceModeSelect)
programmSequence--;
updateScreen();
}
break;
case leftKey:
if (!inMainProgram)
{
if (programmSequence < sequenceModeProgram)
programmSequence++;
updateScreen();
}
break;
case upKey:
case downKey:
if (!inMainProgram)
{
switch (programmSequence)
{
case sequenceModeSelect:
menuModeSelect( keyEvent );
break;
case sequenceModeOption:
menuOptionSelect( keyEvent );
break;
case sequenceModeProgram:
break;
}
}
break;
case selectKey:
lcd.setCursor(0, 1);
if (lastEvent != keyEvent)
{
lastEvent = keyEvent;
countEvent=0;
}
else
countEvent++;
lcd.print(msgs[keyEvent]);
lcd.print(countEvent);
break;
}
}
}

// ===================================================================
// Menu tools

void menuModeSelect( int keyEvent )
{
switch (keyEvent)
{
case rightKey:
if (programMode < programMode3)
programMode++;
break;
case leftKey:
if (programMode > programMode1)
programMode--;
break;
}
lcd.setCursor(0,1);
lcd.print( sequenceModes[programMode] );
}

void menuOptionSelect( int keyEvent )
{
char cbuf[4] = " ";
lcd.setCursor(0,1);
lcd.print(sequenceOptions[programMode]);
switch (keyEvent)
{
case rightKey:
switch (programMode)
{
case programMode1:
if (valueOpt1 < maxOpt1)
valueOpt1++;
break;
case programMode2:
if (valueOpt2 < maxOpt2)
valueOpt2++;
break;
}
break;
case leftKey:
switch (programMode)
{
case programMode1:
if (valueOpt1 > minOpt1)
valueOpt1--;
break;
case programMode2:
if (valueOpt2 > minOpt2)
valueOpt2--;
break;
}
break;
}
switch(programMode)
{
case programMode1:
if (valueOpt1 > minOpt1)
lcd.print("<");
else
lcd.print(" ");
sprintf(cbuf,"%3d",valueOpt1);
lcd.print(cbuf);
if (valueOpt1 < maxOpt1)
lcd.print(">");
else
lcd.print(" ");
break;
case programMode2:
if (valueOpt2 > minOpt2)
lcd.print("<");
else
lcd.print(" ");
sprintf(cbuf,"%2d",valueOpt2);
lcd.print(cbuf);
if (valueOpt2 < maxOpt2)
lcd.print(">");
else
lcd.print(" ");
break;
}
}

// ===================================================================
// Lcd tools

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

// ===================================================================
// Define a custom char in lcd
int defineCharacter(int ascii, int data) {
int baseAddress = (ascii * 8) + 64;
// baseAddress = 64 | (ascii << 3);
lcd.command(baseAddress);
for (int i = 0; i < 8; i++)
lcd.write(data
);*

  • lcd.command(128);*
  • return ascii;*
    }
    // ===================================================================
    // Convert ADC value to key number
    int adc_key_val[NUM_KEYS] ={ 30, 150, 360, 535, 760 };
    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;*

}
// ===================================================================
// new key detection routine, without delays!
int lastKeyEvent = 0;
int curKeyEvent = 0;
int keyToReturn = 0;
boolean keyToProcess = false;
int adc_key_in = 0;
int detectKey()
{

  • keyToReturn = -1;*
  • adc_key_in = analogRead(0); // read the value from the sensor *
  • curKeyEvent = get_key(adc_key_in); // convert into key press*
  • if (curKeyEvent != lastKeyEvent)*
  • {*
  • if (!keyToProcess)*
  • {*
  • lastKeyEvent = curKeyEvent;*
  • keyToProcess = true;*
  • }*
  • else*
  • {*
  • keyToReturn = lastKeyEvent;*
  • lastKeyEvent = -1;*
  • keyToProcess = false;*
  • }*
  • }*
  • return keyToReturn;*
    }
    // ===================================================================[/quote]

Did you test your detectKey() function? Does it return the key presses correctly? May something wrong with your wiring.

Hi, have tested key values via serial monitor and read values for all buttons, also changed upkey to leftkey and downkey to rightkey in sketch which is the one i pasted and left and right key is working in sketch as up and down navigation so i know its reading the a0 key value but i cannot navigate into submenus? I can just scroll up and down first menu.

Your code navigates within the menus but it completes navigation and immediately returns the main menu. Put long delays and see what happens. You should put loops in "menuOptionSelect" and "menuModeSelect" functions and get key codes.

ok got the code working, anyone outhere doing their head in with this menu code for the lcd keypad sheild all that needs to be done is to delcare lcd screen size in void(setup)

eg mine

lcd.begin(16, 2);

menu away,

ill be back more headaches to come yet :slight_smile: