Hacking Halloween: Using Arduino and Twilio To Build An Interactive Haunted House

October 24, 2013
Written by

hackingHalloween

Talk about this post on twitter: #hauntedHack

When I was a young trick-or-treater I never missed the house on the hill that gave full-size candy bars; that was the Halloween destination on our street. But these days setting up the ideal trick-or-treating destination requires thinking outside the Snickers bar. I want kids to remember our house. I want parents to tell other parents about it. But more importantly I want a “surprise factor” when people discover our house. So this year I amped up the “trick” and put together an interactive haunted house using Twilio, Arduino and some cheap electronic components.

Haunted Hack: Pumpkins That Change Color When You Text Them

My initial goal was simple. When people text a color to my app I wanted the pumpkins in our lawn to change colors.

Here’s a video of the final product.


 

First my wife texts “red” to the Twilio number, which turns the pumpkins red. Then she texts the word “chaos”, which unleashes a world of terror. Can’t wait to see how the trick-or-treaters react when their parents are texting chaos as they walk up! Let’s walk through how I built these interactive pumpkins using Arduino and Twilio.

Here’s what you’ll need to make this happen:

Extras:

  • Fog Machine
  • Speakers
  • Bats
  • Other spooky business

This is my exact circuit with one change. Instead of a 9V battery I used a 12V AC to DC converter. A 9V battery WILL work it just won’t be as bright.

This circuit is based off of this make guide tutorial and is relatively simple. The only trick here is that we are using MOSFETs (a type of transistor) in order to amplify the voltage going to the LEDs. Because the LEDs require more than the 5V the arduino puts out, we have to use MOSFETs to amplify the power. The way it works is the Arduino sends a digital signal (PWM) to the MOSFET through the (G) gate pin. The signal switches the transistor passing the higher current at 12 V, gathered through the (S) source, out through the (D) drain to the LED strip. This is a smart way of amplifying a small PWM signal to a device that requires a higher source of power.


Safety Warning!!

Remember whenever working with power to be extremely careful. Always build circuits with the power unplugged. The last thing we want is for you to fry your Arduino or yourself, leave the shocking to Dr. Frankenstein.
Once you’ve got the circuit looking like this, we should be ready to go on to Step 2.

The Arduino Software

Now let’s get the Arduino piece working. Before we look at the code let’s make sure you are all setup.

First you need to:

Now that you’re all set to go, let’s set up a sketch to make the Arduino talk to Pusher and trigger some fun LED colors.

Once you have the Arduino app (IDE) open, create a new file and paste the following code into it.

#include 
#include 

// Constants representing Pins on the Arduino
#define RED    6 
#define GREEN  9
#define BLUE   5

int led = 13;
PusherClient client;
long k;

