Project – Single button combination lock

Hello Readers

Time for something different  – a single button combination lock. Allow me to explain…

Normally a combination lock would require the entry of a series of unique numbers in order to unlock something or start an action. For example:

(image information)

A more contemporary type of lock could be controlled electronically, for example by a keypad where the user enters a series of digits to cause something to happen. Such as the keypad on this dodgy $30 safe from Officeworks:

As you can see there is a button for each digit. You would think that this would be a good idea –  however people can watch you enter the digits, or users can be silly enough to write down the combination somewhere. In some cases the more cunning monkeys have even placed cameras that can observe keypads to record people entering the combination. There must be a better way. Possibly! However in the meanwhile you can consider my idea instead – just have one button. Only one button – and the combination is made up of the time that elapses between presses of the button. There are many uses for such an odd lock:

  • A type of combination lock that controls an electric door strike, or activates a device of some sort;
  • A way of testing mind-hand coordination for skill, or the base of a painfully frustrating game;
  • Perhaps an interlock on motor vehicle to prevent drink driving. After a few drinks there’s no way you could get the timing right. Then again, after a double espresso or two you might have problems as well.
How does it work? Consider the following:

We measure the duration of time between each press of the button (in this case – delay 1~4). These delay times are then compared against values stored in the program that controls the lock. It is also prudent to allow for some tolerance in the user’s press delay – say plus or minus ten to fifteen percent. We are not concerned with the duration of each button press, however it is certainly feasible.

To create this piece of hardware is quite easy, and once again we will use the Arduino way of doing things. For prototyping and experimenting it is simple enough to create with a typical board such as a Uno or Eleven and a solderless breadboard – however to create a final product you could minimise it by using a bare-bones solution (as described here) or an Arduino Nano. Now let’s get started…

For demonstration purposes we have a normally-open button connected to digital pin 2 on our Arduino-compatible board using the 10k ohm pull down resistor as such:

The next thing to do is determine our delay time values. Our example will use five presses, so we measure four delays. With the following sketch, you can generate the delay data by pushing the button yourself – the sketch will return the delay times on the serial monitor (download).

/* Single-button combination lock Delay Time data generation sketch - John Boxall June 2011 http://tronixstuff.wordpress.com/projects | CC by-sa-nc */  int count=0; unsigned long a[]={0,0,0,0,0,0}; unsigned long del[]={0,0,0,0,0};  void setup() { pinMode(2, INPUT); Serial.begin(115200); Serial.println("Ready..."); }  void dataCapture() { a[count]=millis(); delay(500); // for button debounce, your value may differ count++; }  void displayData() { // calcualate delays between keypresses del[0]=a[1]-a[0]; del[1]=a[2]-a[1]; del[2]=a[3]-a[2]; del[3]=a[4]-a[3];  // display delay data for use in combination lock sketch for (int a=0; a<4; a++) { Serial.println(); Serial.print("Delay "); Serial.print(a); Serial.print(" use "); Serial.print(del[a]); Serial.println(" ms"); } Serial.println("- - - - - - - - -"); count=0; }  void loop() { if (digitalRead(2)==HIGH) { dataCapture(); } if (count>4) { displayData(); } }

So what’s going on the this sketch? Each time the button is pressed a reading of millis() is taken and stored in an array. [More on millis() in the tutorial]. Once the button has been pressed five times, the difference in time between each press is calculated and stored in the array del[]. Note the use of a 500 ms delay in the function dataCapture(), this is to prevent the button bouncing and will need to be altered to suit your particular button. Finally the delay data is then displayed on the serial monitor. For example:

The example was an attempt to count one second between each press. This example also illustrates the need to incorporate some tolerance in the actual lock sketch. With a tolerance of +/- 10% and delay values of one second, the lock would activate. With 5% – no. Etcetera.

Now for the lock sketch. Again it measures the millis() value on each button press and after five presses calculates the duration between each press. Finally in the function checkCombination() the durations are compared against the stored delay values (generated using the first sketch) which are stored in the array del[]. In our example lock sketch we have values of one second between each button press. The tolerance is stored as a decimal fraction in the variable tolerance; for example to have a tolerance of ten percent, use 0.1.

Download link

/* Single-button combination lock - John Boxall June 2011 http://tronixstuff.wordpress.com/projects | CC by-sa-nc */  int count=0; unsigned long a[]={0,0,0,0,0}; unsigned long b[]={0,0,0,0,0}; unsigned long del[]={1000,1000,1000,1000}; // these are the values obtained from running combilock1.pde // delay between each button press is 1000 ms float tolerance=.2;  void setup() { pinMode(2, INPUT); Serial.begin(115200); // for testing purposes Serial.println("Start"); // for testing purposes }  void dataCapture() { a[count]=millis(); delay(500); // for button debounce, your value may differ count++; }  void checkCombination() { int compare=0; count=0; // calcualate delays between keypresses b[0]=a[1]-a[0]; b[1]=a[2]-a[1]; b[2]=a[3]-a[2]; b[3]=a[4]-a[3];  // compare the button delay values if (b[0]<=(del[0]*(1+tolerance)) && b[0]>=(del[0]*(1-tolerance))) { compare++; } if (b[1]<=(del[1]*(1+tolerance)) && b[1]>=(del[1]*(1-tolerance))) { compare++; } if (b[2]<=(del[2]*(1+tolerance)) && b[2]>=(del[2]*(1-tolerance))) { compare++; } if (b[3]<=(del[3]*(1+tolerance)) && b[3]>=(del[3]*(1-tolerance))) { compare++; } if (compare==4) { success(); } if (compare!=4) { failure(); } }  void success() { // contains code to run when combination successfully entered Serial.println("Success!"); delay(5000); Serial.println("- - - - -"); }  void failure() { // contains code to run when combination unsuccessfully entered Serial.println("Failure!"); delay(5000); Serial.println("- - - - -"); }  void loop() { if (digitalRead(2)==HIGH) { dataCapture(); } if (count>4) { checkCombination(); } }

When choosing your time delays, ensure they are larger than the value used for button debounce (the delay() function call) in the dataCapture() function. Notice the two functions success() and failure() – these will contain the results of what happens when the user successfully enters the combination or does not.

If you are looking to control various types of circuitry or devices with this sketch, you may find the following of interest:

For a demonstration of the final product, I have connected an LCD to display the outcomes of the entry attempts. You can download the sketch from here. The key used in this example is 1,2,3,4 seconds:

Although there are four buttons on the board used in the vide, only one is used. The board is a generic ‘button  board‘ whose purpose is to make using buttons easier when prototyping.

Well I hope someone out there found this interesting. Feel free to modify and use the sketches in your own projects and other nefarious ideas. Furthermore, to keep up with new activities here at tronixtuff please subscribe to the blog, RSS feed (top-right), twitter or joining our Google Group.

If you have any questions about the processes or details in this article, please ask in our Google Group – dedicated to the projects and related items on this website. Sign up – it’s free, there is the odd competition or give-away –  and we can all learn something.

Otherwise, have fun, stay safe, be good to each other – and make something!

Advertisements
By John Boxall

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s