Raspberry Pi Doorbell (Python)


To start I will explain the problem we have at home with our doorbell.  We live in a 3 storey townhouse (bedrooms on the top floor, living area on the middle floor, sound proofed recording studio/office on the ground).  If we shut the doors to the living area on the 1st floor we can’t hear the door if it’s being knocked or a ground-only located doorbell.  If I am in the studio/office and shut the door I also can’t hear it.  If we open the door and are on the top floor we also can’t hear it.

We tried a cheap wireless doorbell solution (Byron SX20) – this kind of worked for about a year – but it started not even ringing at all.  I changed the wireless channel and it worked for a week then stopped working.  This repeated for a couple of months – I even bought a new receiver – but it still didn’t work.  I switched to a wired battery powered doorbell and also ran another cable upstairs to the 1st floor though this 2nd ringer never worked well and was not loud enough to hear it on the top floor.  There was also no chance of hearing it while in the studio with the door shut and music playing.

I hate wireless anything (Wifi) as it never works 100% of the time.  When we moved into the house I put in CAT5E all over the house and wanted to use this to solve my doorbell issue.

Raspberry Pi

Along came the Raspberry Pi and I noticed that it had a GPIO (General Purpose Input Output) interface.  Ok I have to admit – I didn’t really know what that was until I read up on the Raspberry Pi and reports were saying it was designed for the novice to connect to and programme.  I’m not really a novice (can program in PHP, VBscript/VBA) I thought, how hard can it be?

I’ve played with Linux for the last 12 years or so – so armed with that knowledge I joined the queue for my Raspberry Pi.

After the 6 weeks wait it arrived and after a few months (waiting for a spare moment) I set about solving my doorbell issue.

EEEEK!  I thought it would be simple – just Google

Raspberry PI doorbell

and do what it says – I hit a brick wall – there are a few sites I found where people had done it but there was no code – no instructions.  I joined a couple of forums and asked people how to do it – They just said “keep reading the forums”.

Anyway – I finally worked it out through butchering other project’s code that I found on the web.

Here I want to share that info so that you, the reader can do it too.

Here’s an overview of how it’s connected

Raspberry Pi Hardware

To start with you need some extra bits of hardware:

Breadboard – this is a piece of plastic with holes in it where you can connect wires together to form circuits – the rows are connected, so where you want to connect wires together, you just plug them into the same row.

you can get them from http://www.fastestpc.co.uk/product.php?p=158057511  for £3.69

Jump Wire kit – You also need some wires.  These kits come with various lengths of wire – you can of course cut them down if you want (though I didn’t bother).



10k Pull Up Resistors – I got these from Ebay – but Maplin or RS Components do them.


Adafruit Pi Cobbler Breakout Kit for Raspberry Pi – I got this from Ebay too


Note: You don’t actually need this – you could just connect to the breadboard directly from the GPIO Pins – but you will need cables with the small sleeves on them.


