Instructables

Halloween Props That Turn to Look at You as you Walk By

FeaturedContest Winner
Picture of Halloween Props That Turn to Look at You as you Walk By

Interactive Halloween props are always fun and they are surprisingly easy to make. This year I designed a simple system that rotates a skull to face you and follows you movements as you walk by.

To accomplish this I used light sensors to detect a person's shadow. An Arduino microcontroller then calculates where they are standing and activates a servo that turns the skull to face them. When they move, the skull turns to follows them.

 
Remove these adsRemove these ads by Signing Up

Step 1: Select a Halloween Prop to Use

Picture of Select a Halloween Prop to Use
The first thing that you need to do is select a Halloween prop that will turn and follow people walking by. Look for props that are both creepy and light weight. I chose to use a foam skull but there are a lot of other props that can also work. Use your imagination.

Step 2: The Light Sensors

Picture of The Light Sensors
cdsconstruction.jpg
graph.jpg
This project uses an array of light sensors to detect where a person is standing. I used CdS photoresistors but you could also use phototransistors.

When using photoresistors, you need to be aware that CdS photoresistors can vary quite a lot in their output characteristics. Even if you purchase a set of photoresistors that are the same type from the same manufacturer, the output of one photoresistor can still be very different from the next. There are several ways that you can compensate for this. You could change the other circuit components to match the photoresistors in the desired lighting. Another option is to change the Arduino code to compensate for different values of the photoresistors. You can add in a simple adjustment factor to any inputs, or you can write code that calibrates itself by referencing its average value. If all else fails you can purchase more photoresistors than you need in the hopes that you can get a group of them with approximately the same output characteristics.


 
nodoubtman18 hours ago

Hi! Nice project :)

What happens if you close completly the lights?

thanks!

marC:)

This project requires a direct light source in order to work. You could make something similar that would work in the dark, but that would require infrared LEDs and receivers.
mlesage1 month ago

Hi! I would like to know if it's possible to do this project with an HC-SR04 ultrasonic proximity? I want to use that project on the Halloween day, outdoor at night, so the photoresistor should have some problems to detect the shadow!

Thanks!

DIY Hacks and How Tos (author)  mlesage1 month ago

It will probably work as long as the signal is 5 volts or less

Nice! I'll try it!!! (When I will get my HC-SR04 from china! lol! Thanks Ebay!!


Thanks!! :)
Kenshow68732 months ago

Hey really liked this project so much that i just finished making my own copy of it however it keeps spazzing out every time i plug it in, i use the original code but i don't know where exactly where to adjust it within the code (if that makes sense). I want it to just move slowly at a constant pace like the one in your youtube video . I also am using 5 sensors instead of 3. Here what it looks like

photo.JPG

You can adjust the "threshold" variable. You may need to create a separate threshold variable for each sensor. You can also adjust the averaging speed. Another thing that will help is moving the sensors farther apart. You don't want the shadow to hit more than one sensor at a time.

So if i increase the threshold hold it should help?

artaex4 months ago

This is a cheap solution, but if you want highly accurate positioning you could use a Kinect sensor.

novianwf6 months ago

Hi, I try made this project using Arduino promini and LDR. It reach at goal point 1, but it cannot back to goal point (or reset point) and cannot reach the other goal point.
Can you help me please?

DIY Hacks and How Tos (author)  novianwf6 months ago
You may need to adjust the sensitivity of the light sensors in the code. Or you may need to change the values of the resistors.
novianwf6 months ago

Hi, I try made this project using Arduino promini and LDR. It reach at goal point 1, but it cannot back to goal point (or reset point) and cannot reach the other goal point.
Can you help me please?

