Reading and storing button values?

Awesome. Everything works great now... I attached the servo too. My last curiosity would be if there could be a way to print a "*" in place of the number pressed after a second or half a second.

I think we have it

:slight_smile:

Try this code out

Fixed a couple of glitches with saving and retrieving code from EEPROM
I think its 100%

My son is loving it... now how to modify his door to lock it without damaging the house lol

//  ********* I don't have an LCD display to test so I commented out that code but I left it intact for you to use and I've edited it to work better I hope :)

//EEPROM
#include <EEPROM.h>

int address = 0;
static unsigned long SaveTimer;
static unsigned long SaveDelay = (30 * 1000); // after successfully unlocking the lock you can change the code with 30 seconds


char CODE[10] = "1234E"; //Lets store the code as a simple text string ASCii... why not default code is "1234E" 'E' represents the Enter Key and is checked also
char Str[10];  // plenty of room to catch imput from your keys we only need 6 char's 4 for the code, one for the Enter Kye and 1 for the NULL '\0' if you want to make the code longer you can have up to 9 digits
int CodeLength = 4;
int Pos = 0;
bool Unlocked;
static unsigned long DisplayTimer; // LCD displays cant refresh fast... so they blink alot but using delay() keeps us from seeing what we want so I just skip the code until time mathces
static unsigned long DisplayDelay = 1000;



//#include <LiquidCrystal.h>

int buttonPin1 = 2;   //sets pins buttons are connected to
int buttonPin2 = 3;
int buttonPin3 = 4;
int buttonPin4 = 5;

int enterbutton = 10; // not in use yet
int clearlockbutton = 13;

//LiquidCrystal lcd(12, 11, 9, 8, 7, 6); //sets pins lcd is connected to, running in 4 bit mode, RW pin tied to gnd

void setup() {
  Serial.begin(9600);
  int EEPROMCodeOK = true;
  Serial.println("Loading Code");
  for (Pos = 0; Pos <= (CodeLength); Pos++) {
    Str[Pos] =  EEPROM.read(Pos);
    if (!(strrchr("1123456789E", Str[Pos]))) { // must be of proper length and contain only these ASCii charaters
      // not a valid code
      EEPROMCodeOK = false;
    }
  }

  if (EEPROMCodeOK) {
    Str[CodeLength + 2] = '\0';
    strncpy(CODE, Str, CodeLength + 1);
  }

  ClearCode();

  Serial.print("Your Code is:");
  Serial.println(CODE);

  pinMode(buttonPin1, INPUT_PULLUP);  //assigns button pins as inputs
  pinMode(buttonPin2, INPUT_PULLUP);
  pinMode(buttonPin3, INPUT_PULLUP);
  pinMode(buttonPin4, INPUT_PULLUP);

  pinMode(enterbutton, INPUT_PULLUP);
  pinMode(clearlockbutton, INPUT_PULLUP);

  //lcd.begin(16, 2); //screen size
  //lcd.setCursor(0, 0);
  //lcd.print("Hello."); //introduction
  //delay(2000); //delay
  //lcd.clear(); //clears screen
  //lcd.setCursor(0, 0); // top left
  //lcd.print("Password:");

  Serial.println("Hello.");
  Serial.println("Password:");
  DisplayTimer = millis() + 200;
}


