Introduction: Halloween Dropping Spider
My Halloween project consisted of a dropping spider triggered by a PIR motion sensor mounted on a Jackolantern and controlled by an arduino MCU. The motion sensor triggered a dropping spider, lights, sounds, low laying fog and finally a tweet with a picture attached (http://twitter.com/ioalerts).
Step 1: Parts List
These are the parts that I used for this project:
- Arduino Duemilanove
- ioBridge IO-204
- x10 Firecracker CM17A
- x10 Transeiver, Appliance and lamp modules
- VHS tape
- 2 Futaba S3003 servos
- Nylon rope
- Plastic Jackolantern
- Parallax PIR sensor
- 2 red LEDs
- 2 1K resistors
- Checklane Yada Yada Yada Toy recorder
- 1 2N2222 tranisistor
- 1 10k resistor
- Fog Machine
- 125VAC/10A DPDT Plug-In Relay (as a switch combined with x10)
- Styrofoam cooler and dryer hose and Ice to create low laying fog.
- Wireless webcam
- Fake spider
- Lights and accesories
- Incandescent black light, strobe light, black light bulbs.
Step 2: Setup
It's all pretty basic. The arduino controlled the PIR motion sensor, the servos for dropping spider reel, Jackolantern LED lights, toy with scary sound, and the X10 CM17A (you can control as many x10 devices as you want). Then the arduino sent a serial message to the ioBridge serial API telling to GET the URL of my site. Then on my site I had a bash script with a while loop looking for request coming from the ioBridge server, then the script played a sound, grab the picture from a wireless webcam and post it to twitter via twitpic's API using cURL.
Step 3: Arduino Sketch
I used the X10Firecracker and the Servo libraries as well as the PIR sensor example from the arduino playground.
I used the 1K resistors on the led1Pin and led2Pin.
I used the 10K resistor on speakerPin going to 2N2222 transistor base, ground to the emitter. Then the emiter went to one side of the toy switch and the collector went to the other. This worked the 2N2222 transistor as a switch.
Look at the comments for the arduino pin wiring.
#include <X10Firecracker.h>
#include <Servo.h>
Servo myservo; // New instance of Servo.h
int rtsPin = 2; // RTS line for C17A - DB9 pin 7
int dtrPin = 3; // DTR line for C17A - DB9 pin 4
// Connect DB9 pin 5 to ground.
int servoPin = 5; // Servo used to lift the reel
int pirPin = 8;
int led1Pin = 10; // Left led
int led2Pin = 11; // Right led
int speakerPin = 12; // Piezo buzzer speaker
int bitDelay = 1; // mS delay between bits (1 mS OK)
int ledStatus = 0;
int calibrationTime = 30;
long unsigned int lowIn;
long unsigned int pause = 5000;
boolean lockLow = true;
boolean takeLowTime;
int booCounter = 1;
void setup(){
Serial.begin(9600); // Start serial communication at 9600 baud rate
pinMode(led1Pin, OUTPUT); // Set led1Pin digital pin to output
pinMode(led2Pin, OUTPUT); // Set led1Pin digital pin to output
pinMode(speakerPin, OUTPUT);// Set speakerPin digital pin to output
pinMode(servoPin, OUTPUT); // Set led1Pin digital pin to output
myservo.attach(7); // Atach servo on pin 7 for continous rotation servo
X10.init(rtsPin, dtrPin, bitDelay); // Initialize X10 C17A
pinMode(pirPin, INPUT);
digitalWrite(pirPin, LOW);
//give the sensor some time to calibrate
Serial.print("calibrating sensor ");
for(int i = 0; i < calibrationTime; i++){
Serial.print(".");
delay(1000);
}
Serial.println(" done");
Serial.println("SENSOR ACTIVE");
delay(50);
myservo.write(140);
}
void loop(){
if(digitalRead(pirPin) == HIGH){
Serial.print("[[[get|http://www.mysite.com/iobridge.html]]]"); // send serial message to iobridge.
digitalWrite(led1Pin, HIGH); //the led visualizes the sensors output pin state
digitalWrite(led2Pin, HIGH); //the led visualizes the sensors output pin state
if(lockLow){
// makes sure we wait for a transition to LOW before any further output is made:
lockLow = false;
// Release the reel by lifting servo.
myservo.write(140);
// Turn on toy with sound
digitalWrite(speakerPin, HIGH);
delay(100);
digitalWrite(speakerPin, LOW);
delay(7000);
myservo.write(65);
// send x10 commands to trun off/on lights
X10.sendCmd( hcC, 1, cmdOn );
X10.sendCmd( hcC, 3, cmdOn );
X10.sendCmd( hcC, 2, cmdOff );
int var = 0;
// Activate the continous rotation servo.
while(var < 800){
digitalWrite(servoPin,HIGH);
delayMicroseconds(1200); // 1.5ms
digitalWrite(servoPin,LOW);
delay(20); // 20ms
var++;
}
delay(50);
}
takeLowTime = true;
}
if(digitalRead(pirPin) == LOW){
if (ledStatus == 0){
digitalWrite(led1Pin, HIGH);
digitalWrite(led2Pin, LOW);
ledStatus = 1;
delay(100);
}
else{
digitalWrite(led1Pin, LOW);
digitalWrite(led2Pin, HIGH);
ledStatus = 0;
delay(100);
}
if(takeLowTime){
lowIn = millis(); //save the time of the transition from high to LOW
takeLowTime = false; //make sure this is only done at the start of a LOW phase
}
//if the sensor is low for more than the given pause,
//we assume that no more motion is going to happen
if(!lockLow && millis() - lowIn > pause){
//makes sure this block of code is only executed again after
//a new motion sequence has been detected
lockLow = true;
// Send x10 commands
X10.sendCmd( hcC, 1, cmdOff );
X10.sendCmd( hcC, 3, cmdOff );
X10.sendCmd( hcC, 2, cmdOn );
}
}
}
I used the 1K resistors on the led1Pin and led2Pin.
I used the 10K resistor on speakerPin going to 2N2222 transistor base, ground to the emitter. Then the emiter went to one side of the toy switch and the collector went to the other. This worked the 2N2222 transistor as a switch.
Look at the comments for the arduino pin wiring.
#include <X10Firecracker.h>
#include <Servo.h>
Servo myservo; // New instance of Servo.h
int rtsPin = 2; // RTS line for C17A - DB9 pin 7
int dtrPin = 3; // DTR line for C17A - DB9 pin 4
// Connect DB9 pin 5 to ground.
int servoPin = 5; // Servo used to lift the reel
int pirPin = 8;
int led1Pin = 10; // Left led
int led2Pin = 11; // Right led
int speakerPin = 12; // Piezo buzzer speaker
int bitDelay = 1; // mS delay between bits (1 mS OK)
int ledStatus = 0;
int calibrationTime = 30;
long unsigned int lowIn;
long unsigned int pause = 5000;
boolean lockLow = true;
boolean takeLowTime;
int booCounter = 1;
void setup(){
Serial.begin(9600); // Start serial communication at 9600 baud rate
pinMode(led1Pin, OUTPUT); // Set led1Pin digital pin to output
pinMode(led2Pin, OUTPUT); // Set led1Pin digital pin to output
pinMode(speakerPin, OUTPUT);// Set speakerPin digital pin to output
pinMode(servoPin, OUTPUT); // Set led1Pin digital pin to output
myservo.attach(7); // Atach servo on pin 7 for continous rotation servo
X10.init(rtsPin, dtrPin, bitDelay); // Initialize X10 C17A
pinMode(pirPin, INPUT);
digitalWrite(pirPin, LOW);
//give the sensor some time to calibrate
Serial.print("calibrating sensor ");
for(int i = 0; i < calibrationTime; i++){
Serial.print(".");
delay(1000);
}
Serial.println(" done");
Serial.println("SENSOR ACTIVE");
delay(50);
myservo.write(140);
}
void loop(){
if(digitalRead(pirPin) == HIGH){
Serial.print("[[[get|http://www.mysite.com/iobridge.html]]]"); // send serial message to iobridge.
digitalWrite(led1Pin, HIGH); //the led visualizes the sensors output pin state
digitalWrite(led2Pin, HIGH); //the led visualizes the sensors output pin state
if(lockLow){
// makes sure we wait for a transition to LOW before any further output is made:
lockLow = false;
// Release the reel by lifting servo.
myservo.write(140);
// Turn on toy with sound
digitalWrite(speakerPin, HIGH);
delay(100);
digitalWrite(speakerPin, LOW);
delay(7000);
myservo.write(65);
// send x10 commands to trun off/on lights
X10.sendCmd( hcC, 1, cmdOn );
X10.sendCmd( hcC, 3, cmdOn );
X10.sendCmd( hcC, 2, cmdOff );
int var = 0;
// Activate the continous rotation servo.
while(var < 800){
digitalWrite(servoPin,HIGH);
delayMicroseconds(1200); // 1.5ms
digitalWrite(servoPin,LOW);
delay(20); // 20ms
var++;
}
delay(50);
}
takeLowTime = true;
}
if(digitalRead(pirPin) == LOW){
if (ledStatus == 0){
digitalWrite(led1Pin, HIGH);
digitalWrite(led2Pin, LOW);
ledStatus = 1;
delay(100);
}
else{
digitalWrite(led1Pin, LOW);
digitalWrite(led2Pin, HIGH);
ledStatus = 0;
delay(100);
}
if(takeLowTime){
lowIn = millis(); //save the time of the transition from high to LOW
takeLowTime = false; //make sure this is only done at the start of a LOW phase
}
//if the sensor is low for more than the given pause,
//we assume that no more motion is going to happen
if(!lockLow && millis() - lowIn > pause){
//makes sure this block of code is only executed again after
//a new motion sequence has been detected
lockLow = true;
// Send x10 commands
X10.sendCmd( hcC, 1, cmdOff );
X10.sendCmd( hcC, 3, cmdOff );
X10.sendCmd( hcC, 2, cmdOn );
}
}
}
Step 4: Spider Reel
I end up using an VHS tape as a reel. I had to modify one servo to have continuous rotation. I used this guide to do so. The second servo just did the lift part.
Step 5: IoBridge Monitor
To establish the arduino-ioBridge serial communication I was planning to use an RF solution, but due to time constraints I had to use a long speaker cable to connect the arduino TX to ioBridge's Serial Board RX with one wire and the second for GND.
This is the bash script I used to trigger a sound as well as send a twitpic.
I used my mac os x Apache 2 server. I had to give write permissions to the access_log so I could append a bogus line as a "break".
This is the bash script I used to trigger a sound as well as send a twitpic.
I used my mac os x Apache 2 server. I had to give write permissions to the access_log so I could append a bogus line as a "break".
#!/bin/bash
booCounter=$1
while true;do
status=`tail -n 1 /private/var/log/apache2/access_log | cut -f 1 -d "-"`
if [ "$status" = "00.00.000.000 " ]
then
echo "Boo" >> /private/var/log/apache2/access_log
afplay /full/path/Halloween/werewolf.mp3
msg="Boo, victim $booCounter just got really scared"
sleep 5
curl -O http://www.mywebcam.com/IMAGE.JPG
curl -F media=@/full/path/Halloween/IMAGE.JPG -F "username=username" -F "password=password" -F "message=$msg" http://twitpic.com/api/uploadAndPost
let booCounter=booCounter+1
fi
done
Step 6: Fog Machine X10 Control
I got this fog machine that comes with manual fog release switch.
I just soldered the 125VAC/10A DPDT Plug-In Relay to the switch and connected to an X10 appliance module.
I just soldered the 125VAC/10A DPDT Plug-In Relay to the switch and connected to an X10 appliance module.
Step 7: Fog Chiller
I made this low laying fog cooler following this instructable.
Step 8: Raw Video
This video just shows the basic stuff without the sounds, fog and lights.