ray7410 months ago
Awesome.
johnhr11 months ago
Hi, I can't get the code to run! It says, error: expected constructor, destructor, or type conversion before 'int'
In function 'void loop()';
error: 'PinOneCurrent' was not declared in this scope
Can you help please, thanks
DIY Hacks and How Tos (author)  johnhr11 months ago
I don't know, I just compiled it and it ran fine.
Hi, Thanks for your reply, got it sorted now, you were right, it didn't copy and paste properly.
Sorry for the trouble
Johnhr
sithdeath johnhr11 months ago
Something must not have copied properly. Its no biggie, just make sure the following is declared before void setup() {
int PinOneCurrent;

And after void loop() {
PinOneCurrent= analogRead(1);

Good luck :-)
My Wife love's projects & with Halloween coming up she'll love this stuff. I'm glad I stumbled across this page.,love it .
markmcg11 months ago
Great instructable! I tried this today and the servo just makes small motions back / forth (maybe 1/8") it doesn't seem to respond to covering up the CDS photosensors, any ideas?
DIY Hacks and How Tos (author)  markmcg11 months ago
Start by changing around the photoresistors to see if that does anything. Then try changing some of the values in the code like the averaging speed.
DragonDon11 months ago
Creepy! Love it!
slipstream1 year ago
Very cool and simple. I Have been wanting to do something like this for a while. I want to place outside (for day and night use) and I'm thinking that the photoresistors will not work (tell me if I'm wrong). So I was wondering if a Parallax PIR Sensor would be a better option.
Photoresistors will not work at night without an external light source. PIR can work, but that is a little more expensive.
Thanks for this cool project as I have been trying to figure out how to get this done for a couple of weeks now :-(. I have tried to use 3 Parallax PIR's, and since I have to use delay(), the servo will not turn in real time as yours does. I tried to modify your code to work with the PIR's, but when I tested the output of the sensor using a multimeter, when the sensor turns off, for a moment the voltage jumps to 7V, and I don't want to fry my Uno :-p. Any suggestions would be great. Thanks
The trouble with a PIR is that the output is HIGH when there is motion or LOW when there is not motion. It doesn't give values relative to how much motion. The best that you can do is have the skull turn to face the sensor that most recently detected motion. Another option is to use just two sensors and have the center position be the default that it will turn to when the sides don't detect motion.
Thank you for the quick response. I will give that a shot tomorrow as I currently tried using 3 PIR sensors... I will also try to see if I can get it working with 2 or 3 Ping sensors, since I have the ones which have both an echo and a trigger output, and let u know...
ok, so maybe when I have more time to mess with the PIR's, I will... In the meantime, I modified your code to include 2 Led's that will go on when the light sensors are triggered...

// Here is the Arduino code that I used.
// Open up the Arduino environment. Then copy and paste it into a new sketch.
// Then upload the code to the Arduino board.
// Based upon code from the following. Thank you
// http://www.instructables.com/id/Halloween-Props-That-Turn-to-Look-at-You-as-you-Wa/
// The only addition is that 2 LED's will now turn on when the light sensors are triggered, and go off after.

#include
Servo myservo; //create servo object to control a servo

#define led1 9
#define led2 10

int ResetTimer=0; //sets delay to reset position
int GoalPosition=3; //stores the goal postion (1-5) where the person is standing
int GoalPositionDegrees; //stores the goal position in degrees (30-150)
int CurrentPositionDegrees=90; //stores the current position in degrees (30-150)
int AveragingSpeed=100; //sets how quickly the average values adjust (a lower value changes average value quickly) //quickly. A value of 100 changes the average value slowly
// his effectively sets the speed at which the sensors recalibrate themselves to changing light conditions
int PinOneCurrent; //stores current value of pins 1-5
int PinTwoCurrent;
int PinThreeCurrent;
int PinFourCurrent;
int PinFiveCurrent;

float PinOneAverage; //stores the average value of pins 1-5
float PinTwoAverage;
float PinThreeAverage;
float PinFourAverage;
float PinFiveAverage;

float RatioPinOne=0.00; //stores the ratio of current pin value to average pin value
float RatioPinTwo=0.00;
float RatioPinThree=0.00;
float RatioPinFour=0.00;
float RatioPinFive=0.00;

float Threshold=0.95; //sets minimum threshold for sensors

void setup()
{
myservo.attach(13); //attaches servo to digital pin 13

pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);

PinOneAverage = analogRead(1); //reads from sensors to set initial average pin value
PinTwoAverage = analogRead(2);
PinThreeAverage = analogRead(3);
PinFourAverage = analogRead(4);
PinFiveAverage = analogRead(5);

}

void loop()
{
//read analog pins 1-5 and set the result as current value
PinOneCurrent= analogRead(1);
PinTwoCurrent= analogRead(2);
PinThreeCurrent= analogRead(3);
PinFourCurrent= analogRead(4);
PinFiveCurrent= analogRead(5);
//adjust average pin values
PinOneAverage=PinOneAverage+(PinOneCurrent-PinOneAverage)/AveragingSpeed;
PinTwoAverage=PinTwoAverage+(PinTwoCurrent-PinTwoAverage)/AveragingSpeed;
PinThreeAverage=PinThreeAverage+(PinThreeCurrent-PinThreeAverage)/AveragingSpeed;
PinFourAverage=PinFourAverage+(PinFourCurrent-PinFourAverage)/AveragingSpeed;
PinFiveAverage=PinFiveAverage+(PinFiveCurrent-PinFiveAverage)/AveragingSpeed;

//calculates ratio of current pin value to average pin value
RatioPinOne=(float)PinOneCurrent/PinOneAverage;
RatioPinTwo=(float)PinTwoCurrent/PinTwoAverage;
RatioPinThree=(float)PinThreeCurrent/PinThreeAverage;
RatioPinFour=(float)PinFourCurrent/PinFourAverage;
RatioPinFive=(float)PinFiveCurrent/PinFiveAverage;


//determine which ratio is the largest and sets the goal position
//set goal position

if (RatioPinThree < Threshold && RatioPinThree < RatioPinOne && RatioPinThree < RatioPinTwo && RatioPinThree < RatioPinFour && RatioPinThree < RatioPinFive)
{ GoalPosition=3;
LedOn();
ResetTimer=0; }
else if (RatioPinOne < Threshold && RatioPinOne < RatioPinTwo && RatioPinOne < RatioPinThree && RatioPinOne < RatioPinFour && RatioPinOne < RatioPinFive)
{ GoalPosition=1;
LedOn();
ResetTimer=0; }
else if (RatioPinTwo < Threshold && RatioPinTwo < RatioPinOne && RatioPinTwo < RatioPinThree && RatioPinTwo < RatioPinFour && RatioPinTwo < RatioPinFive)
{ GoalPosition=2;
LedOn();
ResetTimer=0; }
else if (RatioPinFour < Threshold && RatioPinFour < RatioPinOne && RatioPinFour < RatioPinTwo && RatioPinFour < RatioPinThree && RatioPinFour < RatioPinFive)
{ GoalPosition=4;
LedOn();
ResetTimer=0; }
else if (RatioPinFive < Threshold && RatioPinFive < RatioPinOne && RatioPinFive < RatioPinTwo && RatioPinFive < RatioPinThree && RatioPinFive < RatioPinFour)
{ GoalPosition=5;
LedOn();
ResetTimer=0; }
else if (ResetTimer > 100) //after delay resets to position 3
{ GoalPosition=3;
LedOn();
ResetTimer=0; }
else
{ ResetTimer=ResetTimer+1;
digitalWrite(led1,LOW);
digitalWrite(led2,LOW);
}


GoalPositionDegrees=GoalPosition*25+15; //converts the goal position to degrees

myservo.write(GoalPositionDegrees); //sets the servo position according to the scaled value

delay(30); //sets how quckly the servo turns (lower numbers turn more quickly)


}

void LedOn() {
digitalWrite(led1,HIGH);
digitalWrite(led2,HIGH);
}
bryan31411 year ago
Hmmm...I like this, but I'm thinking that it's time to revisit the old plastic skull model that you assemble and go with either red LEDs or eyeballs and make them face the person instead. should be able to fit most of the mechanicals inside the skull kit.
poofrabbit1 year ago
This is cool nicely done!