Reading and storing button values?

Hello,

I am working on an electronic lock project, with four buttons to enter a passcode, as well as an enter button, and a clear button.

I have this code where if a button is pressed, the corresponding number will display on the screen, and I also have a button that will clear the numbers in case somebody typed a wrong number in.

#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() {

  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.print("Password:");
}


void loop() {



  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) {
    lcd.print("1");  //if button 1 is pressed, print 1.
    delay(250);

  }

  else if (buttonState2 == LOW) {
    lcd.print("2"); //if button 2 is pressed, print 2.
    delay(250);

  }

  else if (buttonState3 == LOW) {
    lcd.print("3"); //if button 3 is pressed, print 3.
    delay(250);

  }

  else if (buttonState4 == LOW) {
    lcd.print("4"); //if button 4 is pressed, print 4.
    delay(350);

  }

  if (clButtonState == LOW) {

    lcd.clear();
    lcd.print("Password:");
    lcd.print("        ");
    delay(1000);
    lcd.clear();
    lcd.print("Password:");
    
    // **INSERT LOCKING CODE HERE**

  }


}

Then, I started experimenting on how to store the button values, so if the correct password was typed in, the unlocking mechanism would go to work.

#include <LiquidCrystal.h>

int buttonPin1 = 2;
int buttonPin2 = 3;
int buttonPin3 = 4;
int buttonPin4 = 5;

int enterbutton = 10;
int clearlockbutton = 13;

const int password = 10;

int p1 = 0;
int p2 = 0;
int p3 = 0;
int p4 = 0;

LiquidCrystal lcd(12, 11, 9, 8, 7, 6);

void setup() {

  pinMode(buttonPin1, INPUT_PULLUP);
  pinMode(buttonPin2, INPUT_PULLUP);
  pinMode(buttonPin3, INPUT_PULLUP);
  pinMode(buttonPin4, INPUT_PULLUP);

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

  lcd.begin(16, 2);
  lcd.setCursor(0, 0);
  lcd.print("Hello.");
  delay(2000);
  lcd.clear();
  lcd.print("Password:");
  
}

void loop() {

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

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

  if (buttonState1 == LOW) {

    lcd.print("1");
    delay(250);

    int p1 = 1;
    
  }

  if (buttonState2 == LOW) {

    lcd.print("2");
    delay(250);

    digitalRead(p1);

    if (p1 == 1) {

      int p2 = 2;
      
    }
  }

  if (buttonState3 == LOW) {

    lcd.print("3");
    delay(250);

    digitalRead(p1);
    digitalRead(p2);

    if (p1 == 1) {
      if (p2 == 2) {

        int p3 = 3;
      }
    }

  }

  if (buttonState4 == LOW) {

    lcd.print("4");
    delay(250);

    digitalRead(p1);
    digitalRead(p2);
    digitalRead(p3);

    if (p1 == 1) {
      if (p2 == 2) {
        if (p3 == 3) {

          int p4 = 4;
          
        }
      }
    }
  }

  digitalRead(p1);
  digitalRead(p2);
  digitalRead(p3);
  digitalRead(p4);

  if (p1 == 1,
      p2 == 2,
      p3 == 3,
      p4 == 4) {

        if(enterButtonState == LOW) {

           lcd.clear();
           lcd.print("Correct!");
           delay(1000);
           lcd.print("Password:");
        
        }

      }


      if(clButtonState == LOW) {
        
        lcd.clear();
        lcd.print("Password:");
        lcd.print("        ");
        delay(1000);
        lcd.clear();
        lcd.print("Password:");
    
    // **INSERT LOCKING CODE HERE** -- when this button is pressed, it will also lock the door if it is unlocked

      }

}

Of course, I haven't added the servo motor yet, but I did have it set to say "correct" if the password was correct. (currently it is '1234'), however nothing happens when I click the 'enter' button. The 1, 2, 3, 4, and clear button functions fine.

Also, here is a photo of my circuit as of now:

What am I doing wrong here? Is it a small coding error, or did I just do this completely wrong? All help would be appreciated. thanks!

  if (p1 == 1,
      p2 == 2,
      p3 == 3,
      p4 == 4)

