Serial Menu Issues

Hi guys! I am trying to build a motor tester for my dual motor controller smartcar projects. I have the algorithm figured out for this, but am having trouble understanding why I can't get the menu's to work.

Here is the code. I cannot get the mainMenu() to not just loop like crazy. I want to hit 'Q' and the mainMenu() comes up just once after a user presses 'Q'. I tried the runOnce scheme, but then it only runs properly once. I cant find any in-between!

/*  Run this program with the Serial Monitor Open for Menu Choices. If the wheels 
 *  are not turning in the direction they are supposed to, swap the red and black
 *  wires on the motors themselves. This an essential starting place for the main
 *  program to work as expected. Do not be tempted to change the software because
 *  although that works, it reverses the variables in the program later in the code.
 *  
 *  Orientation is described the same as a passenger car. 
 *  Passenger Side = Right Side
 *  Drivers Side = Left Side */

/* Right Rear Motor Number One*/
const int enableA_RR = 44;  /* Must be PWM (pins 2 through 13,44-46 on Mega) */
const int in1 = 38;         /* Each IN pin sets up the Digital Matrix        */
const int in2 = 39;         /* for forward and reverse motor rotation        */
float motorSpeed_RR;    /* Variable for the Right Rear Motors Speed      */

/* Left Rear Motor Number Two */
const int enableB_LR = 45;  /* Must be PWM (pins 2 through 13,44-46 on Mega) */
const int in3 = 40;         /* Each IN pin sets up the Digital Matrix        */
const int in4 = 41;         /* for forward and reverse motor rotation        */
float motorSpeed_LR;        /* Variable for the Left Rear Motors Speed       */

/* Right Front Motor Number Three */
const int enableC_RF = 46;  /* Must be PWM (pins 2 through 13,44-46 on Mega) */
const int in5 = 47;         /* Each IN pin sets up the Digital Matrix        */
const int in6 = 48;         /* for forward and reverse motor rotation        */
float motorSpeed_RF;        /* Variable for the Right Front Motors Speed     */

/* Left Front Motor Number Four */
const int enableD_LF = 2;   /* Must be PWM (pins 2 through 13,44-46 on Mega) */
const int in7 = 34;         /* Each IN pin sets up the Digital Matrix        */
const int in8 = 35;         /* for forward and reverse motor rotation        */
float motorSpeed_LF;        /* Variable for the Left Front Motors Speed      */

char menu;
int subMenu;
bool runOnce = true;

void setup() {
  Serial.begin(115200);  
  pinMode (enableA_RR, OUTPUT);      /* Both enable A(black wire) and B(red wire) are from the first    */
  pinMode (enableB_LR, OUTPUT);      /* module located on the long connector at the front of the module */
  pinMode (enableC_RF, OUTPUT);      /* Both enable C(black wire) and D(red wire) are from the second   */                            
  pinMode (enableD_LF, OUTPUT);      /* module located on the long connector at the front of the module */
  pinMode (in1, OUTPUT);
  pinMode (in2, OUTPUT);             /* in1 and in2 are enabled by enableA-RR (Right Rear) */  
  pinMode (in3, OUTPUT);             
  pinMode (in4, OUTPUT);             /* in3 and in4 are enabled by enableB-LR (Left Rear)  */ 
  pinMode (in5, OUTPUT);
  pinMode (in6, OUTPUT);             /* in5 and in6 are enabled by enableC-RF (Right Front)*/
  pinMode (in7, OUTPUT);
  pinMode (in8, OUTPUT);             /* in7 and in8 are enabled by enableD-LF (Left Front) */
  mainMenu();
  
}

void mainMenu() {
  Serial.println ("     <>*<>*<>*<>*<>*     Menu Options        *<>*<>*<>*<>*<>   ");
  Serial.println ("1)Right Rear  2)Left Rear  3)Right Front  4)Left Front  5) ALL ");
}

void myExit(){
  if (menu != '1' || menu != '2' || menu != '3' || menu != '4' || menu != '5') {
  Serial.println ("Choose Options 1 through 5");
  }
}

void loop() {
  if (Serial.available() > 0) {
      menu = Serial.read();
      
  }
  switch (menu) {
    runOnce = true;
    case '1': {      
      Serial.println("1) Forward   2) Reverse  Q) QUIT"); //prompt user for position
      while (Serial.available()==0) {} //wait for user input
      subMenu = Serial.read();     
         
      if (subMenu == '1') {
        
          motorSpeed_RR = 255; 
          digitalWrite (in1, LOW);
          digitalWrite (in2, HIGH);
          analogWrite (enableA_RR, motorSpeed_RR);
      }
      else if (subMenu == '2') {
        motorSpeed_RR = 255; 
          digitalWrite (in1, HIGH);
          digitalWrite (in2, LOW);
          analogWrite (enableA_RR, motorSpeed_RR);
      }
      else if (subMenu == 'Q' || subMenu == 'q') {
        motorSpeed_RR = 0; 
        analogWrite (enableA_RR, motorSpeed_RR);      
        menu = 'Q';
      }
      break;
    } // end case '1'  
  
    case 'Q' : case 'q' : {     
     while (runOnce == true) {
      mainMenu(); 
      runOnce = false;
     }
    break;     
    } //end case Q    
  } //end switch
} // end loop

Any help would be appreciated. Thanks again!

Don't you want the switch/case inside the same conditional as the Serial.read?

I'm not sure how to go about this. The void setup brings the menu up once, then after the sub menu takes over, I cant seem to figure out how to return back to the main menu and have it only display once. Right now, everything works unless you try more than twice to use Case 1.

You need more than one main menu state. You need the submenus to go to the "display main menu" state. That state only runs once before going to the "main menu is waiting for the user" state.

How would that look different? Anytime I put mainMenu() anywhere in the loop, it just repeats itself. I can't think of a loop that would make it run one time BEFORE the user input. Menus are very confusing. If there were a such thing as mainMenuOFF what would trigger it?

I got it. All I had to do was move the runOnce = true; at the top of the loop to just under menu= Serial.read.

I would however, love to hear more coherent ideas on how to go about structuring menus and submenus. Thanks to all who commented and those who just shook their head!

At their very simplest, menus can just be a hierarchy of functions