You make a menu on an Arduino Nano by doing two things:
- Decide where the menu is shown (Serial Monitor? LCD? OLED?).
- Write a simple state machine that reacts to user input and changes “screens”.
Let me show you a very clear example using the Serial Monitor (no extra hardware needed), then briefly how you’d adapt it to an LCD + buttons.
1. Serial Monitor menu (simplest way)
Idea
- Show a text menu in the Serial Monitor.
- The user presses keys like 1, 2, 3…
- The code runs different actions based on that input.
We’ll build a menu like this:
- 1 → Blink LED
- 2 → Read analog value from A0
- 3 → Go into a small “settings” submenu
- b → Back to main menu when in submenu
Wiring
For this basic example:
No extra wiring needed.
- Use the built-in LED on pin 13 (LED_BUILTIN)
- Optionally connect a potentiometer to A0:
- One side → 5V
- Other side → GND
- Middle pin → A0
Full example code
// Simple menu for Arduino Nano via Serial Monitor
enum MenuState {
MENU_MAIN,
MENU_SETTINGS
};
MenuState currentMenu = MENU_MAIN;
const int ledPin = LED_BUILTIN;
const int analogPin = A0;
void setup() {
pinMode(ledPin, OUTPUT);
Serial.begin(9600);
while (!Serial) {
; // Wait for Serial on some boards (not strictly needed on Nano)
}
Serial.println(F("=== Arduino Nano Menu Demo ==="));
printMainMenu();
}
void loop() {
// Check if the user entered something
if (Serial.available() > 0) {
char c = Serial.read();
// Ignore line endings
if (c == '\n' || c == '\r') {
return;
}
if (currentMenu == MENU_MAIN) {
handleMainMenuInput(c);
} else if (currentMenu == MENU_SETTINGS) {
handleSettingsMenuInput(c);
}
}
}
// ---------------- Main Menu ----------------
void printMainMenu() {
Serial.println();
Serial.println(F("===== MAIN MENU ====="));
Serial.println(F("1) Blink LED once"));
Serial.println(F("2) Read analog A0"));
Serial.println(F("3) Settings submenu"));
Serial.println(F("x) Stop LED (turn off)"));
Serial.print(F("Select option: "));
}
void handleMainMenuInput(char choice) {
switch (choice) {
case '1':
Serial.println(F("\n[Blink] LED will blink once."));
blinkLedOnce();
printMainMenu();
break;
case '2':
Serial.println(F("\n[Analog] Reading A0..."));
readAnalogOnce();
printMainMenu();
break;
case '3':
Serial.println(F("\n[Settings] Entering settings menu."));
currentMenu = MENU_SETTINGS;
printSettingsMenu();
break;
case 'x':
case 'X':
Serial.println(F("\n[LED] Turning LED off."));
digitalWrite(ledPin, LOW);
printMainMenu();
break;
default:
Serial.println(F("\n[Error] Invalid choice."));
printMainMenu();
break;
}
}
// ---------------- Settings Menu ----------------
void printSettingsMenu() {
Serial.println();
Serial.println(F("===== SETTINGS MENU ====="));
Serial.println(F("a) Turn LED ON"));
Serial.println(F("b) Back to main menu"));
Serial.print(F("Select option: "));
}
void handleSettingsMenuInput(char choice) {
switch (choice) {
case 'a':
case 'A':
Serial.println(F("\n[Settings] LED is now ON."));
digitalWrite(ledPin, HIGH);
printSettingsMenu();
break;
case 'b':
case 'B':
Serial.println(F("\n[Settings] Returning to main menu."));
currentMenu = MENU_MAIN;
printMainMenu();
break;
default:
Serial.println(F("\n[Error] Invalid choice in settings."));
printSettingsMenu();
break;
}
}
// ---------------- Helper functions ----------------
void blinkLedOnce() {
digitalWrite(ledPin, HIGH);
delay(300);
digitalWrite(ledPin, LOW);
delay(300);
}
void readAnalogOnce() {
int raw = analogRead(analogPin);
float voltage = raw * (5.0 / 1023.0);
Serial.print(F("Raw A0 = "));
Serial.print(raw);
Serial.print(F(" | Voltage ≈ "));
Serial.print(voltage, 2);
Serial.println(F(" V"));
}
How to use it
- Upload the sketch to your Arduino Nano.
- Open Serial Monitor (Ctrl+Shift+M).
- Set baud rate to 9600.
- You’ll see the MAIN MENU.
- Type 1, 2, 3, x, a, b, etc. and press Enter.
You just built a simple text-based menu system with:
- A main menu
- A submenu
- Different actions for each item
2. How to turn this into an LCD + buttons menu
Once you have the state machine idea, moving to an LCD is just about changing I/O:
- Instead of Serial.print(...) → use lcd.print(...) with the LiquidCrystal library.
- Instead of reading Serial.read() → read buttons:
- “UP” button → decrease menu index
- “DOWN” button → increase menu index
- “SELECT” button → choose current item
Pseudo-logic:
int menuIndex = 0;
const int menuCount = 3;
void loop() {
if (buttonUpPressed()) {
menuIndex--;
if (menuIndex < 0) menuIndex = menuCount - 1;
drawMenu();
}
if (buttonDownPressed()) {
menuIndex++;
if (menuIndex >= menuCount) menuIndex = 0;
drawMenu();
}
if (buttonSelectPressed()) {
runMenuItem(menuIndex);
}
}
Where:
- drawMenu() redraws text on the LCD,
- runMenuItem() runs the selected action.
3. Key takeaway
A menu on Arduino Nano is just:
- A current state (MENU_MAIN, MENU_SETTINGS, or a menuIndex)
- A way to print that state (Serial, LCD, OLED)
- A way to read user input (Serial characters, buttons, encoder)
- A switch / if block that runs different code for each choice

Top comments (0)