Easy to use GLCD menu system

General discussion on mikroC for dsPIC30/33 and PIC24.
Post Reply
Author
Message
idakota
Posts: 334
Joined: 27 Sep 2006 08:07
Location: Pretoria/South Africa
Contact:

Easy to use GLCD menu system

#1 Post by idakota » 05 Jun 2008 17:13

I've created a easy to use text based menu for the GLCD.

Code: Select all

struct menuStruct;
void mainScreen();
void item2Handle();

//Font for the arrows
const unsigned short Arrows5x6[] = {
        0x30, 0x3C, 0x3F, 0x3C, 0x30,
        0x03, 0x0F, 0x3F, 0x0F, 0x03
        };

//Menu item structure
typedef struct menuItem
               {
                char *itemName;                 //Name of this item
                void (*handler)(void);          //Pointer to function, null if not used
                struct menuStruct *subMenu;     //Pointer to sub menu, null if not used
               } menuItem;

//Menu structure
typedef struct menuStruct
               {
                char *menuName;                 //Name of menu
                unsigned short numberItems;     //Number of menu items
                menuItem *items;                //Pointer to array of items
               } menuStruct;

//Demo menu. Menus are declared in reverse order,
menuItem subItem1ItemList[] = {{"Sub Sub Item 1", 0, 0}, {"Sub Sub Item 2", 0, 0}};

menuStruct subItem1Menu = {"Sub Item 1 Sub Menu", 2, &subItem1ItemList};

menuItem item1ItemList[] = {{"Sub sub menu 1", 0, &subItem1Menu}, {"Sub Item 2", 0, 0}};

menuStruct item1Menu = {"Item 1 Sub Menu", 2, &item1ItemList};

menuItem mainMenuItemList[] = {{"Sub Menu 1", 0, &item1Menu},{"Demo function", &item2Handle, 0},{"Sub sub menu 1", 0, &subItem1Menu},{"Item 4", 0, 0},{"Item 5", 0, 0},
                               {"Item 6", 0, 0},{"Item 7", 0, 0},{"Item 8", 0, 0},{"Item 9", 0, 0},{"Item 10", 0, 0}};

menuStruct mainMenu = {"Main Menu", 10, &mainMenuItemList};

//Demo item handle function
void item2Handle()
{
 GLCD_Fill(0x00);
 GLCD_Write_Text("Press RA4", 0, 0, 1);

 while(!Button(&PORTA, 4, 5, 1))
 {
 }
 return;
}

//Draws the actual menu
void drawMenu(menuStruct *menuToShow, short selectedIndex)
{
 unsigned short i;

 GLCD_Fill(0x00);
 GLCD_Set_Font(FontSystem5x8,5,8,32);
 GLCD_Write_Text(menuToShow->menuName, 0, 0, 1);

 for(i=0;i < (menuToShow->numberItems > 6 ? 6 : menuToShow->numberItems) ;i++)
 {
  if (i > 5 + (selectedIndex > 5 ? selectedIndex - 5 : 0))
  {
   break;
  }
  else if (selectedIndex < 6)
  {
   GLCD_Write_Text(menuToShow->items[i]->itemName, 5, i+1, (selectedIndex == i) ? 0 : 1);
  }
  else
  {
   GLCD_Write_Text(menuToShow->items[i+(selectedIndex-5)]->itemName, 5, i+1, (selectedIndex == i+(selectedIndex-5)) ? 0 : 1);
  }
 }

 Glcd_H_Line(0,127,7,1);
 Glcd_H_Line(0,127,55,1);
 GLCD_Set_Font(Arrows5x6,5,6,30);
 GLCD_Write_Char(30, 5, 7, 1);
 GLCD_Write_Char(31, 25, 7, 1);
 GLCD_Set_Font(FontSystem5x8,5,8,32);
 GLCD_Write_Text("Select", 45, 7, 1);
 GLCD_Write_Text("Back", 101, 7, 1);
 return;
}

