Physical Pattern Lock

by taifur in Circuits > Sensors

9287 Views, 110 Favorites, 0 Comments

Physical Pattern Lock

1.jpg
2.jpg

The pattern lock of Android device fascinates me. From the inspiration of Android pattern lock I made a physical pattern lock using IR sensors and Arduino microcontroller. You can use the lock where some sort of security is required such as your home or office.

No more tension about losing the keys!!!

The lock has following features:

  • Contains 9 sensors and lots of patterns are possible
  • Pattern change button to change the pattern anytime.
  • LED Indication for wrong and right pattern
  • Blocking facility for multiple wrong try
  • Power saving mode

Demo Video

Bill of Materials

Freetronics_ATmega328P_.png
lth1550.jpg
Component_Switch_Button_SW02_01.jpg
resistor-grab_large.png
64-8933-0.jpg
acrylic_sheets_clear-xl.jpg
11231-01b.jpg

Components

1. Photointerrupter (LTH-1550-01) (Seeedstudio.com)

2. ATmega328 with Arduino Optiboot (Sparkfun.com)

3. Mini Pushbutton Switch (Sparkfun.com)

4. Resistor 220 ohm (12 pcs)

5. Resistor 15k (10 pcs)

6. Resistor 1k (1 pcs)

7. Perfboard (3.5" x 2")

8. Acrylic Sheet (2" x 2")

9. Arduino (for programming the microcontroller)

10. General purpose transistor (2N2222 or equivalent- 1 pcs)

11. Lithium Ion Battery - 850mAh (Sparkfun.com)

12. LiPo Charger/Booster (Sparkfun.com)

13. Some jumper wires

Tools

1. Soldering Iron (Sparkfun.com)

2. Hot Glue Gun (Seeedstudio.com)

3. Diagonal Pliers (Seeedstudio.com)

How It Works

Pattern-lock.png
LTH-1550-01-pinout.jpg
328p-pinout.jpg
4.-Working-principle-of-IR-sensor.jpg

The principle behind this pattern lock is very simple. I used 9 photointerrupters (Reflective Object Sensor) to implement the pattern. A photo interrupter integrates a infrared photodiode and an phototransistor in a single package. Photodiode emits a beam of infrared light and if any object places above the sensor's face the light is reflected back to the base of the phototransistor and works as a close switch. In my circuit each sensor is connected to a Arduino digital pin with a pull-up resistor. If a finger is placed in the sensor arduino reads it as logic zero as like a button press. Nine sensors are connected to nine different digital pin of the Arduino. When drawing a particular pattern you are actually pressing several buttons one after one. Arduino reads all the input and stores the result in an array according to the sequence you press. Then it is compared to the predefined sequence and if match then considered as a right pattern.

I included two momentary buttons into the circuit, one for updating the pattern and another for waking up the Arduino from the sleep mode. Avr deep sleep mode is implemented for saving the power as it is a battery power device. When no button is press or Arduino doesn't receive any pattern for five seconds then it goes to deep sleep mode. Wake up button is connected to the INT0 (interrupt zero) pin of the arduino and wake up from the deep sleep as you know an external interrupt can wake up arduino from sleep mode.

Two LEDs are connected to the circuit for indicating the actions and the results (given pattern is right or wrong or want to change the pattern). For the right pattern green led blinks for three times and for any wrong pattern red led blinks three times.

For updating the pattern you first need to enter the right pattern and then need to press the update button. Glowing red led means it is ready to take new pattern. After giving a pattern green led blinks two times for successful update.

Schematic for the complete system, pin-out for the sensors and the datasheet are attached in the step.

Soldering the Sensors

2.jpg
3.jpg
4.jpg
5.jpg

In a 2 inch x 3.5 inch perfboard place all 9 sensors as like attached photo and solder all with a soldering iron. The gap between each sensor should be identical. You should also place the sensors in the board in such a way that all are identically place considering the pin-out of the sensors to make the soldering easier. Connect a 220 ohm current limiting resistor to every photo diode to keep it safe from burning out. The value of the resistor may be slightly different. Follow the device datasheet for details. A 15k pull-up resistor must be connected to the collector pin of the photo transistor. Changing the value may change the sensitivity of the sensor. I found good performance for 15k but higher value should also work. For completing all the connection you may required some jumper connection. I used all jumper wires at the bottom side to keep it clean at the top as it will be the visible part.

