|
|
View previous topic :: View next topic |
Author |
Message |
colesha
Joined: 09 Jan 2012 Posts: 45
|
Failure to come out of the loop from a sub menu |
Posted: Fri Feb 14, 2020 5:57 am |
|
|
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
|
|
Posted: Fri Feb 14, 2020 6:33 am |
|
|
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
|
|
Posted: Fri Feb 14, 2020 7:49 am |
|
|
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
|
|
Posted: Fri Feb 14, 2020 8:14 am |
|
|
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
|
|
Posted: Fri Feb 14, 2020 8:24 am |
|
|
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
|
|
Posted: Fri Feb 14, 2020 8:27 am |
|
|
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: 19506
|
|
Posted: Fri Feb 14, 2020 9:19 am |
|
|
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
|
|
Posted: Fri Feb 14, 2020 2:20 pm |
|
|
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
|
|
Posted: Tue Feb 18, 2020 4:06 pm |
|
|
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: 19506
|
|
Posted: Wed Feb 19, 2020 3:20 am |
|
|
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'. |
|
|
colesha
Joined: 09 Jan 2012 Posts: 45
|
|
Posted: Wed Feb 19, 2020 10:45 am |
|
|
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'. |
Hello, i just cant figure out this, kindly assist with some more guidance. |
|
|
|
|
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
|