LCD Menu Bugs/Glitches

So I recently got an LCD display shield and wanted to use it to have a menu that can run multiple programs for this robot (Depending on what the user wants) The issue I’m running into is that some of my menu options don’t work properly, I tried overwriting my changes with the default code

void displayMenu(int x) {
     switch (x) {
      case 1:
        clearPrintTitle();
        lcd.print ("-> Menu Option 1");
        break;
      case 2:
        clearPrintTitle();
        lcd.print ("-> Menu Option 2");
        break;
       case 3:
        clearPrintTitle();
        lcd.print ("-> Menu Option 3");
        break;
      case 4:
        clearPrintTitle();
        lcd.print ("-> Menu Option 4");
        break;
    }
}
 
//Print a basic header on Row 1.
void clearPrintTitle() {
  lcd.clear();
  lcd.setCursor(0,0);
  lcd.print(" HACKSHED.CO.UK ");
  lcd.setCursor(0,1);
}
 
//Show the selection on Screen.
void selectMenu(int x) {
   switch (x) {
      case 1:
        clearPrintTitle();
        lcd.print ("Selected Opt 1");
        //Call the function that belongs to Option 1
        break;
      case 2:
        clearPrintTitle();
        lcd.print ("Selected Opt 2");
        //Call the function that belongs to Option 2
        break;
       case 3:
        clearPrintTitle();
        lcd.print ("Selected Opt 3");
        //Call the function that belongs to Option 3
        break;
      case 4:
        clearPrintTitle();
        lcd.print ("Selected Opt 4");
        //Call the function that belongs to Option 4
        break;
    }
}

(Hopefully the important parts of the code I was basing my code off of since I ran into character limit issues)

More specifically at the bottom where it actually runs a function. When I replace my added code with all the default results from the menu it worked as intended so I’m assuming it has something to do with the way I’ve coded it. When I replace just case 1 with the default code case 2 works but case 3 and 4 stay on the menu when I press select.

#include <LiquidCrystal.h>
#include <Servo.h>

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

int currentMenuItem = 0;
int lastState = 0;
int encounters = 0;
int value;

int someDegrees =   0; //delete these later
int somemoreDegrees = 0; // delete these later

const int pResistor = A8;
const int rgbRed = 30;
const int rgbBlue = 32;
const int rgbGreen = 34;

Servo resetServo;
Servo lrServo;
Servo runServo;
Servo abServo;
Servo xyServo;

void pressA() {
  abServo.write(someDegrees);
  delay(200);
  abServo.write(somemoreDegrees);
}

void pressB() {
  abServo.write(someDegrees);
  delay(200);
  abServo.write(somemoreDegrees);
}

void pressX() {
  abServo.write(someDegrees);
  delay(200);
  abServo.write(somemoreDegrees);
}

void pressY() {
  xyServo.write(someDegrees);
  delay(200);
  xyServo.write(somemoreDegrees);
}

void resetGame() {
  resetServo.write(0);
  delay(200);
  resetServo.write(90);
}

void setup() {
  Serial.begin(9600);
  pinMode(rgbRed, OUTPUT);
  pinMode(rgbGreen, OUTPUT);
  pinMode(rgbBlue, OUTPUT);
  pinMode(pResistor, INPUT);
  lrServo.attach(36);
  runServo.attach(38);
  resetServo.attach(40);
  abServo.attach(42);
  xyServo.attach(44);
  lcd.begin(16, 2);
  clearPrintTitle();
}

void loop() {
mainMenu();
}

void photoRead() {
  value = analogRead(pResistor);
  Serial.println(value);
}

void shinyPokemon() {
 int dasaShiny = 1;
  while (dasaShiny == 1) {
    digitalWrite(rgbRed, HIGH);
    digitalWrite(rgbGreen, LOW);
    digitalWrite(rgbBlue, LOW);
    delay(300);
    digitalWrite(rgbRed, LOW);
    digitalWrite(rgbGreen, HIGH);
    digitalWrite(rgbBlue, LOW);
    delay(300);
    digitalWrite(rgbRed, LOW);
    digitalWrite(rgbGreen, LOW);
    digitalWrite(rgbBlue, HIGH);
    delay(300);
    digitalWrite(rgbRed, HIGH);
    digitalWrite(rgbGreen, HIGH);
    digitalWrite(rgbBlue, LOW);
    delay(300);
    digitalWrite(rgbRed, LOW);
    digitalWrite(rgbGreen, HIGH);
    digitalWrite(rgbBlue, HIGH);
    delay(300);
    digitalWrite(rgbRed, HIGH);
    digitalWrite(rgbGreen, LOW);
    digitalWrite(rgbBlue, HIGH);
    delay(300);
    digitalWrite(rgbRed, HIGH);
    digitalWrite(rgbGreen, HIGH);
    digitalWrite(rgbBlue, HIGH);
    delay(300);
  }
}

