Menu selection help

Hi all.
I was wondering if there was anyone out there able to figure out what I'm doing wrong with my code. I wouldn't call myself an expert by any stretch and am really struggling to complete this task.
I'm trying to program a simple menu selection screen on the serial monitor. It seems to be working fine up until the sub menu option process comes up. I can't get it to go through the sub menu and print the options within as selecting either 1, 2 or 3 loops back and displays the sub menu.
Any help would be appreciated.

Btw I only have one void submenu atm


int num = 0;
int subNum = 0;

void setup(){

// put your setup code here, to run once:

Serial.begin(9600);

mainMenu();

}

void loop(){

// put your main code here, to run repeatedly:

if (Serial.available() == 0){

}

num = Serial.parseInt();

if (num == 1){

Serial.println("Sub menu 1 selected");

subMenu1();

}else if(num == 2){

Serial.println("Sub menu 2 selected");

subMenu2();

}else if(num == 3){

Serial.println("Sub menu 3 selected");

subMenu3();

}else if(num == 4){

Serial.println("Sub menu 4 selected");

subMenu4();

}else if(num != 0){

Serial.println("Please select a valid option");

mainMenu();

}

}

void mainMenu(){

Serial.println("---Main Menu---");

Serial.println(" ");

Serial.println("Please select a sub menu");

Serial.println("Sub Menu 1");

Serial.println("Sub Menu 2");

Serial.println("Sub Menu 3");

Serial.println("Sub Menu 4");

Serial.println(" ");

}

void subMenu1(){

Serial.println("---Sub Menu 1---");

Serial.println(" ");

Serial.println("Please select a sub menu option");

Serial.println("Option 1");

Serial.println("Option 2");

Serial.println("Option 3");

Serial.println(" ");

}

void subMenu2(){

Serial.println("---Sub Menu 2---");

Serial.println(" ");

Serial.println("Please select a sub menu option");

Serial.println("Option 1");

Serial.println("Option 2");

Serial.println("Option 3");

Serial.println(" ");

}

void subMenu3(){

Serial.println("---Sub Menu 3---");

Serial.println(" ");

Serial.println("Please select a sub menu option");

Serial.println("Option 1");

Serial.println("Option 2");

Serial.println("Option 3");

Serial.println(" ");

}

void subMenu4(){

Serial.println("---Sub Menu 4---");

Serial.println(" ");

Serial.println("Please select a sub menu option");

Serial.println("Option 1");

Serial.println("Option 2");

Serial.println("Option 3");

Serial.println(" ");

}

void subMenu1Option() {

subNum = Serial.parseInt();

if (subNum == 1) {

Serial.println("Option 1 selected in Sub Menu 1");

} else if (subNum == 2) {

Serial.println("Option 2 selected in Sub Menu 1");

} else if (subNum == 3) {

Serial.println("Option 3 selected in Sub Menu 1");

} else if (subNum != 0) {

Serial.println("Invalid option in Sub Menu 1");

subMenu1();
}
}

Your loop() code has a several problems.

The main that you read the Serial regardless whether it buffer has a char or not. The line
if (Serial.available() == 0){ }
is absolutly useless.
You need to move the closing curly barcket to the end of the function, that Serial.available() condition indludes a whole loop() code, or replace the if with the while

The second problem is that using parseInt() method is a bad choice. Your Serial input supposed to be a single byte, so you could use it directly, without converting it to Int.

In general, I would recommend you read Serail_basic_tutorial (use a search in the forum) before you proceed.

so if nothing is available you don't do anything and right after that (probably still nothing is available) you try to parse an integer from the Serial input? The function will wait for a specific timeout (1s by default) and then return 0.

As your commands are only one char, you could do something very verbose like this:

byte menuLevel = 0;

void showMainMenu() {
  Serial.println(F("MAIN MENU"));
  Serial.println(F("1.\toption 1"));
  Serial.println(F("2.\toption 2"));
}

void showOption1() {
  Serial.println(F("OPTION 1"));
  Serial.println(F("1.\tcommand 1.1"));
  Serial.println(F("2.\tcommand 1.2"));
  Serial.println(F("3.\tback to main menu"));
}

void showOption2() {
  Serial.println(F("OPTION 2"));
  Serial.println(F("1.\tcommand 2.1"));
  Serial.println(F("2.\tcommand 2.2"));
  Serial.println(F("3.\tcommand 2.3"));
  Serial.println(F("4.\tback to main menu"));
}

void command11() {
  Serial.println(F("Command 1.1 done."));
}
void command12() {
  Serial.println(F("Command 1.2 done."));
}
void command21() {
  Serial.println(F("Command 2.1 done."));
}
void command22() {
  Serial.println(F("Command 2.2 done."));
}
void command23() {
  Serial.println(F("Command 2.3 done."));
}


void showMenu() {
  switch (menuLevel) {
    case 0: showMainMenu(); break;
    case 1: showOption1(); break;
    case 2: showOption2(); break;
    default: Serial.println("wrong menu level"); break;
  }
}

void testMenuInput() {
  int r = Serial.read(); // we get -1 if there is nothing to read otherwise we get the byte
  if ((r == -1) || isspace(r)) return; // ignore spaces, CR, LF, tab..

  switch (menuLevel) {
    case 0:
      switch (r) {
        case '1': menuLevel = 1; showMenu(); break;
        case '2': menuLevel = 2; showMenu(); break;
        default: Serial.println(F("------- wrong input ------- ")); showMenu(); break;
      }
      break;

    case 1:
      switch (r) {
        case '1': command11(); showMenu(); break;
        case '2': command12(); showMenu(); break;
        case '3': menuLevel = 0; showMenu(); break;
        default: Serial.println(F("------- wrong input ------- ")); showMenu(); break;
      }
      break;

    case 2:
      switch (r) {
        case '1': command21(); showMenu(); break;
        case '2': command22(); showMenu(); break;
        case '3': command23(); showMenu(); break;
        case '4': menuLevel = 0; showMenu(); break;
        default: Serial.println(F("------- wrong input ------- ")); showMenu(); break;
      }
      break;
    default:
      Serial.println("wrong menu level");
      break;
  }
}


void setup() {
  Serial.begin(115200);
  showMenu();
}

void loop() {
  testMenuInput();
}

this could be made much better with structures and arrays but that's a start you can probably easily read and understand.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.