I need help with my access control project

Me and my dad made a door lock with the arduino. Now we found out that when the Arduino loses power it forgets all the tags we added. Is there a way to save them to the EEprom or to the arduino. So that when it loses power and we turn it on again we don't have to add all the tags again.

#include <SPI.h>
#include <MFRC522.h>
#include <LiquidCrystal.h>
#include <Servo.h>
#include <EEPROM.h>


#define RST_PIN   9
#define SS_PIN    10

byte readCard[4];
char* myTags[100] = {};
int tagsCount = 0;
String tagID = "";
boolean successRead = false;
boolean correctTag = false;
int proximitySensor;
boolean doorOpened = false;

// Create instances
MFRC522 mfrc522(SS_PIN, RST_PIN);
LiquidCrystal lcd(2, 3, 4, 5, 6, 7); //Parameters: (rs, enable, d4, d5, d6, d7)
Servo myServo; // Servo motor

void setup() {
  // Initiating
  Serial.begin(115200);
  Serial.println("Test prox sensor");
  SPI.begin();        // SPI bus
  mfrc522.PCD_Init(); //  MFRC522
  lcd.begin(16, 2);   // LCD screen
  //myServo.attach(8);  // Servo motor

  pinMode(8, OUTPUT); //relais

  myServo.write(10); // Initial lock position of the servo motor
  // Prints the initial message
  lcd.print("-No master tag!-");
  lcd.setCursor(0, 1);
  lcd.print("    SCAN NOW");
  // Waits until a master card is scanned
  while (!successRead) {
    successRead = getID();
    if ( successRead == true) {
      myTags[tagsCount] = strdup(tagID.c_str()); // Sets the master tag into position 0 in the array
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print("Master Tag Set!");
      tagsCount++;
    }
  }
  successRead = false;
  printNormalModeMessage();
}

void loop() {
  int proximitySensor = analogRead(A0);
  Serial.println(proximitySensor);
  // If door is closed...
  if (proximitySensor > 200) {
    if ( ! mfrc522.PICC_IsNewCardPresent()) { //If a new PICC placed to RFID reader continue
      return;
    }
    if ( ! mfrc522.PICC_ReadCardSerial()) {   //Since a PICC placed get Serial and continue
      return;
    }
    tagID = "";
    // The MIFARE PICCs that we use have 4 byte UID
    for ( uint8_t i = 0; i < 4; i++) {  //
      readCard[i] = mfrc522.uid.uidByte[i];
      tagID.concat(String(mfrc522.uid.uidByte[i], HEX)); // Adds the 4 bytes in a single String variable
    }
    tagID.toUpperCase();
    mfrc522.PICC_HaltA(); // Stop reading

    correctTag = false;
    // Checks whether the scanned tag is the master tag
    if (tagID == myTags[0]) {
      lcd.clear();
      lcd.print("Program mode:");
      lcd.setCursor(0, 1);
      lcd.print("Add/Remove Tag");
      while (!successRead) {
        successRead = getID();
        if ( successRead == true) {
          for (int i = 0; i < 100; i++) {
            if (tagID == myTags[i]) {
              myTags[i] = "";
              lcd.clear();
              lcd.setCursor(0, 0);
              lcd.print("  Tag Removed!");
              printNormalModeMessage();
              return;
            }
          }
          myTags[tagsCount] = strdup(tagID.c_str());
          lcd.clear();
          lcd.setCursor(0, 0);
          lcd.print("   Tag Added!");
          printNormalModeMessage();
          tagsCount++;
          return;
        }
      }
    }
    successRead = false;
    // Checks whether the scanned tag is authorized
    for (int i = 0; i < 100; i++) {
      if (tagID == myTags[i]) {
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print(" Access Granted!");
        myServo.write(170); // Unlocks the door

        digitalWrite(8, HIGH);   // turn the LED on (HIGH is the voltage level)
        delay(3000);                       // wait for three seconds
        digitalWrite(8, LOW);    // turn the LED off by making the voltage LOW
       
        printNormalModeMessage();
        correctTag = true;
      }
    }
    if (correctTag == false) {
      lcd.clear();
      lcd.setCursor(0, 0);
      lcd.print(" Access Denied!");
      printNormalModeMessage();
    }
  }
  // If door is open...
  else {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print(" Door Opened!");
    while (!doorOpened) {
      proximitySensor = analogRead(A0);
      if (proximitySensor < 200) {
        doorOpened = true;
      }
    }
    doorOpened = false;
    myServo.write(10); // Locks the door
    delay(1000);
    printNormalModeMessage();
  }
}

