/* This is a Menutest for my Mecha Dungeon Mika Günther Fabacademy 2025 */ #include LiquidCrystal_I2C lcd(0x27, 16, 2); //0x27 is the standard I2C Adress for the PCF8574-Based LCD const int buttonNext = 5; // button for next entry const int buttonPrev = 6; // button for previous entry const int buttonSelect = 7; // button for selection //const mean that the array for example is not changeable while running const char* menuItems[] = { "Dungeon Select", "Create Dungeon" }; //what to display on the LCD const int menuLength = 2; int menuIndex = 0; boolean inMenu = false; // Dynamic dungeons array String* dungeons = nullptr; // Pointer to dynamically allocated array int dungeonCount = 0; // Number of dungeons int currentDungeon = 0; boolean inDungeons = false; #define STRING_LENGTH 25 // Define the required string length (for the test i'm using a 5x5 grid -> 25bits) char receivedString[STRING_LENGTH + 1]; // Array to store input (+1 for null termination) void setup() { Serial.begin(115200); //allow a serial connection with a baudrate of 115200 to comunicate with for example the computer // set the Buttons as Input pinMode(buttonNext, INPUT); pinMode(buttonPrev, INPUT); pinMode(buttonSelect, INPUT); // Initialize the LCD and activate the Backlight lcd.init(); lcd.backlight(); //Print welcomescreen lcd.setCursor(3, 0); lcd.print("Welcome to"); lcd.setCursor(2, 1); lcd.print("MechaDungeon"); delay(5000); // Initialize with predefined dungeons(call the function) initializeDungeons(); //call the function to initialize the Menu showMenu(); } void loop() { //check in which Menu we are if (inMenu) { //check if and wich button is pressed if (digitalRead(buttonPrev)) { menuIndex--; //changes the current position in the menu to previous Entry if (menuIndex < 0) menuIndex = menuLength - 1; // if "before" the begin of the list go to last entry showMenu(); //refresh screen delay(300); // Debounce the Button to prevent multiple inputs }else if (digitalRead(buttonNext)) { menuIndex++; // current position to next entry if (menuIndex >= menuLength) menuIndex = 0; // if at the end of the list start from the beginnig of the list showMenu(); delay(300); // Debounce }else if (digitalRead(buttonSelect)) { //if button is pressed, call function acording to current index switch (menuIndex) { case 0: showDungeons(); break; case 1: getDungeon(); break; } delay(300); // Debounce } }else if (inDungeons) { if (digitalRead(buttonPrev)) { currentDungeon--; if (currentDungeon < 0) currentDungeon = dungeonCount - 1; showDungeons(); delay(300); // Debounce } if (digitalRead(buttonNext)) { currentDungeon++; if (currentDungeon >= dungeonCount) currentDungeon = 0; showDungeons(); delay(300); // Debounce } if (digitalRead(buttonSelect)) { //if pressed, "build" or show content of the selected Dungeon buildDungeon(); delay(300); // Debounce } } } void initializeDungeons() { dungeonCount = 2; //set initial dungeoncount dungeons = new String[dungeonCount]; //let the pointer point to a new String Array with size of the initial dungeoncount //Save first two example Dungeons dungeons[0] = "1111110001101011000111111"; dungeons[1] = "1011110100101011000111111"; } void showMenu() { lcd.clear(); lcd.setCursor(0, 0); lcd.print("Menu:"); lcd.setCursor(0, 1); lcd.print("> " + String(menuItems[menuIndex])); //says that we are now in the mainmenu and that the mainmenu loop starts; resets the dungeonmenu params inMenu = true; inDungeons = false; currentDungeon = 0; } void showDungeons() { lcd.clear(); lcd.setCursor(0, 0); lcd.print("Dungeons:"); lcd.setCursor(0, 1); lcd.print("> " + String(currentDungeon + 1) + ". Dungeon"); //says that we are now in the dungeonmenu and that the dungeonmenu loop starts; resets the mainnmenu params inDungeons = true; inMenu = false; menuIndex = 0; } void getDungeon() { String receivedString = "";//creates String to store new Dungeon //Reads string from serial while (receivedString.length() < STRING_LENGTH - 1) { if (Serial.available()) { char receivedChar = Serial.read(); receivedString += receivedChar; } } // Create a new dynamic array with one extra slot String* dungeonsNew = new String[dungeonCount + 1]; // Copy old dungeons into new array for (int i = 0; i < dungeonCount; i++) { dungeonsNew[i] = dungeons[i]; } // Add the new dungeon dungeonsNew[dungeonCount] = receivedString; // Free old memory delete[] dungeons; // Update pointers and count dungeons = dungeonsNew; dungeonCount++; } void buildDungeon() { lcd.clear(); lcd.setCursor(0, 0); lcd.print("Selected Dungeon:"); lcd.setCursor(0, 1); lcd.print(dungeons[currentDungeon]); delay(3000); inMenu = true; inDungeons = false; showMenu(); }