Are you new in soldering? You may follow the link below:

Soldering the Microcontroller

2.jpg
4.jpg
5.jpg
6.jpg

For soldering the Arduino microcontroller to the circuit board I used 28 pin IC base. Using an IC base without directly soldering an IC to the perfboard has some advantages and you can easily remove or replace an IC without desoldering. Connect a 16 MHz crystal with two 22pf capacitor. Capacitors provide batter stability for the crystal and microcontroller.

I used a 2N2222 general purpose transistor to drive all the photodiodes. The base of the transistor is connected to the digital pin #3 of the arduino. Driving photodiodes with transistor and microcontroller gives me the opportunity to turn of the sensors when arduino is in sleep mode and reduce the power consumption in a great extent. If you connect all the sensors directly to the power supply then it is not possible.

So, solder a transistor to the board in a convenient location. Don't forget to add a 1k resistor to the base of the transistor.

Soldering Buttons & LEDs

2.jpg
1.jpg
3.jpg
4.jpg

Now, connect two momentary buttons, one green LED and one red LED to the board according the circuit diagram. Don't forget to connect current limiting resistor with the leds. Always try to put any button in a easy accessible place of a circuit board. I put both button at the bottom edge of the circuit board. No pull up resistor is required with the button switch as internal pull up resistor is enabled in the arduino sketch. You may require several jumper connections to complete the circuit. I suggest to connect all jumper wires to the bottom side of the board to keep top side good looking.

Attaching Acrylic Sheet

1.jpg
2.jpg
3.jpg
4.jpg
5.jpg
6.jpg

Take a thin 2" x 2" transparent acrylic sheet and place it to the top of the sensor's face. Place it in such a way that, it perfectly aligns with the circuit board. Then use hot glue around the sides to fix the acrylic sheet with the circuit board. Follow the photos attached above. The acrylic board should be thin enough otherwise it may effect the sensors output. Use as thin as you get, mine is 3mm thick and working perfectly.

Attaching the Lock (Funny Thing)

1.jpg
2.jpg
3.jpg
4.jpg
5.jpg

This is the funnest part of the project. I attached a lock at the back side of the circuit board using hot glue. Use enough glue to keep the lock separate from the circuit board otherwise it can short the pads. Then I attached the key of the lock with a 9g micro servo. After that I fixed the servo in the circuit board. I kept all perfectly aligned when glued with the board.

For the right pattern the servo rotates the key at 45 degree to open the lock. You see here both lock and key are attached with the circuit board with glue. It is a funny approach and only for demonstration. But this may be done if you can enclose lock, key and the servo within a hard and durable box. You can also implement the pattern circuit in any other lock in a creative way.

Uploading Program

Arduino_standalone_breadboard_led.jpg
8612350288_325dce77a8_c.jpg

The program for the microcontroller was developed in Arduino environment. I used Arduino UNO for uploading the program to the microcontroller and then I remove the IC from the UNO board and placed the microcontroller to the circuit board. For storing the updated pattern I used internal EEPROM of the Arduino microcontroller. The simple demo sketch is attached at the bottom of the step.

#include 
//1-26, 4-27, 7-28, 2-19, 3-16, 5-23, 6-17, 8-18, 9-15 (ic-pin)
//1-17, 2-13, 3-10, 4-18, 5-14, 6-11, 7-19, 8-12, 9-9 (Arduino)
 //EEPROM.write(address, value)
  //EEPROM.update(i, i);
  //value = EEPROM.read(a);
#include 
Servo myservo;  // create servo object to control a servo
const byte one = 17;
const byte two = 13;
const byte three = 10;
const byte four = 18;
const byte five = 14;
const byte six = 11;
const byte seven = 19;
const byte eight = 12;
const byte nine = 9;

