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
![]()
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!