You need to read up on how to use if with multiple tests. I expect that you meant

  if (p1 == 1 &&  p2 == 2 && p3 == 3 && p4 == 4)

Note that I have not looked at the details of how your program works, but you would do well to print the value of pertinent variables in appropriate places in the code to make sure that the values are what you expect. The program also looks like it would benefit from the use of arrays to avoid repetitive code. The clue is the variables with basically the same name and a number suffix.

You have lines like:

digitalRead(p1);

in several places. That reads the pin p1 but does not store or do anything with the return value. It does not give the return value to p1.

UKHeliBob:

  if (p1 == 1,

p2 == 2,
      p3 == 3,
      p4 == 4)



You need to read up on how to use if with multiple tests. I expect that you meant


if (p1 == 1 &&  p2 == 2 && p3 == 3 && p4 == 4)



Note that I have not looked at the details of how your program works, but you would do well to print the value of pertinent variables in appropriate places in the code to make sure that the values are what you expect. The program also looks like it would benefit from the use of arrays to avoid repetitive code. The clue is the variables with basically the same name and a number suffix.

I made that change, but still no luck, but because of what ground said I'm not surprised... Would arrays just make things neater, or are they necessary in some spots?

groundfungus:
You have lines like:

digitalRead(p1);

in several places. That reads the pin p1 but does not store or do anything with the return value. It does not give the return value to p1.

How can I permanently store a value if a button is pressed until the 'enter' or 'clear' button is pressed which would ideally reset it then?

Delta_G:

int buttonState = digitalRead(p1);

Now the state of the button is in the variable buttonState. p1 is the pin number. comparing it to anything is rather useless. But you can compare buttonState to HIGH or LOW to see if the button was pressed when it was read into that variable.

I'm sorry, I'm not following..

Would arrays just make things neater, or are they necessary in some spots?

Arrays would make things neater but I suggest that you get the more pedestrian version working first.

UKHeliBob:
Arrays would make things neater but I suggest that you get the more pedestrian version working first.

Okay, and how can I get this to work? what exactly is wrong in this code? and how can I correct it?

I was looking for a project to do with my son today and yours seemed fun to work on...
I haven't put it together so there may still be bugs but this should get you started

Forgive any spelling errors :slight_smile:
I compiled the code and it looks to be good
I store your 4 digit code in EEPROM to be there when you start again

to Change the code enter the default code 1234 Enter and then within 30 seconds of Clearing enter the new 4 digit code and Enter
it should display Saving Code
and Save it in EEPROM as well as set that code as the current code

now reset and the new code Should be there. if it isn't well I haven't finished with my son yet here. Ill update you if i find any errors I've made

Thanks for the cool project idea :slight_smile:

//  ********* 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
char 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 = 200;



//#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() {

  int EEPROMCodeOK = true;
  for (Pos = 0; Pos <= (CodeLength); Pos++) {
    Str[Pos] =  EEPROM.read(Pos);
    if (!(strrchr("1123456789", Str[Pos]))) { // must be of proper length and contain only these ASCii charaters
      // not a valid code
      EEPROMCodeOK = false;
    }
  }
  Pos++;
  Str[Pos] =  EEPROM.read(Pos); // get the last value which is the enter Key
  if (Str[CodeLength + 1] != 'E') EEPROMCodeOK = false; // Last Char must be the enter Key 'E'
  if (EEPROMCodeOK) {
    Str[CodeLength + 2] = '\0';
    strncpy(CODE, Str, CodeLength + 1);
  }
  ClearCode();


  Serial.begin(115200);
  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.print("Hello.");
  Serial.print("Password:");
  DisplayTimer = millis() + 200;
}


void loop() {
  Lock(); // keep it locked at all times except when code is entered
  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) {
      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() && (Pos + 1) == CodeLength) { // 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
      for (Pos = 0; Pos <= (CodeLength + 1); Pos++) {
        EEPROM.write(Pos, Str[Pos]); // Store the code for next power up
      }
      // lcd.setCursor(0, 0); // top left
      // lcd.print("Saving Code:");
      // lcd.setCursor(0, 1); // bottom left
      // lcd.print(Str);  // unlock and Show Saved Code for Conformation



      Serial.print("Save Code:");
      Serial.println("Str");
      Unlocked = true;
    }

    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
      }
    }
    ClearCode();
  }

  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 += 200;
    // lcd.setCursor(0, 1); // bottom left
    // lcd.print(Str);
    // 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
}