void loop() {
  Lock(); // keep it locked at all times except when code is entered
  if (Pos > CodeLength) {
    for (int x = 0; x <= CodeLength; x++) {
      Str[x] = Str[x + 1];
    }
  }
  Pos = constrain(Pos, 0, CodeLength);

  int buttonState1 = digitalRead(buttonPin1);  //reads buttons
  int buttonState2 = digitalRead(buttonPin2);
  int buttonState3 = digitalRead(buttonPin3);
  int buttonState4 = digitalRead(buttonPin4);

  int clButtonState = digitalRead(clearlockbutton);
  int enterButtonState = digitalRead(enterbutton);



  if (buttonState1 == LOW) {
    Str[Pos] = '1';
    Pos++;
    Str[Pos] = '\0';
    delay(250); // <<good for debounce on your button :)
    while (digitalRead(buttonPin1) == LOW); //wait for button to br released

  }

  else if (buttonState2 == LOW) {
    Str[Pos] = '2';
    Pos++;
    Str[Pos] = '\0';
    delay(250); // <<good for debounce on your button :)
    while (digitalRead(buttonPin2) == LOW); //wait for button to be released

  }

  else if (buttonState3 == LOW) {
    Str[Pos] = '3';
    Pos++;
    Str[Pos] = '\0';
    delay(250); // <<good for debounce on your button :)
    while (digitalRead(buttonPin3) == LOW); //wait for button to be released
  }

  else if (buttonState4 == LOW) {
    Str[Pos] = '4';
    Pos++;
    Str[Pos] = '\0';
    delay(250); // <<good for debounce on your button :)    delay(350);
    while (digitalRead(buttonPin4) == LOW); //wait for button to be released

  }
  else if (enterButtonState == LOW) {
    Str[Pos] = 'E';
    Pos++;
    Str[Pos] = '\0';
    delay(250); // <<good for debounce on your button :)    delay(350);
    while (digitalRead(buttonPin1) == LOW); //wait for button to be released
    //if (Str == CODE){
    if (strcmp (Str, CODE) == 0) {
      Serial.println("Unlocked");
      Unlocked = true;
      // lcd.setCursor(0, 0); // top left
      // lcd.print("Unlocked");
      // lcd.setCursor(0, 1); // bottom left
      // lcd.print("          "); // Hide Code While unlocked
    }

    else if (SaveTimer > millis()) {

      
      if (Pos  == (CodeLength + 1)) { // you successfully unlocked this in the last 30 seconds and have entered a 4 digit code + enter button

        strcpy(CODE, Str); // store the code locally
        Serial.println("Saving to EEPROM");

        for (Pos = 0; Pos <= (CodeLength + 1); Pos++) {
          Serial.println(Str[Pos]);
          EEPROM.write(Pos, Str[Pos]); // Store the code for next power up
        }
        Str[CodeLength]= '\0'; // Hide the letter E
        // lcd.setCursor(0, 0); // top left
        // lcd.print("Saving Code:");
        // lcd.setCursor(0, 1); // bottom left
        // lcd.print(Str);  // Show Saved Code for Conformation
        SaveTimer = millis(); // clear save timer
        Serial.print("Save Code:");
        Serial.println(Str);
      }
    }
    else {
      Serial.println("Access Denied.");
      //lcd.clear();
      //lcd.print(" Access Denied.");
      delay(2000);
      //lcd.clear();
      //lcd.print("Password:");


      Serial.println("Password:");

    }

    while (Unlocked) { // Lets hold here wile it is unlocked no other imput but the clear button will work.
      Unlock();
      if (digitalRead(clearlockbutton) == LOW) {
        delay(200); // <<good for debounce on your button :)
        Unlocked = false;

        SaveTimer = millis() + 30000; // set timer to allow saving of new code withing the next 30 seconds
      }
    }
    Lock();
    Serial.println("Lock");
    //lcd.clear();
    //lcd.print("     Locked");
    delay(2000);
    //lcd.clear();
    ClearCode();

    DisplayTimer = millis() + DisplayDelay;
  }

  else if (clButtonState == LOW) {
    delay(500); // <<good for debounce on your button :)

    while (clearlockbutton == LOW); //wait for button to be released
    if ((millis() - SaveTimer) > 4500) {
    }
    ClearCode();
  }

  if ( (long)( millis() - DisplayTimer ) >= 0) {
    DisplayTimer += DisplayDelay;
    // lcd.setCursor(9, 0); // Top 9 chars in left
    // lcd.print(Str);
    // lcd.print("  ");
    //lcd.setCursor(15, 0);
    if (SaveTimer > millis()) {

      // lcd.pring{"*");
      Serial.print((int) ((SaveTimer - millis()) * .001));
      Serial.println(" Seconds left to save new password");
    } else {
      //lcd.print(" ");

    }


    Serial.print("Password:\t");
    Serial.println(Str);

  }
}

void ClearCode() {
  Pos = 0;
  Str[Pos] = '\0';
  //lcd.setCursor(0, 0); // top left
  //lcd.print("Password:");
  // lcd.setCursor(0, 1); // bottom left
  // lcd.print("          ");
}

void Unlock() {
  // drive your servo here
}
void Lock() {
  // drive your servo here
}

As for your "*" do something like

static unsigned long HideTimer; // LCD displays cant refresh fast... so they blink alot but using delay() keeps us from seeing what we want so I just skip the code until time mathces
static unsigned long HideDelay = 1000;
// trigger the hide by
HideTimer = millis + HideDelay;

// have this in the main loop
if ( (long)( millis() - HideTimer ) >= 0) {
  
  lcd.setCursor(8, 0);

  for (int c = 0; c <= pos ; c++) {
    lcd.print("*");
  }
}

Sweet, this was a great success. Thanks a ton, this was really fun to make!