Make An Auto-Locking Office Door with Smartphone Proximity Sensor
Pinterest Stumbleupon Whatsapp

Pssst – want some high tech protection for your home office, or a secret lock for your “workshop” (ok, you got me, it’s actually a dungeon/gaming room) that the kids won’t be able to figure out? We’ve got you covered. Let’s build a DIY smart lock that automatically detects when you’re there, and locks when you’re not.

How does it work? NOBODY KNOWS! Or more specifically, Bluetooth.

The Concept

Your smartphone is a powerful device that’s constantly revealing information about itself to the outside world; one way it does this is Bluetooth.

In discovery mode, it broadcasts a unique identification number – but even when not specifically allowing itself to be discovered, anything that knows that address can try to ping it. If a response is heard, that would indicate whether it’s in range or not.

We’ll be setting up a Raspberry Pi with a Bluetooth adapter to constantly be on the lookout for when your smartphone is out of range, and when it is, the relay will snap into action and lock the door.

You Will Need

  • Raspberry Pi – any model should work since it’s not an CPU intensive task, but I’m using a older model B, and the GPIO pinouts may be slightly different on your model. See the section on board mode below. You’ll also need some basics like a wired Ethernet connection or Wi-Fi configured Setting Up Wireless Networking on Your Raspberry Pi Setting Up Wireless Networking on Your Raspberry Pi Virtually every Raspberry Pi project will require a network connection, and considerable flexibility can be gained by ignoring the Ethernet port in favour of a wireless USB dongle. Read More ; plus SD card and micro USB power cable.
  • Bluetooth USB adaptor. Adafruit sells a Bluetooth 4.0 BLE module confirmed working (what’s Bluetooth 4.0? How Bluetooth 4.0 Is Shaping the Future of Mobile Connectivity How Bluetooth 4.0 Is Shaping the Future of Mobile Connectivity Bluetooth is the forgotten star on the device specifications sheet. Read More ), but you should test any you already have lying around before purchasing a new one just for this project. I found an old standard Bluetooth mini adaptor I bought in Japan that appears to work fine. We don’t care about transfer speeds or connection reliability, as all we’re doing is sending out a quick handshake to see if a device is alive and well.
  • GPIO breakout board (“cobbler”) and jumper cables. You could work directly from the pins on the Pi, but it’s a lot easier if you have labels on each pin, and they’re only $6 anyway.
  • Relay board. You’ve got a wide variety of choices here, and anything will work if it’s designed for use with a microcontroller and can drive at least 12 volts at 5 amps. I’ve used a generic 4-channel board similar to this one for around $5, but I’m going to assume you know how to work yours.
  • 12/24V electromagnet lock, though an electronic solenoid lock should also work. The one I purchased has 180KG holding force and comes complete with mounting plates and instructions, for about $35.
  • 12/24V power supply. The magnet lock must have a separate power supply – whatever you do, don’t try to pull power for it from the Pi.
  • Python app, but we’ll write this as we go along.

Working with Bluetooth

Bluetooth is central to this project, so let’s start by installing some Bluetooth support and test our adapter. You can either do this directly from the Pi, or SSH in remotely (how to set up Windows to SSH into you Pi Setting Up Your Raspberry Pi For Headless Use With SSH Setting Up Your Raspberry Pi For Headless Use With SSH The Raspberry Pi can accept SSH commands when connected to a local network (either by Ethernet or Wi-Fi), enabling you to easily set it up. The benefits of SSH go beyond upsetting the daily screening... Read More ).

sudo apt-get install bluez python-bluez

Insert your dongle if you haven’t already, and let’s have a look at what it’s reporting.

hcitool dev

If you have something listed in the output, you’re good to go. Next we’ll use a Python script to poll for nearby Bluetooth devices, and grab the unique device address. We only need to do this once for each device.


If you see “0 devices found”, you either don’t have a compatible USB Bluetooth dongle, or your smartphone isn’t discoverable. Don’t despair though: I found I had to actually open the Bluetooth settings page on my iPhone to kick it into discovery mode, then this happened:

bluetooth identified

Great, now let’s create the first stage of our software that do the detection. Create a Python app called, and open it with Nano.


Paste in this sample code:


import bluetooth
import time

while True:
    print "Checking " + time.strftime("%a, %d %b %Y %H:%M:%S", time.gmtime())
    result = bluetooth.lookup_name('78:7F:70:38:51:1B', timeout=5)
    if (result != None):
        print "User present"
        print "User out of range"


and adjust the following line with your Bluetooth device address:

result = bluetooth.lookup_name('78:7F:70:38:51:1B', timeout=5)

Press CTRL-X and Y to close and save. Run the same code, and you see something like this:

