Arduino keypad door lock with serial LCD

 

Wiring Diagram:

diagram

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Code:

 

 

/*
Arduino keypad door entry with serial LCD output by Andrew Grayson - 2013.
 
Thanks for this go to Google, Arduino.cc, Instructables and the wonderfully talented people who create things and help clueless people like me understand how they did it.
 
This project uses a standard 12 button keypad to operate a servo that can pull a door lock.
A 20 x 4 serial LCD is used in this example so that it will operate on an UNO but if you have a mega then you can use a parallel LCD as it has more pins.
 
The buzz function was written by Rob Faludi - http://www.faludi.com/2007/04/23/buzzer-arduino-example-code/
 
This code is in the public domain.
 
Wiring for Serial I2C LCD:
SCL > Arduino A5
SCA > Arduino A4
GND > GND
VCC > +5v
 
Wiring for Servo:
Black/Brown > GND
Red > +5v
Orange/White (signal) > Arduino Pin 3
 
Wiring for Keypad:
This is a little tricky and depends on your model of keypad. The one used in this example is made by Sparkfun.
 
The pins on the keypad correspond to the three columns and four rows.
The columns from left to right are pins 3, 1, 5.
The rows from top to bottom are pins 2, 7, 6, 4.
So pressing button 5 will create a circuit between pins 1 and 7 on the keypad.
 
Pin 1 > Arduino 11
Pin 2 > Arduino 9 and also to a 10k Ohm resistor then to Arduino +5v
Pin 3 > Arduino 12
Pin 4 > Arduino 6 and also to a 10k Ohm resistor then to Arduino +5v
Pin 5 > Arduino 10
Pin 6 > Arduino 7 and also to a 10k Ohm resistor then to Arduino +5v
Pin 7 > Arduino 8 and also to a 10k Ohm resistor then to Arduino +5v
 
Wiring the buzzer:
+ > Arduino 4
- > 100 Ohm resistor > Arduino GND
 
Wiring the green "success" LED
+ > Arduino 1
- > resistor (between 300 Ohm and 1K Ohm) > Arduino GND
 
Wiring the red "fail" LED
+ > Arduino 2
- > resistor (between 300 Ohm and 1K Ohm) > Arduino GND
*/
 
#include <Keypad.h> //Library for the matrix keypad available from http://playground.arduino.cc/code/Keypad
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h> //You must use F. Malpartida's new LCD library for Serial LCD https://bitbucket.org/fmalpartida/new-liquidcrystal/wiki/Home
#include <Servo.h> 
 
#define I2C_ADDR    0x3F  // Define I2C Address for the LCD. This varies by device, see the data sheet for yours
// Set up serial to parallel configuration for LCD
#define BACKLIGHT_PIN 3
#define En_pin  2
#define Rw_pin  1
#define Rs_pin  0
#define D4_pin  4
#define D5_pin  5
#define D6_pin  6
#define D7_pin  7
 
// define a servo instance
Servo myservo;
// define an LCD instance
LiquidCrystal_I2C lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);
// define keypad mapping
const byte ROWS = 4; // Four rows
const byte COLS = 3; // Three columns
// Define the Keymap. Note the position of # and * alter between models
char keys[ROWS][COLS] = {
  {'1','2','3'},
  {'4','5','6'},
  {'7','8','9'},
  {'*','0','#'}
};
 
// Connect keypad ROW0, ROW1, ROW2 and ROW3 (top to bottom) to these Arduino pins.
byte rowPins[ROWS] = { 
  9, 8, 7, 6 };
// Connect keypad COL0, COL1 and COL2 (left to right) to these Arduino pins.
byte colPins[COLS] = { 
  12, 11, 10 }; 
 