(Source: http://www.raspberrypi.org/archives/tag/gpio)

This Youtube clip does touch on this a little

Soldering the Adafruit Cobbler Kit does require a small ended Solerding Iron – I bought a new one to do the job on Ebay for only £7.95 as my old iron had a chisel end and would never have done the job.

Follow the instructions on how to do it at http://learn.adafruit.com/adafruit-pi-cobbler-kit/solder-it


Building the Breadboard to connect to the Raspberry Pi

I’ve never done any electronics before but I do have a multi-meter and know roughly how to use it.

Click for larger version


This breadboard came from Maplin and has the handy screw top connectors in Black, Yellow, Blue, Green and Red.  Of course you can use any of them – I chose the Green and Red to connect to the actual doorbell using the bell wire that I was using for my rubbish wired battery doorbell.

Now expert electronics people may laugh at my wiring – but it literally takes 10 minutes to connect together.

This connects to a bog standard doorbell

Adafruit Pi Cobbler Starter Kit

I’ll start with the Ribbon cable connected Adafruit connector.

(Source: http://learn.adafruit.com/adafruit-pi-cobbler-kit/solder-it)

Here you can see The GND pin along the bottom row

(Source: http://learn.adafruit.com/adafruit-pi-cobbler-kit/solder-it)


The 3.3v power is on the other side of the connecter (far right) – is hidden in the top of the 3 pictures by the black connector wall.

Once this has been soldered together with the supplied pins as per http://learn.adafruit.com/adafruit-pi-cobbler-kit/solder-it which explains the process very simply, you pop that onto the breadboard.  Remember that the rows of the breadboard are connected except where there is a channel between them – so in my image above the pins actually sit in columns V1 C and H and there is a channelled groove between F and G.  If you were to put the board in A and F then it wouldn’t work as the 2 rows of pins would connect.  Also you need some space to connect wires to it.

You connect the board as described above.  It’s not important where you connect it as long as the points that you place the pins are in the correct rows corresponding to GND, 3.3v and the GPIO Pin you choose (I chose GPIO 23).

You can just connect the earth to one of the connectors of the door bell button and solder a resistor to the other side of the bell button pusher cable and the other end of it connected to 3.3v as well as GPIO23 – theoretically that should work but don’t hold me to it.

This is a simplified version of the one described at http://learn.adafruit.com/playing-sounds-and-using-buttons-with-raspberry-pi/bread-board-setup-for-input-buttons

As I only needed 1 button and didn’t bother with the momentary push-button switches (though I did buy these to test it).


So that’s the Breadboard setup and connected to the Raspberry Pi. Now the tricky bit.

Raspberry Pi PYTHON GPIO

I’ve never used Python – and to be honest I don’t really have a big desire to learn it.  I’m not sure what I’d use that skills for, in any other project – but a lot of programming is cut and pasted from the web these days.  So I followed the instructions at http://learn.adafruit.com/playing-sounds-and-using-buttons-with-raspberry-pi/overview and it all seemed to work.  I could play an MP3 file if I pressed the button,  BUT it was terrible – it would behave as if I pressed it 100 times.

I also had terrible trouble with it even accepting the button and just played the MP3 without pressing the button.  In fact it even played the MP3 as soon as I ran the script, without the ribbon cable connected between the breadboard and Raspberry Pi.

The code listed below just did not work as it is

#This does not work

#!/usr/bin/env python

from time import sleep
import os
import RPi.GPIO as GPIO

GPIO.setup(23, GPIO.IN)
GPIO.setup(24, GPIO.IN)
GPIO.setup(25, GPIO.IN)

while True:
        if ( GPIO.input(23) == False ):
                os.system('mpg321 binary-language-moisture-evaporators.mp3 &')
        if ( GPIO.input(24) == False ):
                os.system('mpg321 power-converters.mp3 &')
        if ( GPIO.input(25)== False ):
                os.system('mpg321 vader.mp3 &')

The problem seems to be called debouncing.  This is where you press the button and 
the voltage changes gradually.  The above code uses a While Loop and detects for the 
input to change state to False.  I put a multi-meter on the switching and while not
 switched the multi-meter showed .001, press the button and it goes from .001 to .010 (from memory)
 and to .000 while it is pressed. So it’s not a straight on off action as the code suggests.
It turned out I needed some extra modifications to the code:
# This code works
#!/usr/bin/env python

from time import sleep
import os
import RPi.GPIO as GPIO

GPIO.setup(23, GPIO.IN, pull_up_down=GPIO.PUD_UP)
test = 0

while True:
        inputchk = GPIO.input(23)
        if  inputchk == 0:
         test = 1   
         os.system("python /home/pi/doorbell/audio.py")
        test = 0


So the pull_up_down=GPIO.PUD_UP section of line 7 was crucial.  To stop the multiple button issue I call another script I called audio.py (both scripts stored in /home/pi/doorbell folder).

To run it you use

sudo python doorbell.py
at the command prompt.
The contents of audio.py contains the playing of the mp3 through the program mpg321 (I used the Imperial tune from Star Wars), 
an output to the screen “button pressed” as well as a snippet from Pushover.net which sends a message to our mobile phones….
found at https://pushover.net/faq#technical-python
The contents of audio.py
# coding=utf-8
import os, sys
import time
import httplib, urllib
conn = httplib.HTTPSConnection("api.pushover.net:443")
conn.request("POST", "/1/messages.json",
     "token": "APP_TOKEN",
     "user": "USER_KEY",
    "message": "There is someone at the front door",
  }), { "Content-type": "application/x-www-form-urlencoded" })
os.system('mpg321 imperial.mp3 &')
print("Button Pressed")
So that’s it – the 2 Python files I use to send me a Pushover Notification on mine 
and the wife’s mobile phone


Running as a Service

I explored how to run the script 24/7 and as a service or at boot (in case the wife turns it off when I’m not at home) – I had issues with it running the MP3 correctly (it played the MP3 twice over the top of itself) and wasn’t ideal.

In the end I found the best way is to use “screen” to run the script

sudo apt-get install screen

Then run screen – which creates another session – run the script and hit Ctrl – A and d to exit the session – to go back to the session type:

session -r

This way you can log out of the SSH session and the doorbell.py script continues to run.

This doesn’t run automatically though – so if anyone has another solution – I’d like to hear it.

The Raspberry Pi is also plugged into an old powered speaker I had lying around

Sure we have to leave it plugged in to hear the Star Wars Imperial track when someone presses the button – The wife really loves it BTW (hahaha NOT!), and our 3.5 year old daughter keeps turning the volume up really loud when the wife is not looking.  So it’s not very green with the Raspberry PI and speaker are both plugged in 24/7.

Raspberry Pi problems

The pull_up_pull_down issue (or lack of using it caused me lots of problems) it was very hard to find good documentation on the GPIO command set.  Of course I am diving in at the deep end of programming Python – I didn’t want to go through learning the whole thing just to do this.

Make sure you don’t connect the push button up to your battery powered door bell – thinking you can just chain it all together.  The batteries give off a voltage and it will damage your RPi.

The thing works perfectly in that it plays the MP3 and send you the message to your phone.  But if the doorbell is pressed again before the MP3 has finished then instead of them queuing up the 2 play at the same time.  A little annoying, as well as you receive 2 messages.

In fact while testing – I managed to use up all of my 7500 monthly allocations from Pushover.net – so best not to implement the Pushover API function until you are certain it works.

The only other thing – it does seem to randomly do it all itself.  So maybe twice a day we get the “doorbell” ringing (MP3 plays and a message sent to our phones) only to find nobody there.  I expect it’s due to dampness in the air causing the small gap between the contacts in the push button to connect the circuit and so triggers the MP3 and message – but I don’t really know – the button is shielded from rain and the elements.

I’ll be happy to help anyone who is trying this – in the end it’s just 2 python files – and an easy electronics build.

Raspberry Pi Doorbell Specs

Specs of the Pi:

Python 2.7.3rc2 (default, May  6 2012, 20:02:25)

[GCC 4.6.3] on linux2

Linux raspberrypi 3.2.27+ #250 PREEMPT Thu Oct 18 19:03:02 BST 2012 armv6l GNU/Linux

Model B with 512MB RAM

Post a Comment

Your email is never shared. Required fields are marked *