Thanks for this!

The typing of the letters works, but the serial monitor just gives me a garbled mess of question marks. I don't know why, but I'll see if I can modify the code to state whatever it is on the screen.

Edit: I just had to make a change from

Serial.begin(115200);

to

Serial.begin(9600);

When pressing 'enter' or 'clear', the numbers disappear but it doesn't say 'unlocked' in either the screen or serial monitor. all I see on the serial monitor is 'Password: str' repeatedly.

Serial.begin(115200);
baud rate is fast

zhomeslice:
Serial.begin(115200);
baud rate is fast

Yeah, I picked that up. What about the second part?

  if ( (long)( millis() - DisplayTimer ) >= 0) {
    DisplayTimer += DisplayDelay;   //  <<<<<<<<<<<<< Changed ** This is how fast the display is updated For your LCD but it is also printing to the serial port 
    // lcd.setCursor(0, 1); // bottom left
    // lcd.print(Str);
    // lcd.print("     ");
    Serial.print("Password:\t");
    Serial.println("Str");

  }

Make the change above

and also adjust this line near the top
static unsigned long DisplayDelay = 1000; // Changed to 1 second between refreshes of the LCD and serial out

zhomeslice:

  if ( (long)( millis() - DisplayTimer ) >= 0) {

DisplayTimer += DisplayDelay;  //  <<<<<<<<<<<<< Changed ** This is how fast the display is updated For your LCD but it is also printing to the serial port
    // lcd.setCursor(0, 1); // bottom left
    // lcd.print(Str);
    // lcd.print("    ");
    Serial.print("Password:\t");
    Serial.println("Str");

}





Make the change above

and also adjust this line near the top
static unsigned long DisplayDelay = 1000; // Changed to 1 second between refreshes of the LCD and serial out

Still no luck. I'll be perfectly honest and say that this code is way out of my knowledge. I think I ought to learn a lot about these different pieces of code, or else I'll be no help to you troubleshooting with this code.

Edit: I am using an arduino uno. I looked up eeprom.h and I noticed it's only compatible with the Arduino AVR?...

If so, I suppose that is why this isn't working on my end.

I added this to help. change it back after your done testing the save:

  ClearCode();


  Serial.begin(9600);
  Serial.print("Your Code is:"); 
  Serial.println(CODE); // not a good thing to have if it is supposed to be secret lol

lol stupid mistakes lol

Serial.println("Str");
// Change to:
Serial.println(Str);

I'm Building the project now. I'm sure there are other glitches but this was an obvious mistake ... getting closer :slight_smile:

Made that change. Now, what I type also goes in the serial monitor sort of like this:

Password: 1
Password: 12
Password: 12
Password: 123
Password: 1234
Password: 1234
Password: 1234
Password: 1234
Password: 1234

Thank you again for all of this help, it's getting there, I know it!

