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

Status
Not open for further replies.

#### dawson

##### New Member
How would I make a menu like this one:

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:

#### Attachments

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);

}

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:
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);

}

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

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.

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
Oops heh I will post entire code in a little while just give me some time

#### dawson

##### New Member
ok I will read through what I have so far and try and figure out how it works.

#### 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 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;
}
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
Thank you that makes much more sense now

#### AtomSoft

##### Well-Known Member
heh np ill b writing more and posting in a minute

#### 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
}

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);

}

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:
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)) {
}
} 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.

Replies
1
Views
2K
Replies
8
Views
4K
Replies
14
Views
2K
Replies
16
Views
957
Replies
23
Views
19K