CCS C Software and Maintenance Offers
FAQFAQ   FAQForum Help   FAQOfficial CCS Support   SearchSearch  RegisterRegister 

ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

CCS does not monitor this forum on a regular basis.

Please do not post bug reports on this forum. Send them to CCS Technical Support

Failure to come out of the loop from a sub menu

 
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion
View previous topic :: View next topic  
Author Message
colesha



Joined: 09 Jan 2012
Posts: 45

View user's profile Send private message Send e-mail

Failure to come out of the loop from a sub menu
PostPosted: Fri Feb 14, 2020 5:57 am     Reply with quote

Hello,
am trying to make a menu function, it is working well but once i select the main menu to enter the sub menu, once in there, i can not go back to the main menu. I tried the tutorial on http://www.magusporta.com/tips/menu_lcd/menu_lcd.html but it is using an encoder which kind of gave me had time to replace the encoder switch with push buttons and internal interrupt.
Here is the entire code. Kindly help. Thanks


Code:

#include <16f887.h>
#device adc=10
#device *=16
#FUSES NOWDT                    //No Watch Dog Timer
#FUSES HS                       //High speed Osc (> 4mhz)
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOBROWNOUT                 //Reset when brownout detected
#FUSES NOPUT                    //No Power Up Timer
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#use delay(clock=20000000)
#use fast_io(A)
#include <flex_lcd4201.c>    //you can use your 4x20 lcd driver

//************************ Varriables Declaration ***************************//
int menu;
int Screen ;

//************************ Cursor ***************************//
void graphics() {          //User defined graphics: cursor and arrows

   // Cursor: 0 //
   lcd_send_byte(0,0b01000000);
   lcd_send_byte(1,0b00010000);
   lcd_send_byte(1,0b00011000);
   lcd_send_byte(1,0b00011100);
   lcd_send_byte(1,0b00011110);
   lcd_send_byte(1,0b00011100);
   lcd_send_byte(1,0b00011000);
   lcd_send_byte(1,0b00010000);
   lcd_send_byte(1,0b00000000);
}

//************************ Satellite Sub Menus/Functions ***************************//
void Function_A(void) {

   lcd_putc("\fScn A (Function A)\n");
   lcd_putc("Push tO RTn to menu");
   if(input(Pin_D7)==1)
   break; 
}
void Function_B() {
   lcd_putc("\fScreen B (Function B)\n");
   lcd_putc("Push to rtn to menu");
   if(input(Pin_D7)==1)
   break;
}
void Function_C() {
   lcd_putc("\fScrn C (Function C)\n");
   lcd_putc("Push to rtn to menu");
   if(input(Pin_D7)==1)
   break;
}

//************************ Navigate menu(Display Curssor) ***************************//

menu_screen(int8 navigate){        //menu_extensions   
switch(navigate){   
case 0:
lcd_gotoxy(1, 1);        //go to raw 1 and
lcd_putc(0);            //display curssor
lcd_gotoxy(1,4);         // go to raw 4
lcd_putc(" ");          //remove curssor from raw 4
menu=0;                 // First menu
break;

case 1:
lcd_gotoxy(1, 2);          //go to raw 2 and
lcd_putc(0);               //display curssor
lcd_gotoxy(1,1);            //go to raw 1 and
lcd_putc(" ");              //remove curssor from raw 1
menu=1;                     // Second menu
break;

case 2:
lcd_gotoxy(1, 3);            //go to raw 3 and
lcd_putc(0);                 //display curssor
lcd_gotoxy(1,2);              //go to raw 2 and
lcd_putc(" ");                //remove curssor from raw 2
menu=2;                       // Third menu
break;

case 3:
lcd_gotoxy(1, 4);          //go to raw 4 and
lcd_putc(0);               //display curssor
lcd_gotoxy(1,3);           //go to raw 3 and
lcd_putc(" ");             //remove curssor from raw 3
menu=3;                     // Fouth menu
break;
}}

//-------Test prgram to flash led---------//
void status()
{
 
    output_high(PIN_D1);;
    delay_ms(500);
    output_low(PIN_D1);
   delay_ms(500);
}