void mainMenu() {
int state = 0;
int x = analogRead (0);
lcd.setCursor(0,0);

if (x < 100) {/*Right*/} 
else if (x < 200) {state = 1;} //Up 
else if (x < 400){state = 2;} //Down
else if (x < 600){/*Left*/} 
else if (x < 800){state = 3;} //Select

if (currentMenuItem < 0 || currentMenuItem > 4) {
currentMenuItem = 0;
}

if (state != lastState) {
  if (state == 1) {
    currentMenuItem = currentMenuItem - 1;
    displayMenu(currentMenuItem);
    } 
  
  else if (state == 2) {
    currentMenuItem = currentMenuItem + 1;
    displayMenu(currentMenuItem);
    }
  
  else if (state == 3) {
    selectMenu(currentMenuItem);
    }
lastState = state;
}
delay(5);
}

void displayMenu(int x) {
switch (x) {
case 1:
clearPrintTitle();
lcd.print ("-> Friend Safari");
break;
case 2:
clearPrintTitle();
lcd.print ("-> Portal SRs");
break;
case 3:
clearPrintTitle();
lcd.print ("-> Servo 0s");
break;
case 4:
clearPrintTitle();
lcd.print ("-> ORAS Starter");
break;
}
}

void clearPrintTitle() {
lcd.clear();
lcd.setCursor(0,0);
lcd.print("vulcBot");
lcd.setCursor(0,1);
}

//Show the selection on screen.
void selectMenu(int x) {
switch (x) {
case 1:
clearPrintTitle();
lcd.print ("Encounters: 0");
int optOne = 1;
while (optOne == 1) {
  photoRead();
  while (value > 10) {
    photoRead();
    lrServo.write(75);
    photoRead();
    delay(400);
    photoRead();
    lrServo.write(35);
    photoRead();
    delay(400);
    }
    clearPrintTitle();
    encounters ++;
    lcd.print("Encounters: ");
    lcd.print(encounters);
    delay(11300);
    value = analogRead(pResistor);
    if (value > 10) {
    runServo.write(0);
    delay(1000);
    runServo.write(90);
    delay(6500);
  }
  else {optOne = 0;}
}
shinyPokemon();
break;

case 2:
clearPrintTitle();
lcd.print ("Encounters: 0");
int optTwo = 1;
while (optTwo == 1) {
  //Skip Groudon, Enter Game, Open Portal, Open second text, confirm going into portal, Wait for shiny, SR or shinyPokemon()
  abServo.write(75);
  delay(250);
  abServo.write(60);
  delay(4000);
  //Skipped Groudon
  abServo.write(75);
  delay(250);
  abServo.write(60);
  delay(3000);
  //Game loaded infront of portal
  abServo.write(75);
  delay(250);
  abServo.write(60);
  delay(1000);
  //Talked to Portal
  abServo.write(75);
  delay(250);
  abServo.write(60);
  delay(1000);
  //Opened next menu
  abServo.write(75);
  delay(250);
  abServo.write(60);
  //Started encounter
  delay(11050);
  photoRead();
  if (value > 200) {
    resetServo.write(0);
    delay(500);
    resetServo.write(90);
    delay(11500);
  }
  else {optTwo = 0;}
}
shinyPokemon();
break;

case 3:
clearPrintTitle();
lcd.print ("Selected Opt 3");
resetServo.write(0);
lrServo.write(0);
runServo.write(0);
abServo.write(0);
xyServo.write(0);
Serial.println("Test");
delay(20000);
break;

case 4:
clearPrintTitle();
lcd.print ("Selected Opt 4");
break;
    }
  }

Any idea why this may be? With the code as is, I can select Case 1 from the menu (Aka “Friend Safari”) but the other 3 just stay on the menu when I try to select them.

I’m using an Arduino mega board if that means anything, my best guess is to just take the working version and slowly add my non-working version to try and isolate the issue, but if there’s a better method I’m very open to help

EDIT:

Replaced Case 2 with

case 2:
clearPrintTitle();
lcd.print ("Selected Opt 2");
break;

Case 1 worked, Case 2, 3, and 4 didn’t

Undid that and made Case 1

case 1:
clearPrintTitle();
lcd.print ("Selected Opt 1");
break;

Case 1 and 2 worked, Case 3 and 4 didn’t.

