Need HELP for a Arduino Menu code

Good day! I want a "back" option when I am in the "attendance mode" or in the "hall pass mode". But my back code doesn't work. Any help is highly appreciated.

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <SPI.h>
#include <MFRC522.h>

#define SS_PIN 10
#define RST_PIN 9

LiquidCrystal_I2C lcd(0x27, 20, 4);
MFRC522 mfrc522(SS_PIN, RST_PIN);   

// Add/Remove Valid UIDs of RFID
byte validUIDs[][4] = 
{                                                   
  {0xB9, 0x1C, 0x0B, 0xD6},   // UID of student 1   
  {0x33, 0x07, 0x4C, 0xD1},   // UID of student 2   
  {0x20, 0xD3, 0xA7, 0x88},   // UID of student 3   
  {0x96, 0xF7, 0x58, 0x9E},   // UID of student 4   
  {0x23, 0x66, 0xA6, 0xD0},   // UID of student 5
  {0x95, 0xBB, 0x09, 0x43},   // UID of student 6
  {0x59, 0x48, 0x0D, 0xC9},   // UID of student 7
};

// Student names in their respective UIDs
const char* studentNames[] = 
{
  "abc",        // Name of student 1
  "def",        // Name of student 2
  "ghi",          // Name of student 3
  "jkl",          // Name of student 4
  "mno",          // Name of student 5
  "pqr",         // Name of student 6
  " stu",           // Name of student 7
};

boolean hasRun = false;
boolean hasRunMenu = false;
int menu = 1;
int up = 2;
int down = 3;
int enter = 4;
int Buzzer = 5;
int LEDR = 6;
int LEDG = 7;

void setup() 
{
  if (hasRun == false) 
  {
    hasRun = true;

    Serial.begin(9600);   
    SPI.begin();          
    mfrc522.PCD_Init();

    lcd.init();
    lcd.backlight();
    lcd.clear();
    lcd.setCursor(5, 1);
    lcd.print("Booting Up");
    lcd.setCursor(4, 2);
    lcd.print("Please Wait!");
    delay(3000);
  }
  pinMode(up, INPUT_PULLUP);
  pinMode(down, INPUT_PULLUP);
  pinMode(enter, INPUT_PULLUP);
  pinMode(Buzzer, OUTPUT);
  pinMode(LEDG, OUTPUT);
  pinMode(LEDR, OUTPUT);
       
  updateMenu();

  if (hasRunMenu == false) 
  {
    hasRunMenu = true;

    updateMenuHallpass();
  }
}

void loop() 
{
  if (!digitalRead(up)) 
  {
    menu--;
    updateMenu();
    delay(100);
    while(!digitalRead(up));
  }
  if (!digitalRead(down)) 
  {
    menu++;
    updateMenu();
    delay(100);
    while (!digitalRead(down));
  }
  if (!digitalRead(enter)) 
  {
    executeAction();
    updateMenu();
    delay(100);
    while (!digitalRead(enter));
  }
}

void backLoop() 
{
  if (!digitalRead(up)) 
  {
    menu--;
    updateMenu();
    delay(100);
    while(!digitalRead(up));
  }
  if (!digitalRead(down)) 
  {
    menu++;
    updateMenu();
    delay(100);
    while (!digitalRead(down));
  }
  if (!digitalRead(enter)) 
  {
    executeAction();
    updateMenu();
    delay(100);
    while (!digitalRead(enter));
  }
}

void updateMenu() 
{
  switch (menu) 
  {
    case 0:
      menu = 1;
      break;
    case 1:
      lcd.clear();
      lcd.print("> Attendance");
      lcd.setCursor(0, 1);
      lcd.print("  Hall Pass");
      break;
    case 2:
      lcd.clear();
      lcd.print("  Attendance");
      lcd.setCursor(0, 1);
      lcd.print("> Hall Pass");
      break;
    case 3:
      menu = 2;
      break;
  }
}

void executeAction() 
{
  switch (menu) 
  {
    case 1:
      lcd.clear();
      lcd.setCursor(3, 1);
      lcd.print("Scan RFID card");
      lcd.setCursor(0, 3);
      lcd.print(">Back");
      Serial.println("Ready to read RFID cards");
      action1Loop();
      action1LoopBack();
      delay(3000);
      break;
    case 2:
      lcd.clear();
      lcd.setCursor(3, 1);
      lcd.print("Scan RFID card");
      lcd.setCursor(0, 3);
      lcd.print(">Back");
      Serial.println("Ready to read RFID cards");
      action2Loop();
      delay(3000);
      break;
  }
}

void action1Loop() 
{
  while (menu == 1) 
  {
    action1();
  }
}

void action1LoopBack() 
{
  while (menu == 1) 
  {
    if (!digitalRead(enter)) 
    {
    updateMenu();
    delay(100);
    while (!digitalRead(enter));
    exit(0);
    }
  }
}

void action2Loop() 
{
  while (menu == 2) 
  {
    action2();
  }
}

void updateAttendance(int studentID, const char* status) 
{
  // Display names of the student on the LCD
  lcd.clear();
  lcd.setCursor(0, 1);
  lcd.print(studentNames[studentID - 1]); 
  lcd.setCursor(6, 2);  
  lcd.print(status);
}