void setup() {
  pinMode(RED, OUTPUT);
  pinMode(BLUE, OUTPUT);
  pinMode(GREEN, OUTPUT);

  // We'll default to orange pumpkins.
  analogWrite(RED, 255);
  analogWrite(GREEN, 102);
  analogWrite(BLUE, 0;

  // paste next block of code here.
}

//paste loop function here

Let’s walkthrough this sketch together. First we are including the two libraries we are going to need for this project; the Ethernet and Pusher libraries. Then all we are doing is setting up our three PWM pins to prepare them to manipulate our three LED strip leads. In this case we are using pins 5, 6 and 9. Pin 5 controls the RED signal, 6 is GREEN and 9 is BLUE.

Now that we have prepped the PINS to do their jobs, we can create complex colors by sending RGB values through each pin. Notice in the setup() function that we are writing different values to each pin. Pin 5 (RED) is sending 255, pin 6 (GREEN) is sending 102, and pin 9 (BLUE) is sending 0. This of course matches the RGB values for Orange.

Next we need to connect to our Pusher channel via the ethernet connection and setup up our handlers for the different events will trigger the pumpkins to change colors.

Paste this next snippet within the setup() function where I’ve indicated in the code.

 // paste next block of code here.

if(client.connect("your-pusher-key")) {
    client.subscribe("trick_channel");
    client.bind("orange", orange);
    client.bind("blue", blue);
    client.bind("red", red);
    client.bind("purple", purple);
    client.bind("green", green);
    client.bind("chaos", chaos);
  }
  else {
    while(1) {}
  }

//paste loop function here

Once our Pusher client has connected to the internet, it authorizes with our app key and subscribes to the channel that we will eventually be sending our events through. Then our client listens for certain event names, in this case colors, and binds those events to event handlers.

Sweet, we’re almost there. Now all we have to do is write the loop and the callback functions that will change the color. Here is the next piece of code.

//paste loop function here
void loop() {
  if (client.connected()) {
    digitalWrite(led,HIGH);
    client.monitor();
  }
  else {
    Serial.println("Client error connecting.");
  }
}

// Callbacks for the pusher events. Change the color.
void orange(String data) {
  analogWrite(RED, 255);
  analogWrite(GREEN, 102);
  analogWrite(BLUE, 0);
}

void blue(String data) {
  analogWrite(RED, 30);
  analogWrite(GREEN, 144);
  analogWrite(BLUE, 255);
}

void red(String data) {
  analogWrite(RED, 255);
  analogWrite(GREEN, 0);
  analogWrite(BLUE, 0);
}

void green(String data) {
  analogWrite(RED, 124);
  analogWrite(GREEN, 252);
  analogWrite(BLUE, 0);
}

void purple(String data) {
  analogWrite(RED, 160);
  analogWrite(GREEN, 32);
  analogWrite(BLUE, 240);
}

// unleash chaos below!
void chaos(String data) {
    // Lets do something crazy here
}

This last piece is straightforward. Inside the loop we tell the Pusher client to constantly monitor the event channel.

Then we create the callback functions for the Pusher event listeners which change the color of the LED strip lights by pulsing new values through the RGB leads. This could be simplified by writing a helper function that takes an RGB array as an argument and loops through the pins. Since we only have a few colors this is fine for now.

Finally we can upload our sketch to the Arduino. You can find the full sketch here for reference.

Next we are going to write a simple Sinatra app and connect all the pieces to create some jacked-up Jack O Lanterns!

Step 3: The Sinatra App

The server piece of this haunted hack is a very basic Sinatra app that we will host on heroku. The first thing to do is set up basic configuration with two new files in your project directory; the Gemfile and the Procfile:

~//Gemfile
source 'https://rubygems.org'
gem 'sinatra'
gem 'pusher'
gem 'pusher-client'
gem 'twilio-ruby'

~//Procfile
web: bundle exec ruby haunted-hack.rb -p $PORT

We’re just going to start with the whole Ruby file since it’s pretty simple. Now you can go ahead and create haunted-hack.rb and add the following code:

require 'sinatra'
require 'twilio-ruby'
require 'pusher'

before do
  # Setup Pusher
  Pusher.app_id = ENV['PUSHER_APP_ID']
  Pusher.key = ENV['PUSHER_KEY']
  Pusher.secret = ENV['PUSHER_SECRET']
end

# The single endpoint that our Twilio number points to.
get '/trick/?' do
  output = "Our ghoulish ghosts have heard your wish. Happy Halloween!"
  # Try to trigger a pusher event based on the Body of the incoming SMS or submitted form
  begin
    Pusher['trick_channel'].trigger('starting:', {:message => 'starting up trick'})
  rescue Pusher::Error => e
    output = "Failed: #{e.message}"
  end
  # Switch colors
  begin
    command = params['Body'].downcase
    puts Pusher['trick_channel'].trigger(command, {:message => command})
  rescue
    command = "no message"
  end

    response = Twilio::TwiML::Response.new do |r|
      r.Message output
    end
    response.text
end

get '/' do
  erb :index, :locals => {:msg => "Haunted Hack"}
end

get '/chaos/' do
  erb :chaos
end

Let’s walk through this file. At the top we are setting up our Pusher configuration variables and including necessary gems. We will set up the environment variables later when we push to Heroku.

Next we set up our /trick/ route, which receives incoming SMS messages and triggers a Pusher event that the Arduino is already listening for. Once the event has been fired, we send a text back to the user using the Twiml.Message verb.

Lastly we throw up our root route which renders a simple index.erb file. Here is the index file.

<h1><%= msg %></h1>
<hr/>
<h1>760-303-4118</h1>
<h2>Text: 'green', 'blue', or any color to change the lights.</h2>
<h2>Text: 'chaos' to unleash chaos.</h2>
<script type="text/javascript" >
  var channel, pusher;
  pusher = new Pusher('46c5ba280c64d8511011');
  channel = pusher.subscribe('trick_channel');
  channel.bind('chaos', function(data) {
    return document.location = '/chaos/';
  });