1. Welcome to our site! Electro Tech is an online community (with over 170,000 members) who enjoy talking about and building electronic circuits, projects and gadgets. To participate you need to register. Registration is free. Click here to register now.
    Dismiss Notice

lcd menu

Discussion in 'Microcontrollers' started by dawson, Oct 23, 2009.

  1. dawson

    dawson New Member

    Joined:
    Sep 21, 2009
    Messages:
    97
    Likes:
    0
    Location:
    UK, north east
    How would I make a menu like this one:

    YouTube - Menu LCD y PIC16F877A

    I would like to write a menu in c, similar to the one above I am using the pic16f628.

    I am able to have a button display a message and then go back to the main screen but i have no idea how to go any further to achieve the above.

    Can anyone help or point me in the right direction please?
     
  2. AllVol

    AllVol New Member

    Joined:
    Nov 22, 2005
    Messages:
    956
    Likes:
    9
    Location:
    Tennesee, USA
    Code (text):
     
    if (youdidit_once)
    {
    do it again
     
    else
     
    trysome_more
     
    }
     
     
    Last edited: Oct 23, 2009
  3. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    Only if it was that easy heh.... You should first make A flowchart of how u want your menu to work this way you won't get to confused later on. Once u have done that u can write code to show the menu items fairly simple..

    Since I don't work tomorrow I will take u through a few steps showing u how to make a simple menu. But it will be for my temp sensor. The idea is to teach u how to go about doing it and not just doing ur work for you.

    Sorry I'd there are any typos I'm using a iPod touch to write this heh
     
  4. dave

    Dave New Member

    Joined:
    Jan 12, 1997
    Messages:
    -
    Likes:
    0


     
  5. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US

    Here is my menu layout. Draft:

    [​IMG]
     

    Attached Files:

    • menu.jpg
      menu.jpg
      File size:
      78.8 KB
      Views:
      1,252
  6. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    Here is some of my main menu code so far... do you understand it?:

    Code (text):

    void MainMenu(void){
    unsigned char POS = 0;  //Used for cursor ONLY!
    unsigned char done = 0;
    unsigned char x;
    unsigned char ITEM=0;
    LCD_CLEAR(5);

    while(!done){
        for(x=0;x<2;x++){
            LCD_LINE(x+1);

            if(x == POS)
                LCD_DATA('>',1);
            else
                LCD_DATA(' ',1);

            LCD_STR(MainMenuLIST[x]);
        }

        switch(WaitForInput()){
            case UP:
                if(POS>0){
                    POS--;
                    ITEM--;
                }
                break;
            case DOWN:
                if(POS<1){
                    POS++;
                    ITEM++;
                }
                break;
            case ENTER:
                done = 0xFF;
                break;
        }
    }
        // ITEM contains what item is selected
        // POS isnt used incase larger then 2 menu...

        switch(ITEM){
            case 0:
                //Code to toggle C or F
                break;
            case 1:
                //Code to jump to new menu system
                break;
        }

        //Bring our title back.. cuz we are done with the menu...
        LCD_LINE(1);
        LCD_STR((unsigned rom char*)"  AtomSoftTech  ");
    }
     
     
    • Like Like x 1
  7. dawson

    dawson New Member

    Joined:
    Sep 21, 2009
    Messages:
    97
    Likes:
    0
    Location:
    UK, north east
    Hi,
    Thanks for the reply. My project is a thermostat so is very close to your example, however I am wanting to learn so am happy for you to just teach me the steps rather than doing it for me.

    I do not fully understand all your code but understand the basic principle of what you are doing:

    First you are waiting for an input and depending on which button is pressed you either increment ITEM or decrement it, when done is pressed ITEM is switched so that the relevant item info is displayed?

    I will have a go at making a flow diagram and see what I can come up with

    Thanks
     
  8. dawson

    dawson New Member

    Joined:
    Sep 21, 2009
    Messages:
    97
    Likes:
    0
    Location:
    UK, north east
    hi,
    I have had a look through the code to try and understand each step that is taken, I think I understand most of it but am struggling with this part:

    Code (text):

    for(x=0;x<2;x++){
            LCD_LINE(x+1);

            if(x == POS)
                LCD_DATA('>',1);
            else
                LCD_DATA(' ',1);

            LCD_STR(MainMenuLIST[x]);
        }
     
    As far as I can see this is a loop to determine which line to display the menu item on in the list? POS being the line number?

    Its the next line I have the problem with

    LCD_STR(MainMenuLIST[x]);

    I am guessing that you output your data like this

    lcd_out(LCD_LINE, LCD_DATA, LCD_STR)

    meaning that MainMenuLIST[x] would be the message you wish to display? but how do I make this list? is this a call to another void?
     
  9. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    The below Sets the LINE to work on... Since we are using a loop which starts on 0 we add 1 so :
    Code (text):
    LCD_LINE(x+1);....
    The loop is:
    Code (text):

    x = 0 + 1 = 1 (LINE 1)
    x=  1  + 1 = 2 (LINE 2)
     
    The below determines which item is selected and shows a '>' it the front of the line or a space if its not the line selected. POS is short for POSition....
    Code (text):

            if(x == POS)
                LCD_DATA('>',1);
            else
                LCD_DATA(' ',1);
     

    This sends a string to the LCD..

    Code (text):
    LCD_STR(MainMenuLIST[x]);
     
    This is my string array:
    Its a multidimension array... 2 x 16 since my first main menu has 2 items and the max length is 16 characters. You should make all items in any menu the same length by using spaces. Will solve a lot of issues.
    Code (text):

    unsigned rom char MainMenuLIST[2][16] = {
    {"Change View "},
    {"Change Speed"}
    };
     
     
  10. dawson

    dawson New Member

    Joined:
    Sep 21, 2009
    Messages:
    97
    Likes:
    0
    Location:
    UK, north east
    Thanks for clearing that up I now have a better understanding how it works.I have not used arrays yet so will have to find out how they work as im getting a syntax error.

    could you please explain how your WaitForInput() function works?

    I currently detect inputs like:
    if (Button(&PORTA, 4, 1, 0)) {
    do somethiong
    }

    so would it work something like this:

    Code (text):

    void WaitForInput() {
       if (Button(&PORTA, 3, 1, 0)) {
          spmehow return up
       }
       if (Button(&PORTA, 4, 1, 0)) {
          spmehow return down
       }
       if (Button(&PORTA, 4, 1, 0)) {
          spmehow return enter
       }
    }
     
     
  11. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    Sorry about not posting it in full but i like questions :)

    Ok here is my wait for input
    Code (text):

    unsigned char WaitForInput(void){
        unsigned char temp1;    //TEMP DATA HOLDER
        unsigned char done = 0; //DONE Var will determine if done

        while(!done){                 //while done == 0
            if(KeyPORT>0){            //if KeyPORT aka PORTB&0x0F.. the &0x0f will make sure we
                              //return the lower part of port only RB0 to RB3
                temp1 = KeyPORT;      //Place the lower part of port into temp variable
                while(KeyPORT==temp1);    //Like a debounce for button press
                done = 0xFF;          //Set DONE Var so we know we are complete
            }
        }
        return temp1;                 //Return our temp1 var
    }

     
    Sorry if the comments suck heh do you understand the way i do it?
     
    Last edited: Oct 24, 2009
  12. dawson

    dawson New Member

    Joined:
    Sep 21, 2009
    Messages:
    97
    Likes:
    0
    Location:
    UK, north east
    No need to appologise I like it this way they I get to learn how it works rather than just getting the code handed out.

    I dont really understand the way you detect which switch it is? or is keyPORT another array?
     
  13. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    Oops heh I will post entire code in a little while just give me some time
     
  14. dawson

    dawson New Member

    Joined:
    Sep 21, 2009
    Messages:
    97
    Likes:
    0
    Location:
    UK, north east
    ok I will read through what I have so far and try and figure out how it works.
     
  15. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    heh ok i have time now heh

    What i do is use definitions:
    Code (text):
    #define KeyPORT (PORTB&0x0F)
    #define KeyDIR  TRISB

    #define MENU  1
    #define ENTER 8
    #define UP    2
    #define DOWN  4
    Now i can use:

    Code (text):
    switch(WaitForInput())
    This will call WaitForInput which will return the lower half of portb. So portb can be:

    0x01 which is 0000-0001 in binary aka MENU
    0x02 which is 0000-0010 in binary aka UP
    0x04 which is 0000-0100 in binary aka DOWN
    0x08 which is 0000-1000 in binary aka ENTER

    Using it this way will let me use the words
    Code (text):
        switch(WaitForInput()){
            case UP:
                if(POS>0){
                    POS--;
                    ITEM--;
                }
                break;
            case DOWN:
                if(POS<1){
                    POS++;
                    ITEM++;
                }
                break;
            case ENTER:
                done = 0xFF;
                break;
        }
    instead of :
    Code (text):
        switch(WaitForInput()){
            case 0x02:
                if(POS>0){
                    POS--;
                    ITEM--;
                }
                break;
            case 0x04:
                if(POS<1){
                    POS++;
                    ITEM++;
                }
                break;
            case 0x08:
                done = 0xFF;
                break;
        }
     
  16. dawson

    dawson New Member

    Joined:
    Sep 21, 2009
    Messages:
    97
    Likes:
    0
    Location:
    UK, north east
    Thank you that makes much more sense now :)
     
  17. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    heh np ill b writing more and posting in a minute
     
  18. dawson

    dawson New Member

    Joined:
    Sep 21, 2009
    Messages:
    97
    Likes:
    0
    Location:
    UK, north east
    Thanks I appreciate all the help :)

    I am still a little confused with the array as i get the error ";expected, but 'char' found"

    Also I am unsure how you output to the lcd i have been doing it like this:

    Lcd_Out(1, 3, "Temperature:")
     
  19. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    Are you using a 2x16 LCD? If so I'll post my LCD code so you can see how I am doing mines. U should post ur code so I can see where the error is
     
    Last edited: Oct 24, 2009
  20. dawson

    dawson New Member

    Joined:
    Sep 21, 2009
    Messages:
    97
    Likes:
    0
    Location:
    UK, north east
    yes I am using a hd44780 compatible 2X16 display

    here is what I have so far:

    Code (text):

    #define KeyPORT (PORTA&0x0F)
    #define KeyDIR  TRISB

    #define ENTER 2
    #define UP    3
    #define DOWN  4

    #define LCD_LINE
    #define LCD_DATA
    #define LCD_STR

    // LCD connections definitions
    sbit LCD_RS at RA0_bit;
    sbit LCD_EN at RA1_bit;
    sbit LCD_D4 at RB0_bit;
    sbit LCD_D5 at RB1_bit;
    sbit LCD_D6 at RB2_bit;
    sbit LCD_D7 at RB3_bit;
    sbit LCD_RS_Direction at TRISA0_bit;
    sbit LCD_EN_Direction at TRISA1_bit;
    sbit LCD_D4_Direction at TRISB0_bit;
    sbit LCD_D5_Direction at TRISB1_bit;
    sbit LCD_D6_Direction at TRISB2_bit;
    sbit LCD_D7_Direction at TRISB3_bit;
    // End LCD connections definitions

    unsigned rom char MainMenuLIST[2][16] = {
    {"Option 1"},
    {"Option 2"}
    };

    unsigned char WaitForInput(void){
        unsigned char temp1;    //TEMP DATA HOLDER
        unsigned char done = 0; //DONE Var will determine if done

        while(!done){                 //while done == 0
            if(KeyPORT>0){            //if KeyPORT aka PORTB&0x0F.. the &0x0f will make sure we
                              //return the lower part of port only RB0 to RB3
                temp1 = KeyPORT;      //Place the lower part of port into temp variable
                while(KeyPORT==temp1);    //Like a debounce for button press
                done = 0xFF;          //Set DONE Var so we know we are complete
            }
        }
        return temp1;                 //Return our temp1 var
    }

    void MainMenu(void){
    unsigned char POS = 0;  //Used for cursor ONLY!
    unsigned char done = 0;
    unsigned char x;
    unsigned char ITEM=0;

    Lcd_Cmd(_LCD_CLEAR);

    while(!done){
        for(x=0;x<2;x++){
            LCD_LINE(x+1);

            if(x == POS)
                LCD_DATA('>',1);
            else
                LCD_DATA(' ',1);

            LCD_STR(MainMenuLIST[x]);
        }

        switch(WaitForInput()){
            case UP:
                if(POS>0){
                    POS--;
                    ITEM--;
                }
                break;
            case DOWN:
                if(POS<1){
                    POS++;
                    ITEM++;
                }
                break;
            case ENTER:
                done = 0xFF;
                break;
        }
    }
        // ITEM contains what item is selected
        // POS isnt used incase larger then 2 menu...

        switch(ITEM){
            case 0:
                //Code to toggle C or F
                break;
            case 1:
                //Code to jump to new menu system
                break;
        }

        //Bring our title back.. cuz we are done with the menu...
        LCD_LINE(1);
        LCD_STR((unsigned rom char*)"  AtomSoftTech  ");

    }
    void main() {
         CMCON  |= 7;                       // Disable Comparators
      Lcd_Init();                                    // Initialize LCD
      Lcd_Cmd(_LCD_CLEAR);                           // Clear LCD
      Lcd_Cmd(_LCD_CURSOR_OFF);                      // Turn cursor off
      Lcd_Out(1, 3, "Temperature:");
       do {
        if(Button(&PORTA,2, 1, 0)) {
                 MainMenu();
                 }
        } while (1);
    }
     
     
  21. AtomSoft

    AtomSoft Well-Known Member

    Joined:
    Feb 7, 2008
    Messages:
    5,670
    Likes:
    41
    Location:
    Brooklyn, NY US
    can you post all the code because this is confusing to me... also what are you writing in? like which compiler...? C18, CSS, Hi-Tech, MikroC?

    Where are your buttons connected to ?
     

Share This Page