void action1() 
{
  if (mfrc522.PICC_IsNewCardPresent())  // Look for new cards
  {
    if (mfrc522.PICC_ReadCardSerial()) 
    {
      Serial.print("UID tag: ");  // Show UID on serial monitor
      for (byte i = 0; i < mfrc522.uid.size; i++) 
      {
        Serial.print("0x");
        if (mfrc522.uid.uidByte[i] < 0x10) Serial.print("0");
        Serial.print(mfrc522.uid.uidByte[i], HEX);
        if (i < mfrc522.uid.size - 1) Serial.print(", ");
      }
      Serial.println();
      Serial.print("UID Number: ");
      String content = "";
      byte letter;
      for (byte i = 0; i < mfrc522.uid.size; i++) 
      {
        content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? "0" : ""));
        content.concat(String(mfrc522.uid.uidByte[i], HEX));
      }
      content.toUpperCase();
      Serial.println(content);

      bool uidMatched = false;  // Check if UID matches any of the valid UIDs
      int studentIndex = -1;
      for (int i = 0; i < sizeof(validUIDs) / sizeof(validUIDs[0]); i++) 
      {
        if (memcmp(mfrc522.uid.uidByte, validUIDs[i], mfrc522.uid.size) == 0) 
        {
          uidMatched = true;
          studentIndex = i;
          break;
        }
      }
      if (uidMatched)  // UID matches, perform attendance action
      {
        updateAttendance(studentIndex + 1, "Present!");
        digitalWrite(LEDG, HIGH);
        tone(Buzzer, 10000, 500);
        Serial.println();
        Serial.println("ID Found");
        Serial.println();
        delay(3000);
        digitalWrite(LEDG, LOW);
      } 
      else  // UID doesn't match, perform deny action
      {
        lcd.clear();
        lcd.setCursor(4, 1);
        lcd.print("ID Not Found");
        lcd.setCursor(5, 2);
        lcd.print("Try Again!");
        digitalWrite(LEDR, HIGH);
        tone(Buzzer, 100, 1000);
        Serial.println();
        Serial.println("ID Not Found");
        Serial.println();
        delay(3000);
        digitalWrite(LEDR, LOW);
      }
      lcd.clear();  // Clear the LCD display and reset for next scan
      lcd.setCursor(3, 1);
      lcd.print("Scan RFID card");
      lcd.setCursor(0, 3);
      lcd.print(">Back");
      delay(1000);   
    }
    
    mfrc522.PICC_HaltA();   
    mfrc522.PCD_StopCrypto1();  
  }
}

void action2() 
{
  if (mfrc522.PICC_IsNewCardPresent())  // Look for new cards
  {
    if (mfrc522.PICC_ReadCardSerial()) 
    {
      Serial.print("UID tag: ");  // Show UID on serial monitor
      for (byte i = 0; i < mfrc522.uid.size; i++) 
      {
        Serial.print("0x");
        if (mfrc522.uid.uidByte[i] < 0x10) Serial.print("0");
        Serial.print(mfrc522.uid.uidByte[i], HEX);
        if (i < mfrc522.uid.size - 1) Serial.print(", ");
      }
      Serial.println();
      Serial.print("UID Number: ");
      String content = "";
      byte letter;
      for (byte i = 0; i < mfrc522.uid.size; i++) 
      {
        content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? "0" : ""));
        content.concat(String(mfrc522.uid.uidByte[i], HEX));
      }
      content.toUpperCase();
      Serial.println(content);

      bool uidMatched = false;  // Check if UID matches any of the valid UIDs
      int studentIndex = -1;
      for (int i = 0; i < sizeof(validUIDs) / sizeof(validUIDs[0]); i++) 
      {
        if (memcmp(mfrc522.uid.uidByte, validUIDs[i], mfrc522.uid.size) == 0) 
        {
          uidMatched = true;
          studentIndex = i;
          break;
        }
      }
      if (uidMatched)  // UID matches, perform attendance action
      {
        updateMenuHallpass();
      } 
      else  // UID doesn't match, perform deny action
            {
        lcd.clear();
        lcd.setCursor(4, 1);
        lcd.print("ID Not Found");
        lcd.setCursor(5, 2);
        lcd.print("Try Again!");
        digitalWrite(LEDR, HIGH);
        tone(Buzzer, 100, 1000);
        Serial.println();
        Serial.println("ID Not Found");
        Serial.println();
        delay(3000);
        digitalWrite(LEDR, LOW);
      }
      lcd.clear();  // Clear the LCD display and reset for next scan
      lcd.setCursor(3, 1);
      lcd.print("Scan RFID card");
      lcd.setCursor(0, 3);
      lcd.print(">Back");
      delay(1000);   
    
    mfrc522.PICC_HaltA();   
    mfrc522.PCD_StopCrypto1(); 
    } 
  }
}

what do you expect this to do?

I believe it works like "break;", I just found that code somewhere on the internet. I'm just bad at coding as you may notice.

it means "terminate the program" (ie nothing works after that) so very different than break :slight_smile:

you might benefit from studying state machines. Here is a small introduction to the topic: Yet another Finite State Machine introduction and using a button library to handle bouncing etc. it will make your code much easier


another weird stuff is

the setup runs only once, and you set hasRun to false so this variable is useless


it's also usually a good idea to keep things that are related in a struct . You could do something like this

struct Student {
  const char * studentName;
  byte uid[4];
};

Student students[] = {
  { "abc", {0xB9, 0x1C, 0x0B, 0xD6}},
  { "def", {0x33, 0x07, 0x4C, 0xD1}},
  { "ghi", {0x20, 0xD3, 0xA7, 0x88}},
  { "jkl", {0x96, 0xF7, 0x58, 0x9E}},
  { "mno", {0x23, 0x66, 0xA6, 0xD0}},
  { "pqr", {0x95, 0xBB, 0x09, 0x43}},
  { "stu", {0x59, 0x48, 0x0D, 0xC9}},
};
const byte studentCount = sizeof students / sizeof *students;

when you do menu-- or menu++ you should check that you stay within the bounds of the defined menu

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.