//Main menu function
void openMenu(menuStruct *menuToShow)
{
 short selectedIndex = 0;               //Current selected item

 delay_ms(50);
 drawMenu(menuToShow, selectedIndex);

   do {
     if (Button(&PORTA, 0, 5, 1))
     {
        selectedIndex--;
        if (selectedIndex < 0)
        {
           selectedIndex = menuToShow->numberItems - 1;
        }
        drawMenu(menuToShow, selectedIndex);
     }
     else if (Button(&PORTA, 1, 5, 1))
     {
        selectedIndex++;
        if (selectedIndex > (menuToShow->numberItems) - 1)
        {
           selectedIndex = 0;
        }
        drawMenu(menuToShow, selectedIndex);
     }
     else if (Button(&PORTA, 2, 5, 1))
     {
         if (menuToShow->items[selectedIndex]->handler != 0)
         {
          menuToShow->items[selectedIndex]->handler();
         }
         else if (menuToShow->items[selectedIndex]->subMenu != 0)
         {
          openMenu(menuToShow->items[selectedIndex]->subMenu);
         }
         drawMenu(menuToShow, selectedIndex);
     }
     else if (Button(&PORTA, 3, 5, 1))
     {
          return;
     }

     delay_ms(30);
  } while (1);

 return;
}

void mainScreen()
{
 GLCD_Fill(0x00);
 GLCD_Set_Font(FontSystem5x8,5,8,32);
 GLCD_Write_Text("Menu", 0, 7, 1);
 return;
}

void main()
{
  ADPCFG = 0xFFFF;

  Glcd_Init_LV_24_33();
  mainScreen();

  //--- main loop
  do
  {
    if (Button(&PORTA, 0, 1, 1))
    {
     openMenu(&mainMenu);
     mainScreen();
    }
    Delay_ms(50);
  } while (1);
}//~!
You should be able to easily pick up how to add menu items, and what buttons to push (Hint: RA0-3 :P )

Hope this can help somebody in their project!

azimahmed
Posts: 15
Joined: 23 Jun 2008 09:26

#2 Post by azimahmed » 23 Jun 2008 09:34

Hi,
I am trying to implement your code in my design but it does not seems to work following is the code and I am using PIC18F452. GLCD.

The error are as follows...

implicit conversion of pointer to integer error on the following lines...
32, 36,41

Recursion of OpenMenu.

I hope you can solve this issue. Thanks.





1: [code]#include<built_in.h>


struct menuStruct;

void mainScreen();
void item2Handle();

//Font for the arrows
const unsigned short Arrows5x6[] = {
0x30, 0x3C, 0x3F, 0x3C, 0x30,
0x03, 0x0F, 0x3F, 0x0F, 0x03
};

//Menu item structure
typedef struct menuItem
{
char *itemName; //Name of this item
void (*handler)(void); //Pointer to function, null if not used
struct menuStruct *subMenu; //Pointer to sub menu, null if not used
} menuItem;

//Menu structure
typedef struct menuStruct
{
char *menuName; //Name of menu
unsigned short numberItems; //Number of menu items
menuItem *items; //Pointer to array of items
} menuStruct;

//Demo menu. Menus are declared in reverse order,
32: menuItem subItem1ItemList[] = {{"Sub Sub Item 1", 0, 0}, {"Sub Sub Item 2", 0, 0}};

36: menuStruct subItem1Menu = {"Sub Item 1 Sub Menu", 2, &subItem1ItemList};

41: menuItem item1ItemList[] = {{"Sub sub menu 1", 0, &subItem1Menu}, {"Sub Item 2", 0, 0}};

menuStruct item1Menu = {"Item 1 Sub Menu", 2, &item1ItemList};

menuItem mainMenuItemList[] = {{"Sub Menu 1", 0, &item1Menu},{"Demo function", &item2Handle, 0},{"Sub sub menu 1", 0, &subItem1Menu},{"Item 4", 0, 0},{"Item 5", 0, 0},
{"Item 6", 0, 0},{"Item 7", 0, 0},{"Item 8", 0, 0},{"Item 9", 0, 0},{"Item 10", 0, 0}};

menuStruct mainMenu = {"Main Menu", 10, &mainMenuItemList};

//Demo item handle function
void item2Handle()
{
GLCD_Fill(0x00);
GLCD_Write_Text("Press RC4", 0, 0, 1);

while(!Button(&PORTC, 4, 5, 1))
{
}
return;
}