//************************ Main program ***************************//
void main(){
   //setup_psp(psp_disabled);
   lcd_init();
   setup_spi(spi_ss_disabled);
   setup_timer_0(RTCC_INTERNAL);
   setup_timer_1(t1_disabled);
   setup_timer_2(t2_disabled,0,1);
   setup_adc(adc_clock_internal);
   setup_ccp1(ccp_off);
   setup_ccp2(ccp_off);
   set_adc_channel( 0 );
   delay_us(20);
   float   actual_temp, setpoint_temp, temp;
 
   setup_adc(ADC_CLOCK_DIV_8 );
   setup_adc_ports(sAN4);
   graphics();
   delay_ms(1250);
   menu=0;

//-------Screen Panes---------//
screen:
lcd_gotoxy(1, 2);
printf(lcd_putc, "Main Screen");
printf(lcd_putc, "\nFor our Menu");
   printf(lcd_putc, "\nImplemetation");
   printf(lcd_putc, "\n.....................");
   
                     
   
while(1)
  {
        set_adc_channel(4);
        delay_us(20);
        actual_temp = read_adc();
        temp = actual_temp*0.488281;               // Calc. temperature
        delay_ms(10);
        lcd_gotoxy(1, 1);
        printf(lcd_putc,"Tmp:%3.1f\x01C Set:%3.0f\x01C",temp, setpoint_temp);
        //status();
//---------------------Main Menu----------------------------------------------------//
screen=0;      //screen

if(input(PIN_B0)==1)       // Menu key
{
lcd_putc("\f");   // clear lcd;
lcd_gotoxy(2,1);
lcd_putc("Push to view scn A  ");
lcd_gotoxy(2,2);
lcd_putc("Push to view scn B ");                                         
lcd_gotoxy(2,3);
lcd_putc("Push to view scn C ");                             
lcd_gotoxy(2,4);
lcd_putc("Push Escape ");

//---------------------Navigate Main Menu----------------------------------------------------//

  if(screen==0){
  menu_screen(0);
while(1)
{
if(input(PIN_D5)==1){        //Up button pressed actually does nothing
if(menu==4){
menu=0;
}
menu=menu;
menu_screen(menu);
delay_ms(100);
}
if(input(PIN_D6)==1){         //Down button pressed to select next menu
if(menu==4){                  // if at fouth  raw
menu=0;                       // go back to first raw           
menu=menu-1;
}
menu=menu+1;
menu_screen(menu);
delay_ms(100);
}
  screen=1;
  delay_ms(200);
       
//---------------------SUB MENU Selection----------------------------------------------------//       
 if(input(PIN_a0)==1)          //Enter to view sub Menu
 {
 switch(menu){
 case 0:                        //Menu 1
       while(1){
       if(input(PIN_a0)==1){      //Press enter to view sub menu
       //screen=0;
       function_A();
       }
     }
 break;
 case 1:                         // Menu 2
       while(1){
       if((input(PIN_a0)==1)&& (menu==1)){  //Press enter to view sub menu
       
       function_B();
       }
     }
     break;
   case 2:                         //Menu 3
       while(1){
       if((input(PIN_a0)==1)&& (menu==2)){    //Press enter to view sub menu
       
       function_C();
       }
     }
break;

//---------------------Exit MENU----------------------------------------------------//
 case 3:                       //Exit Main menu
       while(1){
       if((input(PIN_a0)==1)&& (menu==3)){
     
        lcd_putc("\f");  //clear lcd
        goto screen;
       }
     }
     break;
     default: break;     
}}}}}}}


Last edited by colesha on Fri Feb 14, 2020 8:33 am; edited 2 times in total
gjs_rsdi



Joined: 06 Feb 2006
Posts: 468
Location: Bali

View user's profile Send private message Send e-mail

PostPosted: Fri Feb 14, 2020 6:33 am     Reply with quote

Hi colesha

Your program as posted does not compile.
It gives
Quote:
Error 128 "PR887.c" Line 0(0,0): A #DEVICE required before this line

