lcd menu

Status
Not open for further replies.
This code wont work:

Code:
  //--- main loop
  do {
    if(Button(&PORTA,2, 1, 0)) {
             MainMenu();
             }
    else {
            read_temp();
          }
    } while (1);

Change it to :
Code:
  //--- main loop
  do {
    if(KeyPORT == ENTER) {
             MainMenu();
             }
    else {
            read_temp();
          }
    } while (1);

I say it wont work because its always high since pulled high so you have to check for low. Did you change the definition to:

#define KeyPORT (~((PORTA>>2)&0x0F))
 
Last edited:
This is how I would normally turn an led on via a switch.

When first turned on "Waiting" is displayed when switch 1(RA2) is pressed "LED ON" is displayed and the LED is turned on, when switch 2 (RA3) is pressed "LED OFF" is displayed and the LED is turned off.

This is all the code I am using, any other include files must be automatically selected by mikroc and I cannot see what it is.

Code:
// 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

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, "Waiting");
  do {
  if (Button(&PORTA, 2, 1, 0)) {  // Detect logical one to zero
     Delay_ms(100);
     Lcd_Cmd(_LCD_CLEAR);
     Lcd_Out(1,1, "LED ON");
     TRISA.F6 = 0;
     PORTA.F6 = 1;
  }
  if (Button(&PORTA, 3, 1, 0)) {  // Detect logical one to zero
     Delay_ms(100);
     Lcd_Cmd(_LCD_CLEAR);
     Lcd_Out(1,1, "LED OFF");
     TRISA.F6 = 0;
     PORTA.F6 = 0;
  }
  } while (1);
}
 
here is teh equavalent code but written the way you have shown me, but it does not recognise switch presses:

Code:
#define KeyPORT ((PORTA>>2)&0x0F)

#define ON   2
#define OFF  3

// 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 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 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, "Waiting");
  do {
  //--- main loop
   switch(WaitForInput()){
		case ON:
                     Delay_ms(100);
                     Lcd_Cmd(_LCD_CLEAR);
                     Lcd_Out(1,1, "LED ON");
                     TRISA.F6 = 0;
                     PORTA.F6 = 1;
			break;
		case OFF:
                     Delay_ms(100);
                     Lcd_Cmd(_LCD_CLEAR);
                     Lcd_Out(1,1, "LED OFF");
                     TRISA.F6 = 0;
                     PORTA.F6 = 0;
			break;
	}
	} while (1);
}
 
oops forgot about the define, now change to
#define KeyPORT (~((PORTA>>2)&0x0F))
in my example script aswell but wit the same result
 
Last edited:
you are using 2 and 3 when its not supposed to be that.. ...

one minute...
 
Last edited:
Im downloading MikroC now to try it out but try this for now:
Code:
#define KeyPORT (~((PORTA>>2)&0x0F))

#define ON   1
#define OFF  2

// LCD connections definitions
s
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 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 main() {
  CMCON  |= 7;                       // Disable Comparators
  TRISA = (0x0F<<2);                 // [b]RA5,RA4,RA3,RA2 are set to input[/b]
  Lcd_Init();                                    // Initialize LCD
  Lcd_Cmd(_LCD_CLEAR);                           // Clear LCD
  Lcd_Cmd(_LCD_CURSOR_OFF);                      // Turn cursor off
  Lcd_Out(1, 3, "Waiting");
  do {
  //--- main loop
   switch(WaitForInput()){
		case ON:
                     Delay_ms(100);
                     Lcd_Cmd(_LCD_CLEAR);
                     Lcd_Out(1,1, "LED ON");
                     TRISA.F6 = 0;
                     PORTA.F6 = 1;
			break;
		case OFF:
                     Delay_ms(100);
                     Lcd_Cmd(_LCD_CLEAR);
                     Lcd_Out(1,1, "LED OFF");
                     TRISA.F6 = 0;
                     PORTA.F6 = 0;
			break;
	}
	} while (1);
}
 
Ok thanks I gess you use a different compiler? Your suggestion did the same as what my code did, just displays waiting.
 
