Arduino keypad door lock with serial LCD
Wiring 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
}
}