Motion-Detecting, Blood Squirting Halloween Skull

Sign in to queue


Create a scary surprise for your Halloween trick-or-treaters! With some off-the-shelf components and a bit of code, you can have some fun with your visitors...

Difficulty: Intermediate
Time Required: 1-3 hours
Cost: $100-$200
Software: Visual C# Express, Phidgets SDK
Hardware: AirLink101 AIC -250W wireless IP camera, Phidgets 0/0/4 Interface Kit, Westinghouse 3-Outlet Heavy Duty Remote, Beckett M60AUL Small Fountain Pump, rubber tubing, plastic skull, solder and soldering iron, external speakers
Download: Download

I wanted to build a small device that would terrify small children as they approached my door for Halloween. I suppose this makes me a bad person, but it's still a lot of fun.

The concept here is pretty simple. We will be using motion detection from a web cam or network-enabled/IP camera to trigger a small fountain pump fitted into a bucket of water to spray anyone that approaches your front door. And, to make it a bit more creepy, we will fit the spray mechanism into a plastic skull.

WARNING: The pump being used will be connected to an A/C wall socket. While the pump is certainly designed to be used with water, please be aware of the fact that you will have water and electricity in close proximity to each other.

What You Will Need

  • A web or network-enabled camera.  I am using the AirLink101 AIC-250W wireless IP camera.
  • A Phidget Interface Kit 0/0/4 – a USB-controlled board with 4 relays.
  • A remote-controlled A/C power outlet. I chose the Westinghouse 3-Outlet Heavy Duty Remote, Item #T28074, normally used for Christmas lights.

  • A fountain water pump. The one I used in this article is the Beckett M60AUL Small Fountain Pump. Almost any fountain pump will work, however be aware of how far the water will need to be pumped and choose a pump to meet your needs.

  • Rubber tubing of the appropriate size to fit the pump, preferably black if you can find it.

  • A Plastic Skull.

  • Red food coloring.
  • A soldering iron, solder and some spare wire.
  • A set of external speakers with an audio extension cable.
  • Optional: A strobe light.
  • Microsoft Visual C# 2005 Express Edition.

The Hardware

Let's start by setting up the hardware. We will be using the remote controlled A/C outlet to toggle power to the pump at will. The remote control for the unit I purchased has a separate on and off switch, so we will wire one relay from the Phidget board to the on switch, and one relay to the off switch.

Open the remote control unit. Inside, you should see something similar to the image below:

Flip the unit over to access the side with the button contacts. My unit had two metal spring-type contacts taped to the board. Once removed, I was able to access the contacts directly. You should see contact pads similar to the following:

The pads each contain a common ground contact and an active contact. When the two are bridged, which happens when the button is pressed, the circuit closes and the remote sends the appropriate signal to the receiving unit. We will replicate the button action by tying a relay to each pad so that when the relay closes at our command, the circuit will close, sending the signal to the outlet unit.

Cut 4 equal lengths of wire and strip a bit of insulation off of each end. Carefully solder one end of each wire to each contact pad on the remote control as shown:


Additionally, use some electrical tape or rubber bands to affix the battery in place on the remote, if required.

Next, put the opposite end of each wire into the appropriate screw terminal on the Phidget relay board. You will notice on the Phidget board that there are 3 terminals per relay, labeled NO, XC, and NC, where “X” is a number from 0 to 3. These stand for “Normally Open”, “Relay X Common”, and “Normally Closed”. Since we want each circuit to be normally open, we will put one wire of each button to the NO terminal, and one to the XC terminal of each relay. For the on button, insert one wire into the NO terminal of relay 0, and one wire into the 0C screw terminal. Do the same with the wires from the off button, but wire them into relay 1. You should wind up with something looking like the picture below:


With this in place, we now have a computer-controlled remote control for the outlet. When the fountain pump (or anything else) is plugged into the outlet, it will toggle on and off as we open and close each relay.

Next, we will modify our plastic skull. If you have access to a real skull, feel free to use that instead. I decided to puncture a small hole in the bottom and drill a hole in the nose of the skull. I then fed the tubing through the nose hole and out of the bottom of the skull. You may also wish to run the tubing out of the eyes by either splitting the tubing near the eyes, or using two separate pumps plugged into the remote outlet.

Cut holes in the appropriate areas and push the rubber tubing through, leaving just a tiny bit hanging out of the exit hole.

Leave a generous amount of tubing coming out of the bottom of the skull. You will cut this later to the desired length once the prop is setup outside. When the gadget is later setup outside, you will fill a bucket with warm (or COLD!) water and add some food coloring, and the fountain pump. The pump I used submerges entirely in water, but yours may use an intake tube instead. Then, plug the pump into the remote controlled outlet, and plug the outlet into a standard A/C wall socket.