This works nice:
Code:
#define ON   2
#define OFF  3

unsigned char WaitForInput(void){
    unsigned char done = 0;           //DONE Var will determine if done and hold key

    while(!done){        	      //while done == 0
      if (Button(&PORTA, ON, 1, 0))   //Is On button pressed (LOW)
          done = ON;                  //If So set done to ON
      if (Button(&PORTA, OFF, 1, 0))  //Is Off button pressed (LOW)
          done = OFF;                 //If so set done to OFF
    }
    return done;		      //Return our done/key var
}

void main() {
  CMCON  |= 7;                        // Disable Comparators
  TRISA = (0x0F<<2);                  // [b]RA5,RA4,RA3,RA2 are set to input[/b]

  do {
  //--- main loop
   switch(WaitForInput()){
		case ON:
                     Delay_ms(100);
                     TRISA.F6 = 0;
                     PORTA.F6 = 1;
			break;
		case OFF:
                     Delay_ms(100);
                     TRISA.F6 = 0;
                     PORTA.F6 = 0;
			break;
	}
	} while (1);
}
 
Last edited:
This also works well:
Code:
unsigned char WaitForInput(void){
    unsigned char done = 0;           //DONE Var will determine if done and hold key

    while(!done){        	      //while done == 0
      if (Button(&PORTA, ON, 1, 0))   //Is On button pressed (LOW)
          return ON;                  //If So set done to ON
      if (Button(&PORTA, OFF, 1, 0))  //Is Off button pressed (LOW)
          return OFF;                 //If so set done to OFF
    }
}
 
Last edited:
yes that does work nicely thank you I will now try and implement the rest of the menu with this code
 
I thought I would add the array to the script and thought that the following should still loop through the menu:

Code:
#define MENU   2
#define UP  3
#define DOWN  4
// 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 char MainMenuLIST[3][16] = {
{"Option 1"},
{"Option 2"},
{"Option 3"}
};

unsigned char WaitForInput(void){
	unsigned char done = 0; //DONE Var will determine if done and hold key

	while(!done){				  //while done == 0
    if (Button(&PORTA, MENU, 1, 0))
          done = MENU;
    if (Button(&PORTA, UP, 1, 0))
          done = UP;
    if (Button(&PORTA, DOWN, 1, 0))
          done = DOWN;
	}
	return done;				  //Return our done/key var
}

void main() {
  unsigned char POS = 0;
  unsigned char x;
  CMCON  |= 7;                       // Disable Comparators
  TRISA = (0x0F<<2);                 // RA5,RA4,RA3,RA2 are set to input
  Lcd_Init();                                    // Initialize LCD
  Lcd_Cmd(_LCD_CLEAR);                           // Clear LCD
  Lcd_Cmd(_LCD_CURSOR_OFF);                      // Turn cursor off
  Lcd_Out(1, 3, "Waiting");
  
  do {

  //--- main loop
   switch(WaitForInput()){
		case MENU:
                     Delay_ms(100);
                     Lcd_Cmd(_LCD_CLEAR);
                     for(x=0;x<2;x++){
                       if(x == POS)
                       Lcd_Out((x+1),2,">");
                     else
			Lcd_Out((x+1),2," ");

                     Lcd_Out((x+1),2,MainMenuLIST[x]);
                     }
                     break;
                case UP:
                     if(POS>0){
               	     POS--;
                     }
                     break;
		case DOWN:
		     if(POS<1){
		     POS++;
                     }
		break;
	}
	} while (1);
}

This scrip displays "Waiting" when MENU is pressed it displays "Option 1" on line 1 and "Option 2" on line 2 however there is no "<" on the screen and pressing UP and DOWN do nothing and I never see option 3.

I would of expected this to:

Waiting
Press MENU
>Option 1
Option 2
press DOWN
>Option 2
Option 3
press DOWN
Option 2
>Option 3
 
