#include <LiquidCrystal_I2C.h> // Library for LCD I2C
#include <RotaryEncoder.h> // Library for rotary encoder
// LCD configuration (address: 0x27, columns: 16, rows: 4)
LiquidCrystal_I2C lcd(0x27, 16, 4);
// Rotary encoder pin configuration
#define CLK_PIN 2
#define DT_PIN 3
#define SW_PIN 4
// Initialize rotary encoder
RotaryEncoder encoder(CLK_PIN, DT_PIN);
// Menu variables
int menuLevel = 0; // Current menu level
int menuIndex = 0; // Selected menu item
int lastPosition = -1; // Previous encoder position
int studentCount = 220; // Default student count
bool editingStudents = false; // Editing student count mode
// Main menu
const char *mainMenu[] = {"Univ Batna 1", "Univ Batna 2"};
const int mainMenuSize = 2;
// Faculties for each university
const char *univBatna1Faculties[] = {"Lettres & Philo", "Economie"};
const int univBatna1FacultiesSize = 2;
const char *univBatna2Faculties[] = {"Biologie", "Sciences & Technology", "Informatique"};
const int univBatna2FacultiesSize = 3;
// Departments for each university
const char *univBatna1Departments[] = {"Dept: Lettres", "Dept: Economie"};
const int univBatna1DepartmentsSize = 2;
const char *univBatna2Departments[] = {"Dept: Biologie", "Dept: Informatique", "Dept: elt", "Dept: Eln"};
const int univBatna2DepartmentsSize = 4;
// Specialties for departments
const char *univBatna1LettresSpecialties[] = {"Spec: Lettres", "Spec: Linguistique", "Spec: Philosophie"};
const char *univBatna1EconomieSpecialties[] = {"Spec: Economie", "Spec: Gestion"};
const char *univBatna2BiologieSpecialties[] = {"Spec: Biotech", "Spec: Environnement", "Spec: Biochimie"};
const char *univBatna2InformatiqueSpecialties[] = {"Spec: Réseaux", "Spec: IA", "Spec: Développement"};
const char *univBatna2ElectroniqueSpecialties[] = {"Spec: Microeln", "Spec: Systèmes Emb", "Spec: Automatique"};
const char *univBatna2MecaSpecialties[] = {"Spec: Mécanique", "Spec: Mécatronique", "Spec: Aéronautique"};
// Current menu tracking
int currentMenuSize = mainMenuSize;
const char **currentMenu = mainMenu;
void setup() {
// Pin configuration
pinMode(SW_PIN, INPUT_PULLUP);
// Initialize LCD
lcd.init();
lcd.backlight();
lcd.clear(); // Initialize menu variables
menuIndex = 0;
currentMenu = mainMenu;
currentMenuSize = mainMenuSize;
// Display initial menu
updateScreen();
}
void loop() {
encoder.tick();
int newPosition = encoder.getPosition();
if (editingStudents) {
// Adjust the student count while in editing mode
if (newPosition != lastPosition) {
if (newPosition > lastPosition) {
studentCount++;
} else {
studentCount--;
}
studentCount = max(studentCount, 0); // Ensure student count doesn't go below 0
lastPosition = newPosition;
updateScreen();
}
} else {
// Detect rotary encoder movement in menu mode
if (newPosition != lastPosition) {
if (newPosition > lastPosition) {
menuIndex++;
} else {
menuIndex--;
}
lastPosition = newPosition;
menuIndex = constrain(menuIndex, 0, currentMenuSize - 1);
updateScreen();
}
}
// Detect button press
if (digitalRead(SW_PIN) == LOW) {
handleButtonPress();
delay(300); // Debounce delay
}
}
// Update LCD screen based on the current menu
void updateScreen() {
lcd.clear();
lcd.setCursor(0, 0);
if (editingStudents) {
// Display student count editing screen
lcd.print("Editer Nb:");
lcd.setCursor(0, 1);
lcd.print(studentCount);
} else {
// Display menu items
for (int i = 0; i < currentMenuSize && i < 4; i++) {
lcd.setCursor(0, i);
if (i == menuIndex) {
lcd.print("> ");
} else {
lcd.print(" ");
}
lcd.print(currentMenu[i]);
}
}
}
// Handle button press on the rotary encoder
void handleButtonPress() {
if (editingStudents) {
// Save the changes and exit editing mode
editingStudents = false;
menuLevel = 0; // Reset menu level to the main menu
currentMenu = mainMenu; // Reset to main menu
currentMenuSize = mainMenuSize;
menuIndex = 0; // Reset menu index
} else {
switch (menuLevel) {
case 0: // Main menu
if (menuIndex == 0) {
currentMenu = univBatna1Faculties;
currentMenuSize = univBatna1FacultiesSize;
} else if (menuIndex == 1) {
currentMenu = univBatna2Faculties;
currentMenuSize = univBatna2FacultiesSize;
}
menuLevel++;
menuIndex = 0;
break;
case 1: // Faculties
if (currentMenu == univBatna1Faculties) {
currentMenu = univBatna1Departments;
currentMenuSize = univBatna1DepartmentsSize;
} else if (currentMenu == univBatna2Faculties) {
currentMenu = univBatna2Departments;
currentMenuSize = univBatna2DepartmentsSize;
}
menuLevel++;
menuIndex = 0;
break;
case 2: // Departments
if (currentMenu == univBatna1Departments) {
if (menuIndex == 0) {
currentMenu = univBatna1LettresSpecialties;
currentMenuSize = 3;
} else if (menuIndex == 1) {
currentMenu = univBatna1EconomieSpecialties;
currentMenuSize = 2;
}
} else if (currentMenu == univBatna2Departments) {
if (menuIndex == 0) {
currentMenu = univBatna2BiologieSpecialties;
currentMenuSize = 3;
} else if (menuIndex == 1) {
currentMenu = univBatna2InformatiqueSpecialties;
currentMenuSize = 3;
} else if (menuIndex == 2) {
currentMenu = univBatna2MecaSpecialties;
currentMenuSize = 3;
} else if (menuIndex == 3) {
currentMenu = univBatna2ElectroniqueSpecialties;
currentMenuSize = 3;
}
}
menuLevel++;
menuIndex = 0;
break;
case 3: // Specialties
editingStudents = true; // Enter student count editing mode
break;
}
}
updateScreen();
}