user present detectpy

The code should be very simple to understand even if you’ve never touched Python before: it’s scanning for a particular Bluetooth device every 10 seconds, and it prints out a different message depending on whether it’s found or not. Toggle the Bluetooth on your phone to simulate moving in and out of range (probably about 4m in reality). You can decrease or increase the time between scans, but I felt 10 seconds was a reasonable amount of time to potentially have to wait for the door to unlock, which is where we’re going with this whole project after all.

I should add, I don’t know about the power consumption of doing this, but I would assume pinging a device more often would necessarily consume more power. I haven’t seen any obvious performance issues in testing, but if battery life is a serious concern for you, consider having a switch inside your office which activates and deactivates the scan loop, so once you’re inside, you can pause the lock system, then re-activate the scanning when you leave.

Congratulations, you now have a Python app that knows when you’re within range, so we can start to act on that.

GPIO Board Modes

Before continuing, you need to figure out which board mode you’re going to use. There’s no right or wrong answer, it just affects whether you specify the literal pin number or the virtual GPIO pin number.

The default is to use the literal pin number (“board mode”), starting with pin 1 in the bottom left (if looking down at the Pi with USB ports on the right). Pin 2 is just above that.

However, if you have a GPIO breakout (“cobbler”) board, the labels you have are from an alternate mode, called “BCM” (Broadcom SOC channel), and are commonly written with GPIO or P prefixing the number. You don’t strictly need a GPIO breakout – it just makes things easier. If you don’t have a breakout board and don’t want to buy one, use this diagram:

Raspberry Pi model A and B pinout diagram from
Raspberry Pi model A and B pinout diagram from

Note that the original model B revision 1, revision 2, and the model B+ and Pi2 all have different pin outs. Refer to this StackExchange question for a diagram correct to your board.

In this project code, I’m using the BCM GPIO numbering system which corresponds to the Adafruit breakout board I have. Minor modifications are needed if you wish to use the literal pin mode.

Wire in a Relay

Attach the breakout board, ensuring that the wire from pins 1 and 2 (the ones in the corner of your Pi) attach to 3v3 and 5V0 on the breakout. You might want to pull out a voltage tester to check this.

rpi smart lock - gpio

Before proceeding, check if anyone else has used your particular relay with the Raspberry Pi (or find one beforehand that you know works). Some may require 5V to activate – but the RPi can only provide 3.3V on the GPIO output pins. By chance, the one I’m using is happy with 3.3V, so I didn’t need any additional circuitry, just the 5V0 to VCC, GND to GND, and GPIO pin 23 for the first relay input.

My previous tutorial on GPIO Getting Started With GPIO On a Raspberry Pi Getting Started With GPIO On a Raspberry Pi If you though the Arduino was cool, just wait till you get your hands on a Raspberry Pi - these things are amazing. As well as being a fully functional computer, they also have a... Read More showed how to wire up a transistor circuit to scale up 3.3V to a full 5V if you need to (in fact, I used the same relay board for that tutorial, but it turns out I didn’t need 5V after all).

No need to wire in the electromagnet yet, as you’ll be able to hear an audible click when the relay fires.

Next up, let’s grab some code to interact with the GPIO ports.

We’ll start by testing outside of Python to confirm everything is working on the ports themselves. Install wiringPi, which gives you some useful command line tools.

git clone git://
cd wiringPi

Once installed, configure GPIO pin 23 to be an output.

gpio -g mode 23 out

Now, do a quick scan of all the ports to confirm

gpio -g readall

You’ll have something similar to this, though yours may be longer on a model B+ or Pi2 since it has more GPIO pins:

gpio readall


This can be a bit confusing at first, but the table is split down the middle and the column order is reversed on each side. On the far left and far right is the BCM pin number. Since we’re using 23, you should see the mode listed now as OUT. This is a useful little command just to get a good idea of what’s going on with all your pins at any point.

To write the pin high or low, just use

gpio -g write 23 1
gpio -g write 23 0

Hopefully, if you have the relay wired correctly, you’ll hear it clicking on and off. If not, don’t continue until you’ve figured out the wiring. Remember, you may need a higher voltage to activate the relay.

Once you’ve confirmed the relay and GPIO is working, add the Python modules for GPIO.

sudo apt-get install python-dev python-rpi.gpio

Now let’s modify our Python app to trigger the relay on or off when the phone is detected. You’ll find the final code at this Gist. Copy the existing to a new, and add the following import and setup commands:

import RPi.GPIO as GPIO
RELAY = 23

In the IF statement, add a command to either activate or deactivate the relay. Note that your relay may work with either a low or a high signal, so adjust accordingly after testing.