When the on signal is sent to the remote controlled outlet, the pump will turn on, and water will squirt from the rubber hose inside the skull!

Our skull is set to spray water out of its nose. Let's set all of this aside for now and move onto the software side of things.

The Camera

For motion detection, I chose to use the AIC-250W wireless IP camera. This allows me to freely mount the camera wherever I wish and not worry about cords. Of course, it will require that you have a wireless access point somewhere nearby to connect the camera and the laptop together. You also could use an ad-hoc network with the camera, but I have not tested this. With the software we will be using, you also should be able to use a standard USB web camera. Regardless of the method chosen, please configure the camera appropriately so that the video output can be seen. In the case of the AIC-250W, it is as simple as running the included utility and setting it up to use your wireless network.

The Software

We will need several pieces installed before we can begin coding. First, ensure that you have Microsoft Visual C# 2005 Express Edition installed.

Following Scott Hanselman's lead, I too will be using the excellent motion detection project from Andrew Kirillov.

Download the source code for this project, as we will be modifying what is there to meet our requirements.

You also will need to download and install the latest Phidget's library.

With those pieces installed and ready, we can begin modifying the software motion detection code.

I am not going to give you a tutorial of Andrew's source code as that is done at the original site linked above. I suggest reading through that article and exploring the source code a bit to learn what's going on behind the scenes. The code is somewhat complex in areas, however the project itself, along with the original article, are a fantastic learning experience.

Open the motion_src.sln file in Visual C# 2005 Express. When the solution is opened, the IDE will prompt you to upgrade the solution to the latest version. Accept the defaults and make your way through the wizard. When complete, you should see your solution with three projects loaded into the IDE.

The first thing we will add to the application is a handler to actually deal with firing the pump when the motion detection alarm is fired, which means we will need to communicate with the PhidgetInterfaceKit. Ensure the Phidget library listed above is installed. Then, right-click on the References folder in the motion project and select Add Reference… . Scroll down and select Phidget21.NET with runtime version 2.0.50727.

The pump is controlled in a separate thread, so we need to add the System.Threading library to our code along with the Phidget library. Finally, to play a loud sound through some external speakers, we need to use the System.Media library. All of this can be done by adding the following using statements to the top of our MainForm.cs code:

using System.Threading;
using Phidgets;
using Phidgets.Events;
using System.Media;

When motion is detected, we want to call a method that will turn the pump on for a bit and then turn it back off. After the pump has been activated, we also want it to wait for the user to click a button or press a button on the keyboard to setup the “trap” again. Otherwise, we run the potential of having the pump fire over and over again while handing out candy or before the “trick-or-treater” leaves. Alternatively, we can have the trap turn off for a specified period of time and then re-enable itself. We will discuss both methods.

First, add a bool variable named pumpOn to the MainForm class. This will maintain whether we are inside of our event handler, firing the pump.

private bool pumpOn = false; 

Next, we need to create an instance of the InterfaceKit object to communicate with the Phidget board. Under the statement added above, add the following:

private InterfaceKit ifKit = new InterfaceKit(); 

Now that we have created an instance of the InterfaceKit object, we need to open communication with the device. In the MainForm constructor, after the call to InitializeComponent, add the following line:

// open the Phidget device;

Next, look for a method named camera_Alarm in MainForm.cs. This is the event that is fired when motion is detected on the camera. Modify the camera_Alarm method to look like the following:


private void camera_Alarm( object sender, System.EventArgs e )
    // save movie for 5 seconds after motion stops   
    intervalsToSave = (int) ( 5 * ( 1000 / timer.Interval ) );

        Thread thread = new Thread(new ThreadStart(ActivatePump));

This will, as long as the pump is not activated, spawn a new thread using the ActivatePump method. Add the following ActivatePump method to the MainForm class:

private void ActivatePump()
    pumpOn = true;

    // play the terrifying sound
    SoundPlayer sp = new SoundPlayer("scream.wav"));

    // press on switch, make sure off switch is not pressed
    ifKit.outputs[0] = true;
    ifKit.outputs[1] = false;

    // leave the pump on for 2 seconds

    // press off switch, make sure on switch is not pressed
    ifKit.outputs[0] = false;
    ifKit.outputs[1] = true;

    // hold it for half a second

    // ensure no button is pressed
    ifKit.outputs[0] = false;
    ifKit.outputs[1] = false;

        // kill the current thread

This method will set our pumpOn variable to true and then create a new SoundPlayer object, loading the file scream.wav as an embedded resource. The scream.wav file should be from the same directory as the source code. The sound will then be played asynchronously using the Play method. Note that the scream.wav file located in the project solution is setup to be copied to the output directory on compilation. This can be done by selecting the file in the Solution Explorer and then choosing Copy always in the Copy to Output Directory option of the Properties window.

