Introduction: Portal Turret Scare Crow

"This instructable was created in fulfillment of the project requirement of the Makecourse at the University of South Florida (www.makecourse.com)"

The idea behind this project was to create a device that could act as a scare crow based on a proximity sensor. The design is based of a turret from the game Portal, which is one of the first games I played. The Portal Turret Scare Crow has proven itself to be a formidable opponent against Husky-Shepard mixes, and most certainly keep any other pet away from your ramen noodles

Step 1: Download the Parts

Download the zip-file that contains all the parts of the Portal Turret Scare Crow. All the files will be in .STL format, which is necessary for 3-D printers to work with the models.

Step 2: Print the 3-D Parts

The 3-D printers should come with software that allows you to print the parts. Make sure that the models are laying flat and the widest parts are on the bottom. You'll need roughly half a roll (1 roll being 1 kg or 2.2 lbs) of 1.75 mm filament. I used white because the original turret is white. However, since you are reading this, you probably live in the free world so you can do whatever.

Step 3: Build the Arduino Circuit

Build the circuit according to the circuit diagram in the pictures. Since this will be inside of the turret, you want to use a small breadboard in order to make it fit. You will need the following pieces of equipment:

1 x Arduino Uno

1 x HC-SR04 Ultrasonic Sensor

1 x SG90 9G Servo

1 x IR Receiver

1 x IRREC-02 IR Remote

A bunch of cables to connect stuff up

Step 4: Upload the Code to the Arduino

Attached is the Arduino sketch file. Upload the sketch to your Arduino. Make sure that the right board is selected and that the port is connected as well. The code is also down below for the Ctrl-C, Ctrl-V type of people. Make sure you add the IRremote library to the program. Luckily, I feel generous enough to include the library for your convenience as well.

<p>#include <servo.h><br>#include "IRremote.h"</servo.h></p><p>Servo myservo; // create servo object to control a servo</p><p>const int trigPin = 7;
const int echoPin = 6;
int setting = 0;</p><p>/*-----( Declare Constants )-----*/
int receiver = 11; // pin 1 of IR receiver to Arduino digital pin 11</p><p>/*-----( Declare objects )-----*/
IRrecv irrecv(receiver);           // create instance of 'irrecv'
decode_results results;            // create instance of 'decode_results'
/*-----( Declare Variables )-----*/</p><p>void setup() {
// initialize serial communication:</p><p>Serial.begin(9600);
myservo.attach(9); // attaches the servo on pin 9 to the servo object
  Serial.println("IR Receiver Raw Data + Button Decode Test");
  irrecv.enableIRIn(); // Start the receiver
  setting = 2;
}
void loop() {
  if (irrecv.decode(&results)) // have we received an IR signal?
  {
//    Serial.println(results.value, HEX);  UN Comment to see raw values
    translateIR(); 
    irrecv.resume(); // receive the next value
  } 
// and the distance result in centimeters:</p><p>long duration, cm;
pinMode(trigPin, OUTPUT);
digitalWrite(trigPin, LOW);
delayMicroseconds(2);
digitalWrite(trigPin, HIGH);
delayMicroseconds(20);
digitalWrite(trigPin, LOW);
pinMode(echoPin, INPUT);
duration = pulseIn(echoPin, HIGH);</p><p>// convert the time into a distance</p><p>cm = microsecondsToCentimeters(duration);</p><p>// the condition for the distance
if (setting ==0){
myservo.write(30);
}
else if (setting == 1){</p><p>if ( cm > 15 && cm < 40)
{
myservo.write(70); // sets the servo position according to the scaled value
delay(200);
}
else if ( cm < 15)
{
myservo.write(110); // sets the servo position according to the scaled value
delay(200);
}
else if (setting ==2){
  myservo.write(105); // sets the servo position according to the scaled value
delay(200);
  
}
else
{
myservo.write(30); // sets the servo position according to the scaled value
delay(200);
}</p><p>//.print(setting);</p><p>//Serial.print("cm");</p><p>//Serial.println();</p><p>delay(100);
}
}
long microsecondsToCentimeters(long microseconds) {</p><p>// The speed of sound is 340 m/s or 29 microseconds per centimeter.</p><p>// The ping travels out and back, so to find the distance of the</p><p>// object we take half of the distance travelled.
return microseconds / 29 / 2;
}
/*-----( Declare User-written Functions )-----*/
void translateIR() // takes action based on IR code received
// describing Car MP3 IR codes 
{
  switch(results.value)
  {</p><p>  case 0xFFA25D:  
    Serial.println(" CH-            "); 
    break;</p><p>  case 0xFF629D:  
    Serial.println(" CH             "); 
    break;</p><p>  case 0xFFE21D:  
    Serial.println(" CH+            "); 
    break;</p><p>  case 0xFF22DD:  
    Serial.println(" PREV           "); 
    break;</p><p>  case 0xFF02FD:  
    Serial.println(" NEXT           "); 
    break;</p><p>  case 0xFFC23D:  
    Serial.println(" PLAY/PAUSE     "); 
    break;</p><p>  case 0xFFE01F:  
    Serial.println(" VOL-           "); 
    break;</p><p>  case 0xFFA857:  
    Serial.println(" VOL+           "); 
    break;</p><p>  case 0xFF906F:  
    Serial.println(" EQ             "); 
    break;</p><p>  case 0xFF6897:  
    Serial.println(" 0              "); 
    break;</p><p>  case 0xFF9867:  
    Serial.println(" 100+           "); 
    break;</p><p>  case 0xFFB04F:  
    Serial.println(" 200+           "); 
    break;</p><p>  case 0xFF30CF:  
    Serial.println(" 1              "); 
    myservo.write(90); // sets the servo position according to the scaled value
delay(100);
    break;</p><p>  case 0xFF18E7:  
    Serial.println(" 2              "); 
    myservo.write(30);
    setting = 1;
    Serial.println(setting);
    
    break;</p><p>  case 0xFF7A85:  
    Serial.println(" 3              "); 
    setting = 0;
    myservo.write(30);
    Serial.println(setting);
    break;</p><p>  case 0xFF10EF:  
    Serial.println(" 4              "); 
    setting = 2;
     myservo.write(110);
    Serial.println(setting);
    break;</p><p>  case 0xFF38C7:  
    Serial.println(" 5              "); 
    break;</p><p>  case 0xFF5AA5:  
    Serial.println(" 6              "); 
    break;</p><p>  case 0xFF42BD:  
    Serial.println(" 7              "); 
    break;</p><p>  case 0xFF4AB5:  
    Serial.println(" 8              "); 
    break;</p><p>  case 0xFF52AD:  
    Serial.println(" 9              "); 
    break;</p><p>  default: 
    Serial.println(" other button   ");</p><p>  }</p><p>  delay(500);</p><p>} //END translateIR</p>

Step 5: Assemble the Turret

You better get a hold on a fresh bottle of super glue because you are gonna need it. Once all parts are printed, assemble the parts using super glue. The circuitry will be placed at the bottom. There's room for a battery pack at the top in case you want to make a Portable Portal Turret Scare Crow.

Use the pictures as a reference on how to assemble the parts. The Ultrasonic sensor will go through the hole in the front. I used the default gear that came with the servo and glued the other gear on top of it.