//Draws the actual menu
void drawMenu(menuStruct *menuToShow, short selectedIndex)
{
unsigned short i;

GLCD_Fill(0x00);
GLCD_Set_Font(FontSystem5x8,5,8,32);
GLCD_Write_Text(menuToShow->menuName, 0, 0, 1);

for(i=0;i < (menuToShow->numberItems > 6 ? 6 : menuToShow->numberItems) ;i++)
{
if (i > 5 + (selectedIndex > 5 ? selectedIndex - 5 : 0))
{
break;
}
else if (selectedIndex < 6)
{
GLCD_Write_Text(menuToShow->items[i]->itemName, 5, i+1, (selectedIndex == i) ? 0 : 1);
}
else
{
GLCD_Write_Text(menuToShow->items[i+(selectedIndex-5)]->itemName, 5, i+1, (selectedIndex == i+(selectedIndex-5)) ? 0 : 1);
}
}

Glcd_H_Line(0,127,7,1);
Glcd_H_Line(0,127,55,1);
GLCD_Set_Font(Arrows5x6,5,6,30);
GLCD_Write_Char(30, 5, 7, 1);
GLCD_Write_Char(31, 25, 7, 1);
GLCD_Set_Font(FontSystem5x8,5,8,32);
GLCD_Write_Text("Select", 45, 7, 1);
GLCD_Write_Text("Back", 101, 7, 1);
return;
}

//Main menu function
void openMenu(menuStruct *menuToShow)
{
short selectedIndex = 0; //Current selected item

delay_ms(50);
drawMenu(menuToShow, selectedIndex);

do {
if (Button(&PORTC, 0, 5, 1))
{
selectedIndex--;
if (selectedIndex < 0)
{
selectedIndex = menuToShow->numberItems - 1;
}
drawMenu(menuToShow, selectedIndex);
}
else if (Button(&PORTC, 1, 5, 1))
{
selectedIndex++;
if (selectedIndex > (menuToShow->numberItems) - 1)
{
selectedIndex = 0;
}
drawMenu(menuToShow, selectedIndex);
}
else if (Button(&PORTC, 2, 5, 1))
{
if (menuToShow->items[selectedIndex]->handler != 0)
{
menuToShow->items[selectedIndex]->handler();
}
else if (menuToShow->items[selectedIndex]->subMenu != 0)
{
openMenu(menuToShow->items[selectedIndex]->subMenu);
}
drawMenu(menuToShow, selectedIndex);
}
else if (Button(&PORTC, 3, 5, 1))
{
return;
}

delay_ms(30);
} while (1);

return;
}

void mainScreen()
{
GLCD_Fill(0x00);
GLCD_Set_Font(FontSystem5x8,5,8,32);
GLCD_Write_Text("Menu", 0, 7, 1);
return;
}


void main(void)
{
trisc = 0b00011111;
Glcd_Init(&PORTB, 2, 3, 4, 5, 7, 6, &PORTD); // Glcd_Init_EP4, see Autocomplete
Glcd_Fill(0x00);


mainScreen();

do
{
if (Button(&PORTC, 0, 1, 1))
{
openMenu(&mainMenu);
mainScreen();
}
Delay_ms(50);
}
while (1);

}[/code]

[color=#BF0000][b]!!! EDITED BY ADMIN: Code tag[/b][/color]

josemabcn
Posts: 11
Joined: 23 May 2009 18:26

Re: Easy to use GLCD menu system

#3 Post by josemabcn » 25 May 2009 22:22

idakota,

I test your code in a 18F4550 and I have this errors/warnings:
"Implicit conversion of pointer to int "

in this lines:

menuItem subItem1ItemList[] = {{"Sub Sub Item 1", 0, 0}, {"Sub Sub Item 2", 0, 0}};
menuItem item1ItemList[] = {{"Sub sub menu 1", 0, &subItem1Menu}, {"Sub Item 2", 0, 0}};
menuItem mainMenuItemList[] = {{"Sub Menu 1", 0, &item1Menu},{"Demo function", &item2Handle, 0},{"Sub sub menu 1", 0, &subItem1Menu},{"Item 4", 0, 0},{"Item 5", 0, 0},{"Item 6", 0, 0},{"Item 7", 0, 0},{"Item 8", 0, 0},{"Item 9", 0, 0},{"Item 10", 0, 0}};

Please, can you help me?


Jose
idakota wrote:I've created a easy to use text based menu for the GLCD.



Hope this can help somebody in their project!

Traccker
Posts: 4
Joined: 02 Jun 2009 00:19

#4 Post by Traccker » 22 Jun 2009 20:51

A very nice code!
I could portate it to the EasyDsPic4 board.

I just need to check out how to make it use less RAM memory. It's using 68% of it. (2kB only in 30F4013)

Does anyone have an idea?

Thanks.

marbeuhan08
Posts: 2
Joined: 09 Aug 2010 12:33

Re: Easy to use GLCD menu system

#5 Post by marbeuhan08 » 09 Aug 2010 12:37

Hi,
At home I can not go to "Demo function".
Can someone help me?

Post Reply

Return to “mikroC for dsPIC30/33 and PIC24 General”