// Include libraries
#include <Wire.h> // For I2C communication
#include <LiquidCrystal_I2C.h> // For LCD display
#include <LcdMenu.h> // For menu interface
#include <Encoder.h> // For encoder input
// Define pins
#define ENCODER_PIN_A 32 // Encoder pin A connected to digital pin 2
#define ENCODER_PIN_B 33 // Encoder pin B connected to digital pin 3
#define ENCODER_BUTTON_PIN 25 // Encoder button connected to digital pin 4
#define LCD_ADDRESS 0x27 // I2C address of LCD display
// Initialize objects
LiquidCrystal_I2C lcd(0x27, 16, 2); // Create LCD object
Encoder encoder(ENCODER_PIN_A, ENCODER_PIN_B); // Create encoder object
LcdMenu menu(&lcd, &encoder, ENCODER_BUTTON_PIN); // Create menu object
// Define variables
int option1 = 0; // Variable for option 1
int option2 = 0; // Variable for option 2
int option3 = 0; // Variable for option 3
// Function to initialize LCD display
void initLCD() {
lcd.init(); // Initialize LCD display
lcd.backlight(); // Turn on LCD backlight
}
// Function to initialize encoder
void initEncoder() {
pinMode(ENCODER_PIN_A, INPUT); // Set encoder pin A as input
pinMode(ENCODER_PIN_B, INPUT); // Set encoder pin B as input
pinMode(ENCODER_BUTTON_PIN, INPUT_PULLUP); // Set encoder button as input with internal pull-up resistor
}
// Function to initialize menu
void initMenu() {
menu.addMenu("Main Menu"); // Add main menu
menu.addMenu("Option 1"); // Add option 1 menu
menu.addMenu("Option 2"); // Add option 2 menu
menu.addMenu("Option 3"); // Add option 3 menu
menu.addMenuItem("Option 1", "Variable 1", &option1); // Add variable 1 to option 1 menu
menu.addMenuItem("Option 2", "Variable 2", &option2); // Add variable 2 to option 2 menu
menu.addMenuItem("Option 3", "Variable 3", &option3); // Add variable 3 to option 3 menu
}
// Function to update LCD display
void updateLCD() {
lcd.clear(); // Clear LCD display
lcd.setCursor(0, 0); // Set cursor to first row
lcd.print(menu.getCurrentMenu()); // Print current menu
lcd.setCursor(0, 1); // Set cursor to second row
lcd.print(menu.getCurrentMenuItem()); // Print current menu item
}
// Function to handle encoder input
void handleEncoder() {
int encoderValue = encoder.read(); // Read encoder value
if (encoderValue > 0) { // If encoder is rotated clockwise
menu.next(); // Move to next menu item
} else if (encoderValue < 0) { // If encoder is rotated counterclockwise
menu.previous(); // Move to previous menu item
}
if (digitalRead(ENCODER_BUTTON_PIN) == LOW) { // If encoder button is pressed
menu.select(); // Select current menu item
}
}
// Function to simulate encoder input
void simulateEncoder() {
int encoderValue = random(-1, 2); // Generate random encoder value (-1, 0, or 1)
if (encoderValue > 0) { // If encoder is rotated clockwise
menu.next(); // Move to next menu item
} else if (encoderValue < 0) { // If encoder is rotated counterclockwise
menu.previous(); // Move to previous menu item
}
if (random(0, 2) == 0) { // Randomly simulate encoder button press
menu.select(); // Select current menu item
}
}
// Function to simulate menu navigation
void simulateMenu() {
menu.next(); // Move to next menu item
delay(1000); // Wait 1 second
menu.select(); // Select current menu item
delay(1000); // Wait 1 second
}
// Main function
void setup() {
initLCD(); // Initialize LCD display
initEncoder(); // Initialize encoder
initMenu(); // Initialize menu
}
void loop() {
handleEncoder(); // Handle encoder input
updateLCD(); // Update LCD display
//simulateEncoder(); // Simulate encoder input
//simulateMenu(); // Simulate menu navigation
}
// Code sourced from:
// https://github.com/Chris--A/