To run this new version, prefix the command with sudo – access to GPIO requires root privileges.

Hooking It Up

Once you’ve confirmed the relay is firing with your proximity sensor, add in your electromagnet lock. On the relay side, bring the 12V positive into the terminal labelled COM (common), then the positive power input from the electromagnet to the NO terminal (normally open, ie. this is normally not connected to the common terminal but will be when you activate the relay).

Join the ground from the power supply and the electromagnet on the GND terminal.

rpi smart lock - relay

Refer to the fitting instructions that came with your lock; the door needs to be quite thick, and it’s easier if it opens away from the side you want the lock to be on. Mine was the opposite, so I need the L-shaped mounting bracket, as well as an additional bit of wood to increase the door thickness.

rpi smart lock - electromagnet


This was a proof of concept for me to build on with other projects, and really just to keep prying eyes out of my office when I’m not there – it’s not designed to be a foolproof security system. For that, you’d need a backup battery to keep the power flowing in the event of being cut.

Of course, if someone breaks into your house and goes to the trouble of cutting your power, you’ve probably got the bigger issue of them being a psychopath who’s out to kill you, rather than a casual burglar. You’d also want a physical deadbolt lock in addition to an electronic one, and a really big stick.

Of course, this proximity detection technique using Bluetooth isn’t just limited to an automatic door lock – you could also use it to trigger your garage door opening when you come home, or turn on your home cinema before you walk in the door.

What feature do you think I should add next? Did you have any problems building this? Let me know in the comments and I’ll do my best to help!

Leave a Reply