ok I found one more change :slight_smile:

    if (Str == CODE){  <<<@Line 140  change this to :
    if (strcmp (Str,CODE) == 0) {
void loop() {
  Lock(); // keep it locked at all times except when code is entered

//Added this here to take only the last 4 digits shifting extras off the start
  if (Pos > CodeLength){
   for (int x = 0; x <= CodeLength; x++){
      Str[x] = Str[x+1];
   } 
  }

zhomeslice:
ok I found one more change :slight_smile:

    if (Str == CODE){  <<<@Line 140  change this to :

if (strcmp (Str,CODE) == 0) {

Bingo! Now says 'unlocked' when correct password entered.

zhomeslice:

void loop() {

Lock(); // keep it locked at all times except when code is entered

//Added this here to take only the last 4 digits shifting extras off the start
 if (Pos > CodeLength){
  for (int x = 0; x <= CodeLength; x++){
     Str[x] = Str[x+1];
  }
 }

When adding this, I get an error.

Arduino: 1.6.8 (Mac OS X), Board: "Arduino/Genuino Uno"

Build options changed, rebuilding all
/var/folders/4w/b3f5dh255ys1f54r9f6089zr0000gq/T/arduino_modified_sketch_857027/sketch_may07c.ino: In function 'void setup()':
sketch_may07c:54: error: 'ClearCode' was not declared in this scope

  • ClearCode();*
  • ^*
    /var/folders/4w/b3f5dh255ys1f54r9f6089zr0000gq/T/arduino_modified_sketch_857027/sketch_may07c.ino: In function 'void loop()':
    sketch_may07c:84: error: 'Lock' was not declared in this scope
  • Lock(); // keep it locked at all times except when code is entered*
  • ^*
    sketch_may07c:170: error: 'Unlock' was not declared in this scope
  • Unlock();*
  • ^*
    sketch_may07c:177: error: 'ClearCode' was not declared in this scope
  • ClearCode();*
  • ^*
    sketch_may07c:188: error: 'ClearCode' was not declared in this scope
  • ClearCode();*
  • ^*
    sketch_may07c:202: error: a function-definition is not allowed here before '{' token
    void ClearCode() {
  • ^*
    sketch_may07c:211: error: a function-definition is not allowed here before '{' token
    void Unlock() {
  • ^*
    sketch_may07c:214: error: a function-definition is not allowed here before '{' token
    void Lock() {
  • ^*
    sketch_may07c:216: error: expected '}' at end of input
    }
    ^
    exit status 1
    'ClearCode' was not declared in this scope
    This report would have more information with
    "Show verbose output during compilation"
    option enabled in File -> Preferences.

Send me a copy of what your code looks like now?

//  ********* 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
char 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 = 200;



#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() {

  int EEPROMCodeOK = true;
  for (Pos = 0; Pos <= (CodeLength); Pos++) {
    Str[Pos] =  EEPROM.read(Pos);
    if (!(strrchr("1123456789", Str[Pos]))) { // must be of proper length and contain only these ASCii charaters
      // not a valid code
      EEPROMCodeOK = false;
    }
  }
  Pos++;
  Str[Pos] =  EEPROM.read(Pos); // get the last value which is the enter Key
  if (Str[CodeLength + 1] != 'E') EEPROMCodeOK = false; // Last Char must be the enter Key 'E'
  if (EEPROMCodeOK) {
    Str[CodeLength + 2] = '\0';
    strncpy(CODE, Str, CodeLength + 1);
  }
  ClearCode();


  Serial.begin(9600);
  Serial.print("Your Code is:"); 
  Serial.println(CODE); // not a good thing to have if it is supposed to be secret lol

  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
  
  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);

  lcd.setCursor(9, 0);

  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 (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() && (Pos + 1) == CodeLength) { // 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
      for (Pos = 0; Pos <= (CodeLength + 1); Pos++) {
        EEPROM.write(Pos, Str[Pos]); // Store the code for next power up
      }
      lcd.setCursor(0, 0); // top left
      lcd.print("Saving Code:");
      lcd.setCursor(0, 1); // bottom left
      lcd.print(Str);  // unlock and Show Saved Code for Conformation



      Serial.print("Save Code:");
      Serial.println(Str);
      Unlocked = true;
    }

    else { 

      lcd.clear();
      lcd.print(" Access Denied.");
      delay(2000);
      lcd.clear();
      lcd.print("Password:");

      Serial.println("Access Denied.");
      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 :)
        lcd.clear();
        lcd.print("     Locked");
        delay(2000);
        lcd.clear();
        Unlocked = false;
        SaveTimer = millis() + 30000; // set timer to allow saving of new code withing the next 30 seconds
      }
    }
    ClearCode();

    
  }

  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(0, 1); // bottom left
    lcd.print(Str);
    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
}

My current code. Modified a few minor things, like when the wrong password is entered, "Access Denied" is printed, or when the door is unlocked and you press the lock button, it prints 'lock' for a short moment.

How can I move the numbers to print on the same lines as "password:" ?

How can I move the numbers to print on the same lines as "password:" ?

change this section of code

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

    Serial.print(SaveTimer > millis());
    Serial.print( Pos == CodeLength);
    Serial.print("Password:\t");
    Serial.println(Str);

  }