Made all cases into

      case 1:
        clearPrintTitle();
        lcd.print ("Selected Opt 1");
        //Call the function that belongs to Option 1
        break;
      case 2:
        clearPrintTitle();
        lcd.print ("Selected Opt 2");
        //Call the function that belongs to Option 2
        break;
       case 3:
        clearPrintTitle();
        lcd.print ("Selected Opt 3");
        //Call the function that belongs to Option 3
        break;
      case 4:
        clearPrintTitle();
        lcd.print ("Selected Opt 4");
        //Call the function that belongs to Option 4
        break;

And all 4 worked, I’m so confused

void shinyPokemon() {
 int dasaShiny = 1;
  while (dasaShiny == 1) {

Nothing in the while body changes the value in dasaShiny, so, if you ever call this function, it will be a very long time before it returns. Somewhere about the 12th of Never.

I can't make heads or tails of your poorly indented snippets. Post ALL of your code, AFTER using Tools + Auto Format to properly indent it.

The stickies define how to post the code when it exceeds the 9500 character limit.

PaulS:

void shinyPokemon() {

int dasaShiny = 1;
 while (dasaShiny == 1) {



Nothing in the while body changes the value in dasaShiny, so, if you ever call this function, it will be a very long time before it returns. Somewhere about the 12th of Never.

I can't make heads or tails of your poorly indented snippets. Post ALL of your code, AFTER using Tools + Auto Format to properly indent it.

The stickies define how to post the code when it exceeds the 9500 character limit.

That’s the point of my code, You select from the 4 menu options, depending on your choice it repeats 1/4 options until it finds a rare occurence which makes an RGB LED change various colors for the end of time until I come back and do what I need to do. Below is my auto-formatted code, I can’t find the sticky you’re referring to, I was looking in all the guides and whatnot but didn’t see anything that talked about the character limit

#include <LiquidCrystal.h>
#include <Servo.h>

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

int currentMenuItem = 0;
int lastState = 0;
int encounters = 0;
int value;

int someDegrees =   0; //delete these later
int somemoreDegrees = 0; // delete these later

const int pResistor = A8;
const int rgbRed = 30;
const int rgbBlue = 32;
const int rgbGreen = 34;

Servo resetServo;
Servo lrServo;
Servo runServo;
Servo abServo;
Servo xyServo;

void pressA() {
  abServo.write(someDegrees);
  delay(200);
  abServo.write(somemoreDegrees);
}

void pressB() {
  abServo.write(someDegrees);
  delay(200);
  abServo.write(somemoreDegrees);
}

void pressX() {
  abServo.write(someDegrees);
  delay(200);
  abServo.write(somemoreDegrees);
}

void pressY() {
  xyServo.write(someDegrees);
  delay(200);
  xyServo.write(somemoreDegrees);
}

void resetGame() {
  resetServo.write(0);
  delay(200);
  resetServo.write(90);
}

void setup() {
  Serial.begin(9600);
  pinMode(rgbRed, OUTPUT);
  pinMode(rgbGreen, OUTPUT);
  pinMode(rgbBlue, OUTPUT);
  pinMode(pResistor, INPUT);
  lrServo.attach(36);
  runServo.attach(38);
  resetServo.attach(40);
  abServo.attach(42);
  xyServo.attach(44);
  lcd.begin(16, 2);
  clearPrintTitle();
}

void loop() {
  mainMenu();
}

void photoRead() {
  value = analogRead(pResistor);
  Serial.println(value);
}

void shinyPokemon() {
  int dasaShiny = 1;
  while (dasaShiny == 1) {
    digitalWrite(rgbRed, HIGH);
    digitalWrite(rgbGreen, LOW);
    digitalWrite(rgbBlue, LOW);
    delay(300);
    digitalWrite(rgbRed, LOW);
    digitalWrite(rgbGreen, HIGH);
    digitalWrite(rgbBlue, LOW);
    delay(300);
    digitalWrite(rgbRed, LOW);
    digitalWrite(rgbGreen, LOW);
    digitalWrite(rgbBlue, HIGH);
    delay(300);
    digitalWrite(rgbRed, HIGH);
    digitalWrite(rgbGreen, HIGH);
    digitalWrite(rgbBlue, LOW);
    delay(300);
    digitalWrite(rgbRed, LOW);
    digitalWrite(rgbGreen, HIGH);
    digitalWrite(rgbBlue, HIGH);
    delay(300);
    digitalWrite(rgbRed, HIGH);
    digitalWrite(rgbGreen, LOW);
    digitalWrite(rgbBlue, HIGH);
    delay(300);
    digitalWrite(rgbRed, HIGH);
    digitalWrite(rgbGreen, HIGH);
    digitalWrite(rgbBlue, HIGH);
    delay(300);
  }
}

void mainMenu() {
  int state = 0;
  int x = analogRead (0);
  lcd.setCursor(0, 0);

  if (x < 100) {
    /*Right*/
  }
  else if (x < 200) {
    state = 1; //Up
  }
  else if (x < 400) {
    state = 2; //Down
  }
  else if (x < 600) {
    /*Left*/
  }
  else if (x < 800) {
    state = 3; //Select
  }

  if (currentMenuItem < 0 || currentMenuItem > 4) {
    currentMenuItem = 0;
  }

  if (state != lastState) {
    if (state == 1) {
      currentMenuItem = currentMenuItem - 1;
      displayMenu(currentMenuItem);
    }

    else if (state == 2) {
      currentMenuItem = currentMenuItem + 1;
      displayMenu(currentMenuItem);
    }

    else if (state == 3) {
      selectMenu(currentMenuItem);
    }
    lastState = state;
  }
  delay(5);
}

void displayMenu(int x) {
  switch (x) {
    case 1:
      clearPrintTitle();
      lcd.print ("-> Friend Safari");
      break;
    case 2:
      clearPrintTitle();
      lcd.print ("-> Portal SRs");
      break;
    case 3:
      clearPrintTitle();
      lcd.print ("-> Hoardes");
      break;
    case 4:
      clearPrintTitle();
      lcd.print ("-> ORAS Starter");
      break;
  }
}

void clearPrintTitle() {
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("vulcBot");
  lcd.setCursor(0, 1);
}

//Show the selection on screen.
void selectMenu(int x) {
  switch (x) {
    case 1:
      clearPrintTitle();
      lcd.print ("Encounters: 0");
      int optOne = 1;
      while (optOne == 1) {
        photoRead();
        while (value > 10) {
          photoRead();
          lrServo.write(75);
          photoRead();
          delay(400);
          photoRead();
          lrServo.write(35);
          photoRead();
          delay(400);
        }
        clearPrintTitle();
        encounters ++;
        lcd.print("Encounters: ");
        lcd.print(encounters);
        delay(11300);
        value = analogRead(pResistor);
        if (value > 10) {
          runServo.write(0);
          delay(1000);
          runServo.write(90);
          delay(6500);
        }
        else {
          optOne = 0;
        }
      }
      shinyPokemon();
      break;

    case 2:
      clearPrintTitle();
      lcd.print ("Encounters: 0");
      int optTwo = 1;
      while (optTwo == 1) {
        //Skip Groudon, Enter Game, Open Portal, Open second text, confirm going into portal, Wait for shiny, SR or shinyPokemon()
        abServo.write(75);
        delay(250);
        abServo.write(60);
        delay(4000);
        //Skipped Groudon
        abServo.write(75);
        delay(250);
        abServo.write(60);
        delay(3000);
        //Game loaded infront of portal
        abServo.write(75);
        delay(250);
        abServo.write(60);
        delay(1000);
        //Talked to Portal
        abServo.write(75);
        delay(250);
        abServo.write(60);
        delay(1000);
        //Opened next menu
        abServo.write(75);
        delay(250);
        abServo.write(60);
        //Started encounter
        delay(11050);
        photoRead();
        if (value > 200) {
          resetServo.write(0);
          delay(500);
          resetServo.write(90);
          delay(11500);
        }
        else {
          optTwo = 0;
        }
      }
      shinyPokemon();
      break;

    case 3:
      clearPrintTitle();
      lcd.print ("Selected Opt 3");
      break;
    case 4:
      clearPrintTitle();
      lcd.print ("Selected Opt 4");
      break;
  }
}
void photoRead() {
  value = analogRead(pResistor);
  Serial.println(value);
}

This function really shouldn't manipulate a global variable. It should return a value.

  int x = analogRead (0);

You gave analog pin 0 a nice name, and you wrote a function to read that pin. Why are you not using that name, or function, here?

What does x mean to you? It doesn't mean anything to me. The name holding the value should reflect what is connected to the pin.

PaulS:

void photoRead() {

value = analogRead(pResistor);
  Serial.println(value);
}



This function really shouldn't manipulate a global variable. It should return a value.



int x = analogRead (0);



You gave analog pin 0 a nice name, and you wrote a function to read that pin. Why are you not using that name, or function, here?

What does x mean to you? It doesn't mean anything to me. The name holding the value should reflect what is connected to the pin.

X doesn't mean anything to me either, I'll change that to something more meaningful, I copy and pasted the menu code from a website and they used x to read the button values off my LCD Button Shield

I'm assuming you made a typo and meant I gave Analog Pin 8 a nice name, Yet again this is because I used code I copy and pasted and that's just what they used, I'll change both of those things.

I really do appreciate the pointers but do you see anything that could cause my menu not to work (I'm assuming it's something to do with my case 1-4 code execution just based on trying to debug)