Have you ever wanted to arrive home to a personal welcome? With a Raspberry Pi and a few simple components, you can! In this simple project we'll use a reed switch to trigger a theme tune when a door is opened. We shall be using a Raspberry Pi as the controller here, though you could use almost any other microcontroller for this project using the same circuit. Here's a demo.

You Will Need

You will likely already own all of the parts you need to make this except the reed switch, which is around $2--3, or you can get a packet of 5 for just over $8 here.

  • A Raspberry Pi (any model will work for this).
  • 1 x 220 Ohm resistor.
  • 1 x 1K Ohm resistor.
  • 3 x 10K Ohm resistor.
  • 1 x Magnetic reed switch.
  • 1 x LED.
  • 2 x Push-button switch.
  • Breadboard.
  • Hook-up cables.
  • Computer speaker or similar.

We'll use the Raspberry Pi to play a song when the room is entered, and design a circuit with buttons on our breadboard to activate it on a delay, and stop the program.

This project, while being made mostly for fun, covers the basics for many applications in DIY home automation and also DIY home security

Getting Started

Lets begin by making our circuit. Make sure your Pi is unpowered, and set up your circuit like this:

Fritzing Annotated HQ

The LED is connected to pin 7 on our pi. The two push button switches are attached to pins 11 and 13, and the reed switch connects to pin 15. Our power goes to pin 1 (3v3) and pin 6 (Gnd).

pin diagram

Be sure to check everything is in exactly the right place.

While you are testing this project it may help to keep your reed switch in front of you so you can easily toggle it on or off. In this instance the reed switch was already installed above the door. Once your project is up and running you can either temporarily attach the switch to your door using tape, or if you are feeling more confident you can attach it more permanently for use in future projects!

reed switch installed

Connect the 3.5mm jack output of you Pi to your speaker system. Once everything is put together it should look something like this:

whole setup correct

Note that the breadboard used here has it's power rails the other way round to the Fritzing diagram above.

Now power up your Pi, and access it using SSH so we can access the terminal. If you are not sure how to do this, this guide can help you. If you are using your Raspberry Pi with a monitor, mouse and keyboard, skip this step and open the terminal.

Before getting started, it is worth checking whether you are up to date. Type

        sudo apt-get update
    

into the terminal.

Now we can move on to getting our Pi talking to our circuit.

Testing Our Setup

To begin, lets check our circuit using a simple program. If you are confident you have wired everything up right so far you can skip this step, though I would recommend it as it can save headaches later on.

If you've never programmed in Python before and are feeling a little daunted, there are a host of great websites that can help you get started.

In the terminal, create a new script:

        nano test.py
    

Once open, add this code to the file, and press Ctrl-C to quit, following the save dialogue:

        #This code was written for an article on www.makeuseof.com by Ian Buckley.
import RPi.GPIO as GPIO
import time
GPIO.setwarnings(False)
GPIO.setmode(GPIO.BOARD)
GPIO.setup(7,GPIO.OUT)
GPIO.setup(11,GPIO.IN)
GPIO.setup(13,GPIO.IN)
GPIO.setup(15,GPIO.IN)

while True:
        GPIO.output(7,GPIO.HIGH)
        if (GPIO.input(11)==1):
                print("Button on GPIO 11")
                time.sleep(1)

        if (GPIO.input(13)==1):
                print("Button on GPIO 13")
                time.sleep(1)

        if (GPIO.input(15)==1):
                print("Button on GPIO 15")
                time.sleep(1)

GPIO.cleanup()

This code reads the value of the buttons and prints to the screen when they change. The two push buttons have pull down resistors, so they report HIGH when pressed. The reed magnet switch reports HIGH whenever its accompanying magnet is close.

switches

Run the program:

        python test.py
    

You should see the LED light up, and a report to the screen when you press your two buttons and pull the magnet away from your reed switch. If you aren't getting feedback when you press buttons, check your circuitry again and make sure everything is connected as it should be. When you are finished testing, press CTRL-C to stop the program.

test

Now we can put together a simple program to set, trigger and reset our door sensor. We will go over the code in parts and briefly explain what each part does, though if you want to see the full code scroll down to see it presented in full.

We need to start by importing some modules:

        import Rpi.GPIO as GPIO
import pygame.mixer
import time

We will be using the Pygame module to play our music. It comes as standard with Raspbian Jessie, and is a great library for everything you need for making Python games and many other amazing projects.

We are going to use a variable called active to decide whether our system is active or not. Let define a couple of functions which will do this for us:

        def activeSetup():
        global active
        active=0
        print("Currently Not Active")

def activeState():
        global active
        if active==1:
                active=0
                GPIO.output(7,GPIO.LOW)
                print("Currently Not Active")

        elif active==0:

                print ("Activating in 10 seconds")
                for x in range(0,10):
                        GPIO.output(7,GPIO.HIGH)
                        time.sleep(0.5)

                        GPIO.output(7,GPIO.LOW)
                        time.sleep(0.5)

                active=1
                GPIO.output(7,GPIO.HIGH)
                print("Currently Active")

        else: return

The first function here creates a variable named active, and sets it to 0. Giving the active state a numeric value means that if you plan to later scale up your program to have different active states you can number them accordingly. While it might not be the best Python programming in the world, it will more than suffice for this project.

The second function when called checks if the system is active (or active==1). If it is, it sets the system to not active (active==0), turns the LED off, and prints to the console. If it isn't, it gives you a 10 second countdown to leave the room in which the LED flashes, before remaining on to show that the system is active.

