User Tools

Site Tools


LCD Menu

I found this model described by Collin80 on arduino forum.
Original thread: LCD menu with three buttons

The first challenge we face is storing of Strings from menu. If we store into RAM we can get out of memory very soon. Much more better solution is storing them into flash memory.

Storing Strings into flash memory can be done this way (citation from original thread):

//Flash based string table. Necessary because otherwise the strings will take up all of our ram.
//Use either PrintLCDAt_P or PrintLCD_P to print these strings to the LCD.
prog_char string_0[] PROGMEM =   "  1. ENROLL USER    ";  //0
prog_char string_1[] PROGMEM =   "  2. EDIT USERS     ";  //1
prog_char string_2[] PROGMEM =   "  3. DELETE USERS   ";  //2
prog_char string_3[] PROGMEM =   "  4. DEL ALL USERS  ";  //3
prog_char string_4[] PROGMEM =   "  5. LIST USERS     ";  //4
prog_char string_5[] PROGMEM =   "  6. SET OPTIONS    ";  //5
prog_char string_6[] PROGMEM =   "      MAIN MENU     ";  //6
PGM_P PROGMEM StringTable[] = {
  string_0, string_1, string_2, string_3, string_4, string_5, string_6

Method used for printing saved String from flash memory to LCD.

//this is the gatekeeper function. The only one to really touch the strings in program memory. This
// keeps the need
//for a buffer string to only one. So, basically we're only using 21 bytes of memory total to store
// strings.
void PrintLCD_P(int which) {
   char buffer[21];
   strcpy_P(buffer, (char*)pgm_read_word(&(StringTable[which])));

Calling of this method can seems like this:

//Prints on LCD String from flash memory in position, where pointing sixth element of StringTable[]. In this case "      MAIN MENU     ".

Next topic is about how to structure the menu and in which way make the passing thru it. In Collin80 solution every component of the menu has it's own method in which it is “wrapped”. Inside this method there is a do-while cycle which runs still until it gets output signal (button pressed), that is time to do something. After it there is a switch by which lead the way to next method representing some menu component.

Menu component may seems like this:

void mainMenu() {
  byte offset=0, loopcnt, whichkey,point=0;
  do {
    PrintLCD_P(6); //"      Main Menu     "
    PrintLCDAt_P(offset, 0, 2);
    whichkey = PollKey();
    switch(whichkey) {
       case KeyUp:
          if (offset > 0) offset--;
       case KeyDown:
          if (offset < 5) offset++;
       case KeySel:
          switch (offset) {
             case 0: //Enroll
               // enrollUser();
             case 1: //Edit users
             case 2: //Delete Users
             case 3: //Delete all users
             case 4: //List Users
             case 5: //Set options
  } while (1 == 1);

Last question is, how to interact with user.

It is simple model using analog signal. It's advantage is big simplicity. The disadvantage is the fact that we can't distinguish between a huge amount of buttons. But for three buttons for basic menu control is more then much. It's principle is that we prepare as many potential levels (eg. with voltage divider) as many buttons we have and thru buttons we conect them to analog input pin of arduino. So if the button is pressed there should be appropriate potential on the pin and we can ditinguish between different buttons.



//Scan the key pin and determine which key was pressed. Then return a code specifying each key
//There is a fuzzy range for each key. This is a central space for all key presses. That way it's
//easy to tweak these values if need be.
char KeyScan() {
   int which, which2, diff,retVal;
   which = analogRead(KeyPin);
   which2 = analogRead(KeyPin);
   retVal = KeyInv;
   diff = abs(which - which2);
   if (diff < 12) {
      if (which > 2 && which < 36) retVal = KeyLeft;
      if (which > 58 && which < 100) retVal =  KeySel;
      if (which > 241 && which < 283) retVal =  KeyDown;
      if (which > 409 && which < 451) retVal =  KeyRight;
      if (which > 577 && which < 619) retVal =  KeyUp;
   return retVal;
//repeatedly calls KeyScan until a valid key press occurs
char PollKey() {
  char Whichkey;
  do {
     Whichkey = KeyScan();
  } while (Whichkey==KeyInv);
  return Whichkey;
en/menu.txt · Last modified: 2018/01/29 10:12 (external edit)