uint8_t getID() {
  // Getting ready for Reading PICCs
  if ( ! mfrc522.PICC_IsNewCardPresent()) { //If a new PICC placed to RFID reader continue
    return 0;
  }
  if ( ! mfrc522.PICC_ReadCardSerial()) {   //Since a PICC placed get Serial and continue
    return 0;
  }
  tagID = "";
  for ( uint8_t i = 0; i < 4; i++) {  // The MIFARE PICCs that we use have 4 byte UID
    readCard[i] = mfrc522.uid.uidByte[i];
    tagID.concat(String(mfrc522.uid.uidByte[i], HEX)); // Adds the 4 bytes in a single String variable
  }
  tagID.toUpperCase();
  mfrc522.PICC_HaltA(); // Stop reading
  return 1;
}

void printNormalModeMessage() {
  delay(1500);
  lcd.clear();
  lcd.print("-Access Control-");
  lcd.setCursor(0, 1);
  lcd.print(" Scan Your Tag!");
}

Yes, you can do it. You'll need to use EEPROM write though and push the data byte by byte because the compiler can't tell how big your tags are.

Arduino EEPROM

see examples

wildbill:
Yes, you can do it. You'll need to use EEPROM write though and push the data byte by byte because the compiler can't tell how big your tags are.

How to do it byte by byte and where to do it in the code?

Where? Read the EEPROM in setup. Write it when you enroll a new tag.

How - two loops, one nested inside the other. Outer loop iterates through tags array. Inner iterates through the four bytes of the tag and writes each to EEPROM.

Since EEPROM has a finite life, you might consider only writing the tag you just enrolled, but the brute force approach should get you started.

Also, you'll want to check that the pointer in the tags array isn't null before you try to write the contents.

Arduino EEPROM update() only writes if the data in the EEPROM is different than the data being written and put() uses the data type to determine how many bytes to write. put() uses update() and put() may recognize that myTags[] is an array and attempt to write the entire array

you need to load from eeprom in setup() and save to eeprom whenever a tag is created/edited

gcjr:
put() uses the data type to determine how many bytes to write. put() uses update() and put() may recognize that myTags[] is an array and attempt to write the entire array

Since myTags[] is an array of pointers, put() may simply write the pointer values rather than the data being pointed to.

thanks. that's right

something like this

eeAdr = 0;
for (int i = 0; i < 100; i++, eeAdr++)
    EEPROM.put(eeAdr, myTag [i]);

wildbill:
Where? Read the EEPROM in setup. Write it when you enroll a new tag.

How - two loops, one nested inside the other. Outer loop iterates through tags array. Inner iterates through the four bytes of the tag and writes each to EEPROM.

Since EEPROM has a finite life, you might consider only writing the tag you just enrolled, but the brute force approach should get you started.

Also, you'll want to check that the pointer in the tags array isn't null before you try to write the contents.

Is there a possibility you could put it the correct way in my code? i can't get it to work

Should not take you long to master EEPROM. If you really don't want to, ask the moderators to move your thread to gigs and collaborations. You may be able to find someone there to do it for cash.

One other thing, the code that gcjr gave you is flawed. It does exactly what gfvalvo warned about and pushes the pointers to EEPROM. I suggest you change the array of tags to a 2d array of char instead.