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.

  • 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.

lcd menu

Status
Not open for further replies.

dawson

New Member
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?
 

AllVol

New Member
Code:
if (youdidit_once)
{
do it again
 
else
 
trysome_more
 
}
 
Last edited:

AtomSoft

Well-Known Member
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
 

AtomSoft

Well-Known Member
Here is my menu layout. Draft:

menu-jpg.34662
 

Attachments

  • menu.jpg
    menu.jpg
    78.8 KB · Views: 1,409

AtomSoft

Well-Known Member
Here is some of my main menu code so far... do you understand it?:

Code:
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  ");
}
 

dawson

New Member
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

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
 

dawson

New Member
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:
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?
 

AtomSoft

Well-Known Member
The below Sets the LINE to work on... Since we are using a loop which starts on 0 we add 1 so :
Code:
LCD_LINE(x+1);....

The loop is:
Code:
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:
		if(x == POS)
			LCD_DATA('>',1);
		else
			LCD_DATA(' ',1);


This sends a string to the LCD..

Code:
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:
unsigned rom char MainMenuLIST[2][16] = {
{"Change View "},
{"Change Speed"}
};
 

dawson

New Member
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:
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
   }
}
 

AtomSoft

Well-Known Member
Sorry about not posting it in full but i like questions :)

Ok here is my wait for input
Code:
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:

dawson

New Member
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?
 

AtomSoft

Well-Known Member
heh ok i have time now heh

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

#define MENU  1
#define ENTER 8
#define UP    2
#define DOWN  4

Now i can use:

Code:
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:
	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:
	switch(WaitForInput()){
		case 0x02:
			if(POS>0){
				POS--;
				ITEM--;
			}
			break;
		case 0x04:
			if(POS<1){
				POS++;
				ITEM++;
			}
			break;
		case 0x08:
			done = 0xFF;
			break;
	}
 

dawson

New Member
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:")
 

AtomSoft

Well-Known Member
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:

dawson

New Member
yes I am using a hd44780 compatible 2X16 display

here is what I have so far:

Code:
#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);
}
 

AtomSoft

Well-Known Member
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 ?
 
Status
Not open for further replies.

Latest threads

EE World Online Articles

Loading
Top