The problem is when I enter the menu. When I scroll first it is fine. But when I press to enter the 'CODES' Sub menu nothing happens untill I scroll again??? Now I am stuck in that sub menu and can't get out. If anyone knows how to solve this I will be blessed. Also the motor is used for demontration so don't pay attention to that. And when you don't understand some code use translate some parts are written in dutch. (Maybe you also noticed but there are sub menu's in sub menu's)
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// [VARIABLES] ---------------------------------------------------------------------------------------------------------------------------------------------------------
// [VARIABLES] Main Variables ---------------------------------------------------------------------------------------------------------------------------------------
#include <LiquidCrystal_I2C.h> // Library I²C LCD
#include <RotaryEncoder.h> // Library Rotary
#include <Keypad_I2C.h> // Library I²C (PCF8759) Keypad
#include <Keypad.h> // Library Keypad
#define I2CADDR 0x20 // I2C-adres van het toetsenbord
bool loggedIn = false; // Variable voor het bepalen of u wel ben ingelogd of niet
LiquidCrystal_I2C lcd(0x27, 20, 4); // Adres Liquid Crystal Display
// [VARIABLES] Motor Control --------------------------------------------------------------------------------------------------------------------------------------------
const int motorPin1 = 2; // Motor control pin 1
const int motorPin2 = 13; // Motor control pin 2
bool rotation = 0; // Sleutel voor het bepalen van richting
// [VARIABLES] Rotary Encoder ---------------------------------------------------------------------------------------------------------------------------------
int encoderPinA = 10; // Pin voor de encoder
int encoderPinB = 11; // Pin voor de encoder
int switchPin = 12; // Pin voor de draairichting van de encoder
int savedCurrentPosition = 0;
RotaryEncoder encoder(encoderPinA, encoderPinB); // Bepaling draairichting
// [VARIABLES] Keypad -----------------------------------------------------------------------------------------------------------------------------------------
const int ROW_NUM = 4; // Variable aantal rijen Keypad
const int COLUMN_NUM = 3; // Variable aantal kolommen Keypad
// Matrix van de layout van de Keypad
char keys[ROW_NUM][COLUMN_NUM] = {
{ '1', '2', '3' },
{ '4', '5', '6' },
{ '7', '8', '9' },
{ '*', '0', '#' }
};
byte rowPins[ROW_NUM] = { 5, 0, 1, 3 }; // Aansluiting op rijpinnen van het toetsenbord
byte colmsPin[COLUMN_NUM] = { 4, 6, 2 }; // Aansluiting op kolompinnen van het toetsenbord
Keypad_I2C customKeypad(makeKeymap(keys), rowPins, colmsPin, ROW_NUM, COLUMN_NUM, I2CADDR); // Initialiseer een instantie van de Keypad_I2C-klasse
// [VARIABLES] Main menu -------------------------------------------------------------------------------------------------------------------------------------
// Opties om te kiezen in het Menu
const char *menuOptions[] = {
"Codes",
"Safe",
"Users",
"Logboek",
"Optie 2",
"Logout"
};
int mainMenuPosition = 0; // Huidige positie in hoofdmenu
int previousMainMenuPosition = 0; // Vorige positie in hoofdmenu ter vergelijking
int mainMenuSwitchStatus = HIGH; // Status van schakelknop voor navigatie hoofdmenu
int previousMainMenuSwitchStatus = HIGH; // Vorige status van schakelknop
int currentPosition = 0; // Huidige positie binnen zichtbare menuopties
int previousPosition = 0; // Vorige positie ter vergelijking
int highPosition = 4; // Hoogste index van zichtbare menuopties
int lowPosition = 1; // Laagste index van zichtbare menuopties
int switchStatus; // Huidige status van schakelknop van de Rotary encoder
int previousSwitchStatus = HIGH; // Vorige status van schakelknop van de Rotary encoder
int MENU_SIZE = sizeof(menuOptions) / sizeof(menuOptions[0]); // Totaal aantal opties in hoofdmenu
// [VARIABLES] Codes And Codes Sub Menu ----------------------------------------------------------------------------------------------------------------------
const char *accessCodes[] = {
"1234",
"5678",
"9876"
};
char enteredPIN[5];
const char *correctPIN = "1234";
const int NUM_CODES = sizeof(accessCodes) / sizeof(accessCodes[0]);
const char *CodesmenuOptions[] = {
"Codes",
"Change Code",
"Go Back"
};
int submenuPosition = 0;
int previousSubmenuPosition = 0;
int submenuSwitchStatus = HIGH;
int previousSubmenuSwitchStatus = HIGH;
int CODES_MENU_SIZE = sizeof(CodesmenuOptions) / sizeof(CodesmenuOptions[0]);
int submenuSize = sizeof(CodesmenuOptions) / sizeof(CodesmenuOptions[0]);
bool inSubmenu = false;
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// [SETUP] -----------------------------------------------------------------------------------------------------------------------------------------------
void setup() {
lcd.init();
lcd.clear();
lcd.backlight();
customKeypad.begin(); // Start het toetsenbord
lcd.begin(20, 4);
pinMode(switchPin, INPUT_PULLUP);
pinMode(motorPin1, OUTPUT);
pinMode(motorPin2, OUTPUT);
displayLoginScreen();
}
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// [LOOP] --------------------------------------------------------------------------------------------------------------------------------------------------------------
// [LOOP] Loginscreen ------------------------------------------------------------------------------------------------------------------------------------------
void displayLoginScreen() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Enter PIN:");
}
// [LOOP] Update Menu ------------------------------------------------------------------------------------------------------------------------------------------
void updateMenu() {
lcd.clear();
int visibleItems = 3;
int startIndex;
if (currentPosition >= 2) {
startIndex = currentPosition - 2;
} else {
startIndex = 0;
}
if (startIndex + visibleItems > MENU_SIZE) {
startIndex = MENU_SIZE - visibleItems;
}
lcd.setCursor(0, 0);
lcd.print("Menu:");
for (int i = 0; i < visibleItems; ++i) {
lcd.setCursor(0, i + 1);
int index = startIndex + i;
if (index == currentPosition) {
lcd.print(">");
} else {
lcd.print(" ");
}
lcd.print(menuOptions[index]);
}
}
// [LOOP] Update Sub Menu ---------------------------------------------------------------------------------------------------------------------------------------
void updateSubMenu() {
lcd.clear();
int visibleItems = 3;
int startIndex;
if (submenuPosition >= 2) {
startIndex = submenuPosition - 2;
} else {
startIndex = 0;
}
if (startIndex + visibleItems > CODES_MENU_SIZE) {
startIndex = CODES_MENU_SIZE - visibleItems;
}
lcd.setCursor(0, 0);
lcd.print("Codes Menu:");
for (int i = 0; i < visibleItems; ++i) {
lcd.setCursor(0, i + 1);
int index = startIndex + i;
if (index == submenuPosition) {
lcd.print(">");
} else {
lcd.print(" ");
}
lcd.print(CodesmenuOptions[index]);
}
}
// [LOOP] Codes ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void CodesMenu() {
int previousMainMenuPosition = currentPosition; // Store the current position in the main menu
updateSubMenu();
while (true) {
encoder.tick();
int encoderDelta = encoder.getPosition() - previousSubmenuPosition;
submenuSwitchStatus = digitalRead(switchPin);
if (encoderDelta != 0 || submenuSwitchStatus == LOW && previousSubmenuSwitchStatus == HIGH) {
submenuPosition += encoderDelta;
if (submenuPosition < 0) {
submenuPosition = 0;
} else if (submenuPosition >= CODES_MENU_SIZE) {
submenuPosition = CODES_MENU_SIZE - 1;
}
lcd.clear();
lcd.setCursor(0, 0);
updateSubMenu();
}
if (submenuSwitchStatus == LOW && previousSubmenuSwitchStatus == HIGH) {
switch (submenuPosition) {
case 0:
// Handle Codes option
break;
case 1:
// Handle Change Code option
break;
case 2:
currentPosition = previousMainMenuPosition; // Restore the previous position in the main menu
updateMenu(); // Go back to the main menu
break;
default:
break;
}
}
previousSubmenuSwitchStatus = submenuSwitchStatus;
previousSubmenuPosition = encoder.getPosition();
}
savedCurrentPosition = currentPosition;
}
//
// [LOOP] Logout -----------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void logout() {
loggedIn = false; // Set login status to false
currentPosition = 0; // Reset menu position
lcd.clear(); // Clear LCD
lcd.setCursor(0, 0);
lcd.print("Logging Out ...");
delay(1500);
lcd.clear();
displayLoginScreen(); // Display login screen
}
// [LOOP] Main Menu Selection Menu --------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void performAction() {
if (currentPosition == 0) {
currentPosition = savedCurrentPosition;
}
switch (currentPosition) {
case 0: // Codes option selected
CodesMenu(); // Display codes submenu
break;
case 1: // Kluis option selected
break;
case 2: // Gebruikers option selected
break;
case 3: // Optie 1 option selected
break;
case 4: // Optie 2 option selected
break;
case 5: // logout option selected
logout(); // Logout
digitalWrite(2, HIGH);
digitalWrite(13, LOW);
delay(3000);
digitalWrite(2, LOW);
digitalWrite(13, LOW);
break;
default:
break;
}
}
// [LOOP] Main Loop --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
void loop() {
if (!loggedIn) {
char customKey = customKeypad.getKey();
static char enteredPIN[5] = { 0 };
if (customKey != NO_KEY && strlen(enteredPIN) < 4) {
lcd.setCursor(strlen(enteredPIN), 1);
lcd.print('*');
enteredPIN[strlen(enteredPIN)] = customKey;
enteredPIN[strlen(enteredPIN) + 1] = '\0';
}
if (strlen(enteredPIN) == 4) {
if (strcmp(enteredPIN, "1234") == 0) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("PIN Correct");
delay(2000);
memset(enteredPIN, 0, sizeof(enteredPIN));
loggedIn = true;
rotation = 1;
updateMenu();
} else {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("PIN Incorrect");
delay(2000);
memset(enteredPIN, 0, sizeof(enteredPIN));
displayLoginScreen();
}
}
} else { // If logged in, handle menu navigation
if (loggedIn && rotation == 1) {
digitalWrite(2, LOW);
digitalWrite(13, HIGH);
delay(3000);
digitalWrite(2, LOW);
digitalWrite(13, LOW);
rotation = 0;
}
// Code voor het bewegen van de cursor in het Main Menu
encoder.tick();
int encoderDelta = encoder.getPosition() - previousPosition;
switchStatus = digitalRead(switchPin);
if (encoderDelta != 0) {
currentPosition += encoderDelta;
if (currentPosition < 0) {
currentPosition = 0;
} else if (currentPosition >= MENU_SIZE) {
currentPosition = MENU_SIZE - 1;
}
lcd.clear();
lcd.setCursor(0, 0);
updateMenu();
}
if (switchStatus == LOW && previousSwitchStatus == HIGH) {
performAction();
}
previousSwitchStatus = switchStatus;
previousPosition = encoder.getPosition();
}
}```