// Create the Keypad instance
Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
 
 
void setup(){
   pinMode(4, OUTPUT); // pin for buzzer output
   pinMode(1, OUTPUT); // pin for green LED
   pinMode(2, OUTPUT); // pin for red LED
   
   myservo.attach(3); //Servo signal attached to pin 3
   
   lcd.begin (20,4); // initialise LCD
   
   myservo.write(179); // set servo position to one extent
 
   // Switch on the backlight
   lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
   lcd.setBacklight(HIGH);
   // clear the LCD
   lcd.clear();
   // move the cursor top left
   lcd.home();
   // print a message on the LCD to enter the code
   lcd.print("********************");
   lcd.setCursor(0, 1);
   lcd.print("Enter Code:(#cancel)");
   lcd.setCursor(0, 3);
   lcd.print("********************");
   // move the cursor to a blank line for code entry
   lcd.setCursor(0, 2);
}
 
void loop(){
 
  String mastercode = "275012"; // the password
  String enteredcode = ""; // the code you enter
  String reason = "   INCORRECT CODE   "; // the default reason why entry failed
  // read a 6 digit code (you can have any length)
  for (int i = 0; i < 6; i++){
    char key = kpd.waitForKey();
    if(key == '#'){ // # is used to cancel
      i = 6; //skip to the end
      reason = "      Cancelled     "; // set the other reason why entry failed. You pressed # to cancel if you pressed a wrong number
    }
    if(key != NO_KEY){ // if you aren't reading no keypress
      lcd.print("#"); // print a # to the LCD so people don't see the number but you know you pressed a button
      enteredcode += key; // append the keypress to the end of the entered code string
    }
  }
 
  if (enteredcode == mastercode) // if the code is correct
  {
    lcd.setCursor (0, 2);
    lcd.print("                    ");
    lcd.setCursor (0, 2);
    lcd.print("    CODE CORRECT    "); // print a success message
    digitalWrite(1, HIGH); // turn on the green LED
    myservo.write(0); // move the servo 180 degrees and open the door lock
    // make 3 beeps
    buzz(4, 2500, 100);
    delay(200);
    buzz(4, 2500, 100);
    delay(200);
    buzz(4, 2500, 100);
    delay (3000); // wait 3 seconds while the door is opened
    digitalWrite(1, LOW); // turn off the LED
    myservo.write(179); // close the door lock
    //reset the LCD for the next user
    lcd.clear();
    lcd.home();
    lcd.print("********************");
    lcd.setCursor(0, 1);
    lcd.print("Enter Code:(#cancel)");
    lcd.setCursor(0, 3);
    lcd.print("********************");
    lcd.setCursor(0, 2);
  }
  else {  // if the code is wrong or cancelled
    // tell the user what happened
    lcd.setCursor (0, 2);
    lcd.print("                    ");
    lcd.setCursor (0, 2);
    lcd.print(reason); // display the reason for failure. Incorrect code by default unless cancel is pressed
    digitalWrite(2, HIGH); // turn on the red LED
    buzz(4, 2500, 500); // make a long fail beep
    delay (3000); // wait 3 seconds before allowing a retry
    digitalWrite(2, LOW); // turn off LED
    // reset the LCD for the next try
    lcd.clear();
    lcd.home();
    lcd.print("********************");
    lcd.setCursor(0, 1);
    lcd.print("Enter Code:(#cancel)");
    lcd.setCursor(0, 3);
    lcd.print("********************");
    lcd.setCursor(0, 2);
 
  }
 
 
}
 
// function for making beeps written by Rob Faludi -  http://www.faludi.com/2007/04/23/buzzer-arduino-example-code/
 
void buzz(int targetPin, long frequency, long length) {
  long delayValue = 1000000/frequency/2; // calculate the delay value between transitions
  //// 1 second's worth of microseconds, divided by the frequency, then split in half since
  //// there are two phases to each cycle
  long numCycles = frequency * length/ 1000; // calculate the number of cycles for proper timing
  //// multiply frequency, which is really cycles per second, by the number of seconds to 
  //// get the total number of cycles to produce
 for (long i=0; i < numCycles; i++){ // for the calculated length of time...
    digitalWrite(targetPin,HIGH); // write the buzzer pin high to push out the diaphram
    delayMicroseconds(delayValue); // wait for the calculated delay value
    digitalWrite(targetPin,LOW); // write the buzzer pin low to pull back the diaphram
    delayMicroseconds(delayValue); // wait againf or the calculated delay value
  }
}