int set_pattern[9] = {1,2,3,5,7,8,9}; //Z pattern
int try_pattern[9];
int pattern_number;
int try_number = 0;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  myservo.attach(3);  // attaches the servo on pin 9 to the servo object
  myservo.write(0); 
  pinMode(one, INPUT_PULLUP);
  pinMode(two, INPUT_PULLUP);
  pinMode(three, INPUT_PULLUP);
  pinMode(four, INPUT_PULLUP);
  pinMode(five, INPUT_PULLUP);
  pinMode(six, INPUT_PULLUP);
  pinMode(seven, INPUT_PULLUP);
  pinMode(eight, INPUT_PULLUP);
  pinMode(nine, INPUT_PULLUP);
  pinMode(15, OUTPUT);
  pinMode(16, OUTPUT);
  pinMode(7, INPUT_PULLUP);
  pinMode(2, INPUT_PULLUP);
}

long previous_millis = millis();

void loop() {
  // put your main code here, to run repeatedly:
  // any button is or within 2s, it is in a trial
  if(button_read() || ((millis() - previous_millis) < 3000)){
  if(button_read()>0){
    if(try_number>0){
      if(button_read() != try_pattern[try_number-1]){
        try_pattern[try_number] = button_read();
        try_number++;
         }
       }
    else{
      try_pattern[try_number] = button_read();
      try_number++;
       }
    previous_millis = millis();
     }      
  } 
  
  if(try_number>0 && !button_read() && ((millis() - previous_millis) > 3000)){
    if (array_cmp(set_pattern, try_pattern, try_number) == true){
           // correct pattern
      //  if(!button_read){ //unlock
           Serial.println("Correct Pattern");
           digitalWrite(15, HIGH);
           delay(500);
           digitalWrite(15, LOW);
           delay(300);
           digitalWrite(15, HIGH);
           delay(500);
           digitalWrite(15, LOW);
           delay(300);
           digitalWrite(15, HIGH);
           delay(500);
           digitalWrite(15, LOW);
           delay(300);
           open_lock();
        
    }else{
           // wrong pattern
           Serial.println("Wrong Pattern");
           digitalWrite(16, HIGH);
           delay(500);
           digitalWrite(16, LOW);
           delay(300);
           digitalWrite(16, HIGH);
           delay(500);
           digitalWrite(16, LOW);
           delay(300);
           digitalWrite(16, HIGH);
           delay(500);
           digitalWrite(16, LOW);
           delay(300);
    }
   array_nul(try_pattern,  try_number);
   try_number = 0; 
  }

  if(!button_read() && ((millis() - previous_millis) > 5000)){
   //May sleep here
  }
 delay(100); 
}

int button_read(){
  if(!digitalRead(one))
    { Serial.println("1");
      return 1;}
  else if(!digitalRead(two))
    { Serial.println("2");
      return 2;}
  else if(!digitalRead(three))
    { Serial.println("3");
      return 3;}
  else if(!digitalRead(four))
    { Serial.println("4");
      return 4;}
  else if(!digitalRead(five))
    { Serial.println("5");
      return 5;}
  else if(!digitalRead(six))
    { Serial.println("6");
      return 6;}
  else if(!digitalRead(seven))
    { Serial.println("7");
      return 7;}
  else if(!digitalRead(eight))
    { Serial.println("8");
      return 8;}
  else if(!digitalRead(nine))
    { Serial.println("9");
      return 9;}
  else {
    Serial.println("0");
    return 0;}
}

boolean array_cmp(int *a, int *b, int len){
     int i;
     // test each element to be the same. if not, return false
     for (i=0;i

Testing

IMG_20170314_145545.jpg
IMG_20170314_145526.jpg

As you uploaded the program to the IC, now you are ready to power up the circuit and test your creation. A 3.7V li-ion battery is capable to drive the circuit with servo motor. Though I found it working, it will be good if you attach a 5 V boost converter module to the battery and then supply the power to the circuit. It will increase the stability of the system. You should also attach a battery management circuit for charging the battery. After powering the circuit test it using 'Z' pattern as it is defined in the code.

Arduino deep sleep is use to save the power. A single charging can drive the system more than five month but it depends on your use.