After removing "[" it gives 57 errors. the first:
Quote:
*** Error 18 "PR887.c" Line 13(10,26): File can not be opened
Not in "C:\Program Files (x86)\PICC\devices\flex_lcd4201.c"
Not in "C:\Program Files (x86)\PICC\drivers\flex_lcd4201.c"
Not in source "flex_lcd4201.c"
Not in local "flex_lcd4201.c"

Tried to find flex_lcd4201.c on my PC, didn't find.
I have CCS PCM C Compiler, Version 5.062

Best wishes
Joe
PCM programmer



Joined: 06 Sep 2003
Posts: 21708

View user's profile Send private message

PostPosted: Fri Feb 14, 2020 7:49 am     Reply with quote

Colesha, please learn how to do code blocks.
You do it like this, except with no spaces before and after the word 'code':
[ code ]
#include <16f887.h>
#device adc=10
#device *=16
#FUSES NOWDT //No Watch Dog Timer
#FUSES HS //High speed Osc (> 4mhz)
#FUSES NOPROTECT
[ /code ]
Edit your post and fix the code blocks.

Use the preview button to check if you did it correctly, before submitting it.
colesha



Joined: 09 Jan 2012
Posts: 45

View user's profile Send private message Send e-mail

PostPosted: Fri Feb 14, 2020 8:14 am     Reply with quote

gjs_rsdi wrote:
Hi colesha

Your program as posted does not compile.
It gives
Quote:
Error 128 "PR887.c" Line 0(0,0): A #DEVICE required before this line


After removing "[" it gives 57 errors. the first:
Quote:
*** Error 18 "PR887.c" Line 13(10,26): File can not be opened
Not in "C:\Program Files (x86)\PICC\devices\flex_lcd4201.c"
Not in "C:\Program Files (x86)\PICC\drivers\flex_lcd4201.c"
Not in source "flex_lcd4201.c"
Not in local "flex_lcd4201.c"

Tried to find flex_lcd4201.c on my PC, didn't find.
I have CCS PCM C Compiler, Version 5.062

Best wishes
Joe


hello i have reproduced the error and found that i posted wrongly, when you copied the code, you included the '[' before the #include <16f887.h>, sorry about that.

The flex_lcd4201.c is a customized version of the flex_lcd420 driver which i found on this blog, i just renamed it so that it can match my development board, however you can use any 4x20 lcd driver you have.

let me re-post the code
colesha



Joined: 09 Jan 2012
Posts: 45

View user's profile Send private message Send e-mail

PostPosted: Fri Feb 14, 2020 8:24 am     Reply with quote

PCM programmer wrote:
Colesha, please learn how to do code blocks.
You do it like this, except with no spaces before and after the word 'code':
[ code ]
#include <16f887.h>
#device adc=10
#device *=16
#FUSES NOWDT //No Watch Dog Timer
#FUSES HS //High speed Osc (> 4mhz)
#FUSES NOPROTECT
[ /code ]
Edit your post and fix the code blocks.

Use the preview button to check if you did it correctly, before submitting it.


Thanks for the direction, i have edited the post. Am new here.
colesha



Joined: 09 Jan 2012
Posts: 45

View user's profile Send private message Send e-mail

PostPosted: Fri Feb 14, 2020 8:27 am     Reply with quote

gjs_rsdi wrote:
Hi colesha

Your program as posted does not compile.
It gives
Quote:
Error 128 "PR887.c" Line 0(0,0): A #DEVICE required before this line

After removing "[" it gives 57 errors. the first:
Quote:
*** Error 18 "PR887.c" Line 13(10,26): File can not be opened
Not in "C:\Program Files (x86)\PICC\devices\flex_lcd4201.c"
Not in "C:\Program Files (x86)\PICC\drivers\flex_lcd4201.c"
Not in source "flex_lcd4201.c"
Not in local "flex_lcd4201.c"

Tried to find flex_lcd4201.c on my PC, didn't find.
I have CCS PCM C Compiler, Version 5.062

Best wishes
Joe


Sir , i have edited the post, please try again.
Thanks
Ttelmah



Joined: 11 Mar 2010
Posts: 19518

View user's profile Send private message

PostPosted: Fri Feb 14, 2020 9:19 am     Reply with quote