Now we can define a function which will watch our reed magnet switch:

        def watchDoor():
        global playing
        playing = False
        while True:

                if active==1 and GPIO.input(15)==1 and playing == False:
                        playing=True
                        pygame.mixer.music.play()
                if GPIO.input(13)==1:
                        print("Stop button pressed: Exiting")
                        pygame.mixer.music.stop()
                        break
                if GPIO.input(11)==1:
                        activeState()
                        time.sleep(0.5)

We create another variable here called playing -- this is there simply to stop the program trying to start playing repeatedly when the switch is triggered.

Inside the while loop, the first if statement starts the music (which we don't have any of yet, but not to worry, it's coming). It only lets the music start if the system is active, the reed switch is open, and it isn't already playing.

The second if statement is for our exit button. If this button is pressed the music stops and the program exits.

The third if statement is for toggling whether the system is active or not. The time.sleep function here is to prevent multiple button reads when it is pressed.

Now it is time to set up out Pi's pins.

        GPIO.setmode(GPIO.BOARD)
GPIO.setup(7, GPIO.OUT,initial=GPIO.LOW)
GPIO.setup(11,GPIO.IN)
GPIO.setup(13,GPIO.IN)
GPIO.setup(15,GPIO.IN)

If you've done any experimenting with the Pi before this should be familiar to you. The initial=GPIO.LOW argument in pin 7's setup sets it to low as soon as it is initialised.

Now we can call our function that will set the system to not be active when the program starts.

        activeSetup()

Music Maestro!

At this point, we should start thinking about the music to play. You can choose any music file you wish, but we shall choose something available to everyone for now. If you watch YouTube you are probably already familiar with Kevin MacLeod's music. Lets download a fantastic tune by him called "One-eyed Maestro". This, along with much of the music on his site, is licensed under Creative Commons, and there are many good reasons to use content with these licences for your projects.

wget

Back in our code, we need to start the Pygame mixer and load our tune.

        pygame.mixer.init(44100,-16,2,1024)
pygame.mixer.music.set_volume(1.0)
name = "One-eyed Maestro.mp3"
pygame.mixer.music.load(name)
print("Loaded track - "+ str(name))

The first line of this block initiates the Pygame mixer. The last argument in the brackets is the buffer which controls the latency in which the sound is played. If you experience choppy playback later when your music plays, try increasing this number to 4096. The settings as they are work with no issue on a Pi 3.

If you downloaded your music file into a different directory to your door.py program, you will need to provide the full path inside the brackets when you define the name variable.

Now all that is left to do is set up a loop which waits for us to either set the program active, or exit it.

        while True:
        if(GPIO.input(13)==1):
                print("Stop button pressed: Exiting")
                pygame.mixer.music.stop()

                break
        if(GPIO.input(11)==1):
                activeState()

                time.sleep(0.5)
        if(active==1):
                watchDoor()
                break

GPIO.cleanup()

This while loop waits for an input from either button, and quits or changes the state to active accordingly. If the state of active becomes 1, then the watchDoor function we defined earlier gets called and the next time the door opens our tune will play. We also call GPIO.cleanup() to reset our pins on exit, which is generally a good practise for all programming on the Raspberry Pi.

That's everything we need to do to get this project up and running, here is the code in full:

        import RPi.GPIO as GPIO
import pygame.mixer
import time

def activeSetup():
        global active
        active=0
        print("Currently Not Active")

def activeState():
        global active
        if active==1:
                active=0
                GPIO.output(7,GPIO.LOW)
                print("Currently Not Active")

        elif active==0:

                print ("Activating in 10 seconds")
                for x in range(0,10):
                        GPIO.output(7,GPIO.HIGH)
                        time.sleep(0.5)

                        GPIO.output(7,GPIO.LOW)
                        time.sleep(0.5)

                active=1
                GPIO.output(7,GPIO.HIGH)
                print("Currently Active")

        else: return

def watchDoor():
        global playing
        playing = False
        while True:

                if active==1 and GPIO.input(15)==1 and playing == False:
                        playing=True
                        pygame.mixer.music.play()
                if GPIO.input(13)==1:
                        print("Stop button pressed: Exiting")
                        pygame.mixer.music.stop()
                        break
                if GPIO.input(11)==1:
                        activeState()
                        time.sleep(0.5)

GPIO.setmode(GPIO.BOARD)
GPIO.setup(7, GPIO.OUT,initial=GPIO.LOW)
GPIO.setup(11,GPIO.IN)
GPIO.setup(13,GPIO.IN)
GPIO.setup(15,GPIO.IN)


activeSetup()

pygame.mixer.init(44100,-16,2,1024)
pygame.mixer.music.set_volume(1.0)
name = "One-eyed Maestro.mp3"
pygame.mixer.music.load(name)
print("Loaded track - "+ str(name))

while True:
        if(GPIO.input(13)==1):
                print("Stop button pressed: Exiting")
                pygame.mixer.music.stop()

                break
        if(GPIO.input(11)==1):
                activeState()

                time.sleep(0.5)
        if(active==1):
                watchDoor()
                break

GPIO.cleanup()

If you scrolled down here to grab the complete code straight away, bear in mind you will still need to download the music onto your Pi for it to work!

Now you should have a functioning welcome home theme tune! Attach your reed switch to your door, and try it out. Embarrassing dancing is optional but recommended.

This project covered the basics for many forms of home monitoring, security and automation, and hopefully was fun too!

Now that you have come this far, why stop there? You could add more tracks and have the program choose one at random from a list. You could add a relay and have other objects be triggered on entry. If you have a home music system, why not have a theme song for every room?

relay lights

Will you be designing your own personal welcome home message? Have you been inventive with reed switches in your home in other ways? If so, leave a comment about what you are planning or have already done in the comments section below!