#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// LCD setup
LiquidCrystal_I2C lcd(0x27, 20, 4); // Adjust I2C address if needed
// Rotary encoder pins
#define CLK_PIN 8
#define DT_PIN 9
#define SW_PIN 10
// LED pin
#define LED_PIN 7
// Variables for rotary encoder
int currentStateCLK;
int lastStateCLK;
int currentStateSW;
int lastStateSW = HIGH;
int menuIndex = 0;
// Menu options
const char* menuOptions[] = {
"1. LED ON",
"2. LED OFF"
};
const int menuSize = sizeof(menuOptions) / sizeof(menuOptions[0]);
void setup() {
// Initialize LCD
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("Rotary Menu Demo");
// Initialize rotary encoder pins
pinMode(CLK_PIN, INPUT);
pinMode(DT_PIN, INPUT);
pinMode(SW_PIN, INPUT_PULLUP);
// Initialize LED pin
pinMode(LED_PIN, OUTPUT);
// Read initial state of CLK
lastStateCLK = digitalRead(CLK_PIN);
// Display initial menu
displayMenu();
}
void loop() {
// Handle rotary encoder rotation
currentStateCLK = digitalRead(CLK_PIN);
if (currentStateCLK != lastStateCLK && currentStateCLK == HIGH) {
// Check direction
if (digitalRead(DT_PIN) != currentStateCLK) {
menuIndex++;
} else {
menuIndex--;
}
// Wrap around menu index
if (menuIndex < 0) menuIndex = menuSize - 1;
if (menuIndex >= menuSize) menuIndex = 0;
// Update menu display
displayMenu();
}
lastStateCLK = currentStateCLK;
// Handle button press
currentStateSW = digitalRead(SW_PIN);
if (currentStateSW == LOW && lastStateSW == HIGH) {
// Execute selected menu option
executeOption(menuIndex);
}
lastStateSW = currentStateSW;
}
void displayMenu() {
lcd.clear();
for (int i = 0; i < menuSize; i++) {
lcd.setCursor(0, i);
if (i == menuIndex) {
lcd.print("> "); // Highlight selected option
} else {
lcd.print(" ");
}
lcd.print(menuOptions[i]);
}
}
void executeOption(int index) {
switch (index) {
case 0:
digitalWrite(LED_PIN, HIGH); // Turn LED on
lcd.setCursor(0, 3);
lcd.print("LED is ON ");
break;
case 1:
digitalWrite(LED_PIN, LOW); // Turn LED off
lcd.setCursor(0, 3);
lcd.print("LED is OFF");
break;
}
}