I have just changed
Code:
for(x=0;x<2;x++){
                       if(x == POS)
                       Lcd_Out((x+1),2,">");
                     else
			Lcd_Out((x+1),2," ");

                     Lcd_Out((x+1),2,MainMenuLIST[x]);
                     }

to

Code:
for(x=0;x<2;x++){
                       if(x == POS)
                       Lcd_Out((x+1),1,">");
                     else
			Lcd_Out((x+1),1," ");

                     Lcd_Out((x+1),2,MainMenuLIST[x]);
                     }

and it now displays:
>Option 1
Option 2

however the UP and DOWN switches still do nothing
 
The following works as expected but only for options 1 and 2, option 3 is still never shown:

Code:
#define MENU   2
#define UP  3
#define DOWN  4
// 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 char MainMenuLIST[3][16] = {
{"Option 1"},
{"Option 2"},
{"Option 3"}
};

unsigned char WaitForInput(void){
	unsigned char done = 0; //DONE Var will determine if done and hold key

	while(!done){				  //while done == 0
    if (Button(&PORTA, MENU, 1, 0))
          done = MENU;
    if (Button(&PORTA, UP, 1, 0))
          done = UP;
    if (Button(&PORTA, DOWN, 1, 0))
          done = DOWN;
	}
	return done;				  //Return our done/key 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++){

		if(x == POS)
   Lcd_Out((x+1),1,">");
		else
   Lcd_Out((x+1),1," ");

        Lcd_Out((x+1),2,MainMenuLIST[x]);
	}

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

	switch(ITEM){
		case 0:
		Lcd_Cmd(_LCD_CLEAR);
                Lcd_Out(1, 3, "temp   ");
                Delay_ms(2000);
			break;
		case 1:
                Lcd_Cmd(_LCD_CLEAR);
                Lcd_Out(1, 3, "Time");
                Delay_ms(2000);
			break;
	}

	//Bring our title back.. cuz we are done with the menu...


}

void main() {
  unsigned char POS = 0;
  unsigned char x;
  CMCON  |= 7;                       // Disable Comparators
  TRISA = (0x0F<<2);                 // RA5,RA4,RA3,RA2 are set to input
  Lcd_Init();                                    // Initialize LCD
  Lcd_Cmd(_LCD_CLEAR);                           // Clear LCD
  Lcd_Cmd(_LCD_CURSOR_OFF);                      // Turn cursor off
  Lcd_Out(1, 3, "Waiting");
      do {
 switch(WaitForInput()){
		case MENU:
		Delay_ms(100);
		MainMenu();
		break;
		}

} while (1);
}
 
look at my other menu... you need a starting point aka a page reference... check this post in 1 minute for code below

EDIT: TRY THIS:
Code:
void MainMenu(void){
unsigned char POS = 0; 	//Used for cursor ONLY!
unsigned char done = 0;
unsigned char x;
unsigned char ITEM=0;
unsigned char PAGE=0;

Lcd_Cmd(_LCD_CLEAR);

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

		if(x == POS)
   Lcd_Out((x+1),1,">");
		else
   Lcd_Out((x+1),1," ");

        Lcd_Out((x+1),2,MainMenuLIST[(x+PAGE)]);
	}

	switch(WaitForInput()){
		case UP:
			if(POS>0){
				POS--;
				ITEM--;
			} else {
        if(PAGE != 0) PAGE--;
      }
			break;
		case DOWN:
			if(POS<1){
				POS++;
				ITEM++;
			} else {
        PAGE++;
      }
			break;
		case MENU:
			done = 0xFF;
			break;
	}
}
	// ITEM contains what item is selected
	// POS isnt used incase larger then 2 menu...
[B]  ITEM+=PAGE;[/B]
	switch(ITEM){
		case 0:
                Delay_ms(2000);
			break;
		case 1:
                Delay_ms(2000);
			break;
	}

	//Bring our title back.. cuz we are done with the menu...


}

Try it now heh i forgot to add the 1 line:
ITEM+=PAGE;
 
Last edited:
Status
Not open for further replies.
Cookies are required to use this site. You must accept them to continue using the site. Learn more…