Next, we set the relays. Relay 0 (which is the On button if you wired as suggested above) is turned on while relay 1 (the Off button) is turned off. This is held for 2 seconds to allow the water to squirt out by putting the thread to sleep. Then, the relays are switched. The Off button is pressed (relay 1) and the On button is opened (relay 0). This is held for half a second, and then both relays are returned to their open positions. When this completes, we terminate our current thread so the process can begin again. Note that we wrap the call to Abort in an exception handler. When a thread is aborted, an exception is generated by the CLR. In this case we don't care about the exception, so it is caught and thrown away.

At this point, you have two ways to handle resetting the software. One option is to add an additional Thread.Sleep call to the method above, wait for several minutes, and reset pumpOn to false:  

ifKit.outputs[1] = false;

// wait two minutes

pumpOn = false;


The other option is to add a button to the MainForm and set the pumpOn member variable to false when clicked. This will allow you to manually reset the effect after the candy has been handed out and the door is closed.

To do this, simply drag a button over to the MainForm, double-click it, and add the following to the generated Click event handler:

private void btnReset_Click(object sender, EventArgs e)
    pumpOn = false;

Running the Application

Press F5 to compile and run the application. When running, click on the File menu and choose the appropriate option to open the camera type you have. For the AIC-250W, we will be using the MJPEG URL option. You can connect to this camera with the following URL:

http://<camera's IP address>/mjpeg.cgi

If everything has gone to plan, you should see the output from the camera show up in the center of the window.

The red lines around objects in the scene denote changes sensed by the software.

Final Tweaks

For my environment, I noticed that the motion detection alarm was a bit too sensitive. If you find the same, there is a simple modification you can make to decrease the sensitivity.

The level at which the alarm is set is determined by a private member variable inside the Camera class. If we expose that variable through a public property, we can then set that property when our application starts. By testing various values of this property, you should find one that is suitable for your area.

Open the Camera.cs file and add the following property to the code:

// AlarmLevel property
public double AlarmLevel
    get { return alarmLevel; }
    set { alarmLevel = value; }

Next, move back to the MainForm.cs file. Look for a method named OpenVideoSource. This method is where the Camera object is created. Right below the call to the Camera object's constructor, add the following line, substituting a value that works for you:

// create camera
Camera camera = new Camera( source, detector );

// ADD: level at which alarm is fired
camera.AlarmLevel = 0.010;

For some additional fun, note that the Motion menu of the application contains an option to record video when motion is detected. With this checked, the application will write an AVI file out to its running directory when the alarm is fired…that is, when the scream is played and the blood is squired on your unsuspecting visitor!

Putting It All Together

The final setup is quite simple.

  1. Fill up a bucket of water and add the red food coloring.
  2. Submerge the pump (or the intake hose) into the water.
  3. Hide the bucket behind a covered stand or inside a box.
  4. Place the skull on top of the stand or box with the tubing running down into the pump's output.
  5. Plug the pump into the remote controlled A/C power outlet.
  6. For some extra fun, plug a strobe light into the remote controlled outlet as well!
  7. Plug that outlet into your outdoor power outlet, or run a cord to an outlet inside your home.
  8. Configure and install the camera in an inconspicuous location near the skull and plug it into an outlet that isn't the remote-controlled outlet. Make sure the camera is mounted sturdily so the camera doesn't move and interfere with the motion detection.
  9. Hide some external PC speakers near the skull and run the audio cable inside your home to your PC or laptop. (Make sure to turn up the volume!)
  10. Back inside, plug the Phidget board (with the remote control connected to it ) into a USB port on your PC.
  11. If you are using a wired camera of some sort, plug that in as well.
  12. Run the application and wait for someone to approach the door!

When the software senses motion on the camera, the sound will play through the speakers and the relays will fire, turning on the outlet, which will fire the water pump. The “blood” will spray out of the skull and terrify the person outside that you've either a) just watched on the output screen, or b) recorded to an AVI file for later embarrassment. When you are ready to engage the gadget again, just click the “Reset” button and wait for the next visitor.


That's all there is to it! With a bit of soldering and some off-the-shelf components, you can create a scary, fun, and wet surprise for your trick-or-treaters!


Though Brian is a recognized .NET expert with over 6 years experience developing .NET solutions, and over 9 years of professional experience architecting and developing solutions using Microsoft technologies and platforms, he has been "coding for fun" for as long as he can remember.  Outside the world of .NET and business applications, Brian enjoys developing both hardware and software projects in the areas of gaming, robotics, and whatever else strikes his fancy for the next ten minutes. He rarely passes up an opportunity to dive into a C/C++ or assembly language project.  You can reach Brian via his blog at


Halloween, events

The Discussion

Add Your 2 Cents