Your problem is this (and the other similar bits).
Code:

 switch(menu){
 case 0:                        //Menu 1
       while(1){
       //This instruction means 'loop for ever'
       if(input(PIN_a0)==1){      //Press enter to view sub menu
       //screen=0;
       function_A();
       //Function A exits, but you are still 'stuck' in the 'for ever' loop.....
       }
     }

//Consider instead:
int1 loop_flag; //global variable

 switch(menu){
 case 0:                        //Menu 1
       loop_flag=TRUE;
       while(loop_flag){
       if(input(PIN_a0)==1){      //Press enter to view sub menu
       //screen=0;
       function_A();
       }
     }

//Now if in function_A, when it exits, you set 'loop_flag=FALSE;' when
//it exits, it'll drop out of the loop.


Obviously you can use the same flag for all the functions and just add
the line to set this 'FALSE' when you want to drop out of the loop.
colesha



Joined: 09 Jan 2012
Posts: 45

View user's profile Send private message Send e-mail

PostPosted: Fri Feb 14, 2020 2:20 pm     Reply with quote

Ttelmah wrote:
Your problem is this (and the other similar bits).
Code:

 switch(menu){
 case 0:                        //Menu 1
       while(1){
       //This instruction means 'loop for ever'
       if(input(PIN_a0)==1){      //Press enter to view sub menu
       //screen=0;
       function_A();
       //Function A exits, but you are still 'stuck' in the 'for ever' loop.....
       }
     }

//Consider instead:
int1 loop_flag; //global variable

 switch(menu){
 case 0:                        //Menu 1
       loop_flag=TRUE;
       while(loop_flag){
       if(input(PIN_a0)==1){      //Press enter to view sub menu
       //screen=0;
       function_A();
       }
     }

//Now if in function_A, when it exits, you set 'loop_flag=FALSE;' when
//it exits, it'll drop out of the loop.


Obviously you can use the same flag for all the functions and just add
the line to set this 'FALSE' when you want to drop out of the loop.


Thanks sir, it has really worked. Here is the final code:
Code:

#include <16f887.h>
#device adc=10
#device *=16
#FUSES NOWDT                    //No Watch Dog Timer
#FUSES HS                       //High speed Osc (> 4mhz)
#FUSES NOPROTECT                //Code not protected from reading
#FUSES NOBROWNOUT                 //Reset when brownout detected
#FUSES NOPUT                    //No Power Up Timer
#FUSES NODEBUG                  //No Debug mode for ICD
#FUSES NOLVP                    //No low voltage prgming, B3(PIC16) or B5(PIC18) used for I/O
#use delay(clock=20000000)
#use fast_io(A)
#include <flex_lcd4201.c>    //you can use your 4x20 lcd driver

//************************ Variables Declaration ***************************//
int menu;
int Screen ;
int1 loop_flag; //global variable

//************************ Cursor ***************************//

void graphics() {          //User defined graphics: cursor and arrows

   // Cursor: 0 //
   lcd_send_byte(0,0b01000000);
   lcd_send_byte(1,0b00010000);
   lcd_send_byte(1,0b00011000);
   lcd_send_byte(1,0b00011100);
   lcd_send_byte(1,0b00011110);
   lcd_send_byte(1,0b00011100);
   lcd_send_byte(1,0b00011000);
   lcd_send_byte(1,0b00010000);
   lcd_send_byte(1,0b00000000);
}

//************************ Satellite Sub Menus/Functions ***************************//
void Function_A() {

   lcd_putc("\fScn A (Function A)\n");
   lcd_putc("Push tO RTn to menu");
    while(input(Pin_D7)==0)
   loop_flag==False;
 
}
void Function_B() {
   lcd_putc("\fScreen B (Function B)\n");
   lcd_putc("Push to rtn to menu");
   while(input(Pin_D7)==0)
   loop_flag==FALSE;
   
}
void Function_C() {
   lcd_putc("\fScrn C (Function C)\n");
   lcd_putc("Push to rtn to menu");
   while(input(Pin_D7)==0)
   loop_flag=FALSE;
 
}

//************************ Navigate menu(Display Cursor) ***************************//

menu_screen(int8 navigate){        //menu_extensions   
switch(navigate){   
case 0:
lcd_gotoxy(1, 1);        //go to raw 1 and
lcd_putc(0);            //display cursor
lcd_gotoxy(1,4);         // go to raw 4
lcd_putc(" ");          //remove cursor from raw 4
menu=0;                 // First menu
break;

case 1:
lcd_gotoxy(1, 2);          //go to raw 2 and
lcd_putc(0);               //display cursor
lcd_gotoxy(1,1);            //go to raw 1 and
lcd_putc(" ");              //remove cursor from raw 1
menu=1;                     // Second menu
break;

case 2:
lcd_gotoxy(1, 3);            //go to raw 3 and
lcd_putc(0);                 //display cursor
lcd_gotoxy(1,2);              //go to raw 2 and
lcd_putc(" ");                //remove cursor from raw 2
menu=2;                       // Third menu
break;

case 3:
lcd_gotoxy(1, 4);          //go to raw 4 and
lcd_putc(0);               //display cursor
lcd_gotoxy(1,3);           //go to raw 3 and
lcd_putc(" ");             //remove cursor from raw 3
menu=3;                     // Fourth menu
break;
}}

//-------Test program to flash led---------//
void status()
{
 
    output_high(PIN_D1);;
    delay_ms(500);
    output_low(PIN_D1);
   delay_ms(500);
}

//************************ Main program ***************************//
void main(){
   //setup_psp(psp_disabled);
   lcd_init();
   setup_spi(spi_ss_disabled);
   setup_timer_0(RTCC_INTERNAL);
   setup_timer_1(t1_disabled);
   setup_timer_2(t2_disabled,0,1);
   setup_adc(adc_clock_internal);
   setup_ccp1(ccp_off);
   setup_ccp2(ccp_off);
   set_adc_channel( 0 );
   delay_us(20);
   float   actual_temp, setpoint_temp, temp;
 
   setup_adc(ADC_CLOCK_DIV_8 );
   setup_adc_ports(sAN4);
   graphics();
   delay_ms(1250);
   menu=0;

//-------Screen Panes---------//
screen:
   lcd_gotoxy(1, 2);
   printf(lcd_putc, "\n Main Screen");
   printf(lcd_putc, "\nimplementation");
   printf(lcd_putc, "\n.....................");
   
                     
   
while(1)
  {
        set_adc_channel(4);
        delay_us(20);
        actual_temp = read_adc();
        temp = actual_temp*0.488281;               // Calc. temperature
        delay_ms(10);
        lcd_gotoxy(1, 1);
        printf(lcd_putc,"Tmp:%3.1f\x01C Set:%3.0f\x01C",temp, setpoint_temp);
        //status();
//---------------------Main Menu----------------------------------------------------//

screen=0;      //screen

if(input(PIN_B0)==1)       // Menu key
{

//---------------------Navigate Main Menu----------------------------------------------------//
  screen1:
  lcd_putc("\f");   // clear lcd;
  lcd_gotoxy(2,1);
  lcd_putc("Push to view scn A  ");
  lcd_gotoxy(2,2);
  lcd_putc("Push to view scn B ");                                         
  lcd_gotoxy(2,3);
  lcd_putc("Push to view scn C ");                             
  lcd_gotoxy(2,4);
  lcd_putc("Push Escape ");
 
  if(screen==0){
  menu_screen(0);
while(1)
{                 //ADD this line if you want to move back and forth in the name
/*if(input(PIN_D5)==1){        //Up button pressed actually does nothing
if(menu==4){
menu=0;
}
menu=menu;
menu_screen(menu);
delay_ms(100);
}*/
if(input(PIN_D6)==1){         //Down button pressed to select next menu
if(menu==4){                  // if at fourth raw
menu=0;                       // go back to first raw           
menu=menu-1;
}
menu=menu+1;
menu_screen(menu);
delay_ms(100);
}
  screen=1;
  delay_ms(200);
       
//---------------------SUB MENU Selection----------------------------------------------------//       
 if(input(PIN_a0)==1)          //Enter to view sub Menu
 {
 switch(menu){
 
 case 0:  //Menu 1
       loop_flag=TRUE;
       while(loop_flag)
       {
       if(input(PIN_a0)==1){      //Press enter to view sub menu
       screen=0;
       function_A();
       }
       break;
     }
break;
 case 1:                         // Menu 2
        loop_flag=TRUE;
        while(loop_flag){
        if((input(PIN_a0)==1)&& (menu==1)){ //Press enter to view sub menu
       screen=0;
       function_B();
        }
       break;
    }
    break;
   
   case 2:                         //Menu 3
       loop_flag=TRUE;
        while(loop_flag){
       if((input(PIN_a0)==1)&& (menu==2)){    //Press enter to view sub menu
       screen=0;
       function_C();
       }
       break;
     }
break;

//---------------------Exit MENU----------------------------------------------------//
 case 3:                       //Exit Main menu
       while(1){
       if((input(PIN_a0)==1)&& (menu==3)){
     
        lcd_putc("\f");  //clear lcd
        goto screen;
       }
     }
     break;
     default: break;
 }
        lcd_putc("\f");  //clear lcd
        goto screen1;    //go back to the main menu
 }
 
     
}}}}}



I added this line so that it can go back to the main menu so that it can act as a back key. But if removed the and left as before, it will go back to the home screen, so it can act as an escape key.

Code:

lcd_putc("\f");  //clear lcd
goto screen1;    //go back to the main menu


and this is how i managed to set the flag to get out of the sub menu:
Code:

void Function_A() {

lcd_putc("\fScn A (Function A)\n");
lcd_putc("Push tO RTn to menu");
while(input(Pin_D7)==0)
   loop_flag==False;
 
}



Once again thanks all.
colesha



Joined: 09 Jan 2012
Posts: 45

View user's profile Send private message Send e-mail

PostPosted: Tue Feb 18, 2020 4:06 pm     Reply with quote

Ttelmah wrote:
Your problem is this (and the other similar bits).
Code:

 switch(menu){
 case 0:                        //Menu 1
       while(1){
       //This instruction means 'loop for ever'
       if(input(PIN_a0)==1){      //Press enter to view sub menu
       //screen=0;
       function_A();
       //Function A exits, but you are still 'stuck' in the 'for ever' loop.....
       }
     }

//Consider instead:
int1 loop_flag; //global variable

 switch(menu){
 case 0:                        //Menu 1
       loop_flag=TRUE;
       while(loop_flag){
       if(input(PIN_a0)==1){      //Press enter to view sub menu
       //screen=0;
       function_A();
       }
     }

//Now if in function_A, when it exits, you set 'loop_flag=FALSE;' when
//it exits, it'll drop out of the loop.


Obviously you can use the same flag for all the functions and just add
the line to set this 'FALSE' when you want to drop out of the loop.

Hi once again Ttelmah, i need some additional assistance. I want to make another sub menu in a selected menu similar to the main menu. For example, when i press the menu button, it brings the main menu. Now at the main menu, say i select function B. When function B is opened, i can scroll through its sub menu, maybe function B1, etc just like the main menu. How do you go about it ? Do i need to copy the entire menu code into function B ?
Ttelmah



Joined: 11 Mar 2010
Posts: 19518

View user's profile Send private message

PostPosted: Wed Feb 19, 2020 3:20 am     Reply with quote

Ideally write the 'menu' into a function. Make it be called with an array
of the text, and return the selection number made. Then you can just
have a basic switch selecting the required function with the result of this.
Then you can just call this in each place you need a 'menu'. Smile
colesha



Joined: 09 Jan 2012
Posts: 45

View user's profile Send private message Send e-mail

PostPosted: Wed Feb 19, 2020 10:45 am     Reply with quote

Ttelmah wrote:
Ideally write the 'menu' into a function. Make it be called with an array
of the text, and return the selection number made. Then you can just
have a basic switch selecting the required function with the result of this.
Then you can just call this in each place you need a 'menu'. Smile


Hello, i just cant figure out this, kindly assist with some more guidance.
Display posts from previous:   
Post new topic   Reply to topic    CCS Forum Index -> General CCS C Discussion All times are GMT - 6 Hours
Page 1 of 1

 
Jump to:  
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum


Powered by phpBB © 2001, 2005 phpBB Group