Your email address will not be published. Required fields are marked *

  1. Liam Blom
    January 8, 2018 at 12:46 pm

    Good day,

    That you for this! Works perfectly.

    What changes would I have to do to the python script to use this in my car as a key less entry solution? The GPIO should only be triggered for a second and only once the status goes from "User out of rage" to "User Present", not every time the Bluetooth devices is found (every 10 seconds).

    Kind Regards

    • James Bruce
      January 9, 2018 at 9:26 am

      Start by making a new variable, like "opened", that you check for in this line:

      if (result != None):

      change that to say "if there's bluetooth results is not null AND if not opened yet"

      then open the door, and change variable to true.

      Once out of range is detected, change "opened" back to false.

      Next, to change the relay timing, instead of just turning it on, you could turn it on, wait for 1 second, then turn it off. (Lookup python time.sleep function).

  2. Nathan Aguiar
    November 2, 2016 at 7:10 pm

    would this all be the same for the pi zero 1.3?

  3. Paolo Bernabe
    October 29, 2016 at 2:05 pm

    Sir i have a question, I have a 12v relay and how can I connect it to the raspberry pi without damaging it. I tried a lot of methods but my relay is not clicking but the python code is working. I'm also doing a locking system with raspberry pi.

  4. Learning Pi
    September 27, 2016 at 9:34 pm

    Can more than 1 bluetooth device be added to the script? Ie a list of employees.

    • James Bruce
      September 28, 2016 at 7:42 am

      Yes. Just duplicate these lines:

      result = bluetooth.lookup_name('78:7F:70:38:51:1B', timeout=5)
      if (result != None):
      print "User present"

      with another address. I would skip the else statement or you'll have a list of users not there. Instead, just output when a user is present. You'll probably want to ping a URL to report presence though, not just output to the screen. You'll find our guide on integrating this with OpenHAB here:

  5. Jonathan Pereira
    June 23, 2016 at 9:23 am

    Is the code compatible with the inbuilt Bluetooth LE in the Raspberry Pi 3

    • James Bruce
      June 24, 2016 at 9:11 am

      Good question. You should have a go and report back!

  6. Joanna Christine Bernard
    June 11, 2016 at 2:39 pm

    Hi i just bought a bluetooth usb adapter but i cant get to pair with my handphone
    any suggest ?

  7. Lukas
    May 23, 2016 at 10:17 pm

    The script is offline, where can i get it? Thanks in advance

  8. Naqqash
    April 11, 2016 at 3:10 pm

    Hi James,
    Very nice tutorials. I came across your website when I was setting up openhab for my raspberry pi.
    Can you point me to any useful resource which I can use to create a "binding" for a setup of my own. Let say you want to add this locking system into your openhab how would you do it. I assume there is no binding available so one has to create a binding for the system above. Any tips will be highly appreciated.

  9. Jan Derk
    April 6, 2016 at 9:05 am

    Is it also possible to detect 2 or 3 i-phones/telephones for this project ? So i can add multiple users for this project.

    • James Bruce
      April 8, 2016 at 8:58 am

      I suck at Python programming, but a quick hack to do this would be to nest the if statements on failure, like:

      result = bluetooth.lookup_name('78:7F:70:38:51:1B', timeout=5)
          if (result != None):
              print "User present"
              result = bluetooth.lookup_name('79:7F:70:38:51:1B', timeout=5)
              if (result != None):
              	print "Other user present"
          		print "No one at all here"
  10. Anonymous
    February 27, 2016 at 3:08 pm

    Copy the existing to a new
    How do i make a new ?

    • James Bruce
      February 29, 2016 at 10:37 am

      Just type:


      This is the linux command for copy, original file into a new file.

      • Anonymous
        March 1, 2016 at 9:17 pm

        Ok thanx. I did copy te script from "at this Gist" and put my adres from my phone into the script. at nano So what should i do next? help...

        • James Bruce
          March 2, 2016 at 8:23 am

          Yuu need to wire up the relay next - that's the final code you've got, so you can continue on to "hooking it up" section.

        • Jan Derk Schuitema
          March 2, 2016 at 10:40 pm

          The relay is connected. But nothing happens if i turn on/off bluetooh.
          And what about the next lines ? IF statement ?? Pefix the command with sudo ??

          In the IF statement, add a command to either activate or deactivate the relay. Note that your relay may work with either a low or a high signal, so adjust accordingly after testing.


          To run this new version, prefix the command with sudo – access to GPIO requires root privileges.

        • James Bruce
          March 3, 2016 at 8:57 am

          Did work at the start of the tutorial? ie, is it actually detecting your phone, without the relay stuff? You need to make sure that one is working first before moving onto the electronics stuff.

          "Prefix" means "Put before". So that means type:

          sudo python

          to run the version that accesses GPIO.

        • Anonymous
          March 3, 2016 at 5:57 pm

          Yes that works allright
          Ok iwill try that and see what it does.

        • Anonymous
          March 3, 2016 at 6:31 pm

          Ok yes now its working. Tank you for youre time to help me

        • Jan Derk
          March 18, 2016 at 10:39 pm

          How do i start the script: sudo python ? after reboot or new start ?

        • James Bruce
          March 19, 2016 at 9:03 am

          Add it to your rc.local file. Start with

          sudo nano /etc/rc.local

          Then add a line before the exit 0:

          sudo python /home/pi/ < /dev/null & (or wherever your is stored, I've just assumed the pi home directory there). Save by hitting CTRL-X, then Y. Then if this is the first time you've used rc.local, you'll need to set the execute bits on it, with the command: sudo chmod +x /etc/rc.local

        • Jan Derk
          March 19, 2016 at 7:39 pm

          Ok that works fine. Nice tutorial. Thanks again...

  11. Angus Parker
    January 1, 2016 at 6:18 am

    I am very new to RPi. I have the RPi 2 and i am have the bluetooth and relay connected and can toggle using the gpio -g write 23 1
    gpio -g write 23 0 commands.

    I am having problems with the script and hope someone can help me. I can't get the relay to toggle. I am using the Keyes 4 channel relay board. Please look at this script .


    import bluetooth
    import time

    while True:
    print "Checking " + time.strftime("%a, %d %b %Y %H:%M:%S", time.gmtime())
    result = bluetooth.lookup_name('68:DB:CA:BE:B8:4E', timeout=3)
    if (result != None):
    print "User present"
    print "User out of range"


    import RPi.GPIO as GPIO
    RELAY = 23

  12. Anonymous
    October 1, 2015 at 5:02 pm

    Dude, why don't you make it a product and sell it to consumers? Great invention!

  13. Anonymous
    August 18, 2015 at 11:03 am

    Hi thank you very much now the bluetooth problem is solved :)

  14. Anonymous
    August 15, 2015 at 6:06 am

    Hi, i'm currently in the middle of trying out this project. I've written up the codes inside but it keeps checking when i run the file. It doesn't says that user present. My phone is located right beside the pi.

    • James Bruce
      August 15, 2015 at 7:00 am

      Couple of thoughts:

      1. Check the hardware address is correct and following the same format. Make sure there are no spaces in there accidentally.
      2. What kind of Bluetooth adaptor is it, and is your phone compatible with BLE? If it's an older phone without BLE, I'm not sure it would respond to a BLE device, but I could be wrong.

    • James Bruce
      August 18, 2015 at 10:57 am

      Hi Arifah - actually, I think this is because your phone isn't open on the Bluetooth settings page. It needs to be open on that settings to be in discoverable mode, otherwise it wont broadcast its address. LAter the program can scan for a specific address, but for to work it must be discoverable.

      • Anonymous
        August 18, 2015 at 11:02 am

        Hi thank you very much now the bluetooth problem is solved ????.