amrmostaafaa
Published © GPL3+

How to Build a DIY Animatronic Halloween Prop Using Arduino

Arduino Halloween robot that can be controlled manually and autonomously. It can play terrifying Halloween soundtracks with light changing.

IntermediateFull instructions provided9,089
How to Build a DIY Animatronic Halloween Prop Using Arduino

Things used in this project

Hardware components

Arduino Mega 2560
Arduino Mega 2560
×1
Jumper wires (generic)
Jumper wires (generic)
×30
Wire Cable - By the Foot
OpenBuilds Wire Cable - By the Foot
×4
wheel+motor+coupling
×2
Linear Regulator (7805)
Linear Regulator (7805)
×1
Servo Module (Generic)
×1
Ultrasonic Sensor - HC-SR04 (Generic)
Ultrasonic Sensor - HC-SR04 (Generic)
×1
Breadboard (generic)
Breadboard (generic)
×1
battery 3.7v 18650
×2
LED (generic)
LED (generic)
×3
Resistor 330 ohm
Resistor 330 ohm
×3
Slide Switch
Slide Switch
×1
motor driver 2 channel
×1
18650 dual battery box
×1
Android or iOS phone
×1
Dual channel motor driver
×1
1Sheeld
1Sheeld
×1

Software apps and online services

1sheeld

Hand tools and fabrication machines

Saw
Red paint
Hot glue gun (generic)
Hot glue gun (generic)
Pilers
Electrical tape
screw driver
Wood glue
Drill

Story

Read more

Custom parts and enclosures

Body design files

Schematics

Schematic

Code

Code

Arduino
#define CUSTOM_SETTINGS
#define INCLUDE_VOICE_RECOGNIZER_SHIELD
#define INCLUDE_MUSIC_PLAYER_SHIELD
#define INCLUDE_GAMEPAD_SHIELD
#define INCLUDE_TERMINAL_SHIELD
#define INCLUDE_KEYPAD_SHIELD
#define INCLUDE_SLIDER_SHIELD


/* Include 1Sheeld library. */
#include <OneSheeld.h>

#include <Servo.h>          //Servo motor library. This is standard library

//sensor pins
#define TRIG_PIN         4
#define ECHO_PIN         5


// motor pins define
#define R_MOTOR            8
#define L_MOTOR            9
#define RIGHT_MOTOR_DIR    19
#define LEFT_MOTOR_DIR     20

#define SERVO_PIN          3

// LEDs pins defines
#define MANU_LED    10
#define AUTO_LED   11


#define RED_PIN     6
#define GREEN_PIN   7
#define BLUE_PIN    12


#define THRESHOLD    70
#define PREPARE_DISTANCE      80
#define TURN_SPEED  80
int AUTO_SPEED = 255;

boolean autonomous = false;

int distance;
int distanceRight = 0;
int distanceLeft = 0;

//Set commands to be recognized by the Arduino Voice Recognition Shield
const char autonomous_command[] = "drive";
const char manual_command[] = "stop";

int diff = 35;
int speed_value = 100;
Servo servo_motor; //our servo name


void setup()
{
  OneSheeld.begin();
  VoiceRecognition.setOnNewCommand(&myFunction);
  
  pinMode(TRIG_PIN , OUTPUT);
  pinMode(ECHO_PIN , INPUT);
  
  pinMode(MANU_LED , OUTPUT);
  pinMode(AUTO_LED , OUTPUT);

  
  pinMode(RED_PIN , OUTPUT);
  pinMode(GREEN_PIN , OUTPUT);
  pinMode(BLUE_PIN , OUTPUT);
  
  
  pinMode(R_MOTOR, OUTPUT);
  pinMode(L_MOTOR, OUTPUT);
  pinMode(RIGHT_MOTOR_DIR, OUTPUT);
  pinMode(LEFT_MOTOR_DIR, OUTPUT);
  
  servo_motor.attach(SERVO_PIN); //our servo pin
  servo_motor.write(90);
  colorModeOff();
  delay(500);
}

void loop()
{
  
  if(autonomous == true)
  {
    autonomousIndicator();
    //Terminal.println("before drive call");
    AutonomousDrive();
    //Terminal.println("after drive call");
  }
  else
  {
    //Terminal.println("manual started");
    manualIndicator();
    moveStop();
      if (GamePad.isUpPressed())
      {
         moveStop();
         moveForward( speed_value );
         delay(50);
         moveStop();
      }
    
      if (GamePad.isDownPressed())
      {
         moveStop();
         moveBackward( speed_value);
         delay(50);
         moveStop();
      }
    
      if (GamePad.isRightPressed())
      {
         moveStop();
         turnRight();
         delay(50);
         moveStop();
      }
    
      if (GamePad.isLeftPressed())
      {
         moveStop();
         turnLeft();
         delay(50);
         moveStop();
      }
      //Terminal.println("manual finished");
  }

  
  // check for color modes
  if (GamePad.isOrangePressed())
  {
    colorModeOff();
  }

  // check for color modes
  if (GamePad.isRedPressed())
  {
    colorModeOne();
  }

  // check for color modes
  if (GamePad.isBluePressed())
  {
    colorModeThree();
    
  }

  // check for color modes
  if (GamePad.isGreenPressed())
  {
    colorModeTwo();
  }

  // check keypad for playing music
  /* If keypad's button 1 is pressed. */
  if(Keypad.isRowPressed(0) && Keypad.isColumnPressed(0))
  {
    MusicPlayer.stop();
    MusicPlayer.play(1);
  }

  /* If keypad's button 2 is pressed. */
  if(Keypad.isRowPressed(0) && Keypad.isColumnPressed(1))
  {
    MusicPlayer.stop();
    MusicPlayer.play(2);
  }

  /* If keypad's button 3 is pressed. */
  if(Keypad.isRowPressed(0) && Keypad.isColumnPressed(2))
  {
    MusicPlayer.stop();
    MusicPlayer.play(3);
  }

  /* If keypad's button 4 is pressed. */
  if(Keypad.isRowPressed(1) && Keypad.isColumnPressed(0))
  {
    MusicPlayer.stop();
    MusicPlayer.play(4);
  }

  /* If keypad's button 5 is pressed. */
  if(Keypad.isRowPressed(1) && Keypad.isColumnPressed(1))
  {
    MusicPlayer.stop();
    MusicPlayer.play(5);
  }

  /* If keypad's button 6 is pressed. */
  if(Keypad.isRowPressed(1) && Keypad.isColumnPressed(2))
  {
    MusicPlayer.stop();
    MusicPlayer.play(6);
  }

  /* If keypad's button 7 is pressed. */
  if(Keypad.isRowPressed(2) && Keypad.isColumnPressed(0))
  {
    MusicPlayer.stop();
    MusicPlayer.play(7);
  }

  /* If keypad's button 8 is pressed. */
  if(Keypad.isRowPressed(2) && Keypad.isColumnPressed(1))
  {
    MusicPlayer.stop();
    MusicPlayer.play(8);
  }

  /* If keypad's button 9 is pressed. */
  if(Keypad.isRowPressed(2) && Keypad.isColumnPressed(2))
  {
    MusicPlayer.stop();
    MusicPlayer.play(9);
  }

  /* If keypad's button 0 is pressed. */
  if(Keypad.isRowPressed(3) && Keypad.isColumnPressed(1))
  {
    MusicPlayer.stop();
    MusicPlayer.play(0);
  }

   /* If keypad's button # is pressed. */
  if(Keypad.isRowPressed(3) && Keypad.isColumnPressed(2))
  {
    MusicPlayer.stop();
  }


  // check for speed
  /* If keypad's button A is pressed. */
  if(Keypad.isRowPressed(0) && Keypad.isColumnPressed(3))
  {
    speed_value = 120;
  }

  /* If keypad's button B is pressed. */
  if(Keypad.isRowPressed(1) && Keypad.isColumnPressed(3))
  {
    speed_value = 160;
  }

  /* If keypad's button C is pressed. */
  if(Keypad.isRowPressed(2) && Keypad.isColumnPressed(3))
  {
    speed_value = 210;
  }

  /* If keypad's button D is pressed. */
  if(Keypad.isRowPressed(3) && Keypad.isColumnPressed(3))
  {
    speed_value = 255;
  }

  // check for autonomous switching
  /* If keypad's button * is pressed. */
  if(Keypad.isRowPressed(3) && Keypad.isColumnPressed(0))
  {
    if (autonomous == true)
    {
      autonomous = false;

    }
    else
    {
      autonomous = true;
    }
    delay(200);
  }
}
/*******************************************************************************************/
void AutonomousDrive()
{
  //Terminal.println("begin of drive call");
  moveForward(AUTO_SPEED);
  //Terminal.println("after move forwar call");
  delay(100);
  //Terminal.println("before ultrasonic read");
  distance = getUltrasonicDistance();
  //Terminal.println(distance);
  //Terminal.println("before distance check");


  // prepare robot to slow down if a probable obstacle detected
  if( distance > THRESHOLD && distance <= PREPARE_DISTANCE )
  {
    prepareForObstacle();
  }

  // return speed to its max value if the probable obstacle has removed
  if(distance > PREPARE_DISTANCE)
  {
    AUTO_SPEED = 255;
  }

  // check an obstacle detected on  adistance equal or less than the threshold
  if (distance <= THRESHOLD)
  {
     moveStop();
     delay(500);
     distanceRight = lookRight();
     distanceLeft = lookLeft();

     // turn right if right distance is greater
     if ( (distanceRight > THRESHOLD) && (distanceLeft <= THRESHOLD) )
     {
       moveBackward(AUTO_SPEED);
       delay(800);
       moveStop();
       delay(500);
       turnRight();
       delay(1000);
       moveStop();
       delay(500);
     }

     // or turn left
     else if ( (distanceLeft > THRESHOLD) && (distanceRight <= THRESHOLD) )
     {
       moveBackward(AUTO_SPEED);
       delay(800);
       moveStop();
       delay(500);
       turnLeft();
       delay(1000);
       moveStop();
       delay(500);
     }

     // or turn towards the biggest direction
     else if ( (distanceLeft > THRESHOLD) && (distanceRight > THRESHOLD) )
     {
        if(distanceLeft > distanceRight)
        {
          moveBackward(AUTO_SPEED);
          delay(800);
          moveStop();
          delay(500);
          turnLeft();
          delay(1000);
          moveStop();
          delay(500);
        }
        else
        {
          moveBackward(AUTO_SPEED);
          delay(800);
          moveStop();
          delay(500);
          turnRight();
          delay(1000);
          moveStop();
          delay(500);
        }
     }

     // or turn 180 degree if right and left are small
     else if ( (distanceLeft <= THRESHOLD) && (distanceRight <= THRESHOLD) )
     {
       moveBackward(AUTO_SPEED);
       delay(800);
       moveStop();
       delay(500);
       turnRight();
       delay(2000);
       moveStop();
       delay(500);
     }
  }
  //Terminal.println("end of drive call");
  
}
/*****************************************************************************************************/
int lookRight()
{  
  servo_motor.write(0);
  delay(300);
  int distance = getUltrasonicDistance();
  delay(100);
  servo_motor.write(90);
  delay(300);
  return distance;
}
/*****************************************************************************************************/
int lookLeft()
{
  servo_motor.write(180);
  delay(300);
  int distance = getUltrasonicDistance();
  delay(100);
  servo_motor.write(90);
  delay(300);
  return distance;
}
/*****************************************************************************************************/
void moveStop()
{
  digitalWrite(LEFT_MOTOR_DIR, HIGH);
  digitalWrite(RIGHT_MOTOR_DIR, HIGH);
  analogWrite(R_MOTOR , 0);
  analogWrite(L_MOTOR , 0);
}
/*****************************************************************************************************/
void moveForward(int motor_speed)
{
  digitalWrite(LEFT_MOTOR_DIR, HIGH);
  digitalWrite(RIGHT_MOTOR_DIR, HIGH);
  analogWrite(R_MOTOR , motor_speed);
  analogWrite(L_MOTOR , (motor_speed-diff) );
}
/*****************************************************************************************************/
void moveBackward(int motor_speed)
{
  digitalWrite(LEFT_MOTOR_DIR, LOW);
  digitalWrite(RIGHT_MOTOR_DIR, LOW);
  analogWrite(R_MOTOR , motor_speed);
  analogWrite(L_MOTOR , (motor_speed-diff) );
  
}
/*****************************************************************************************************/
void turnRight()
{
  digitalWrite(LEFT_MOTOR_DIR, HIGH);
  digitalWrite(RIGHT_MOTOR_DIR, LOW);
  analogWrite(R_MOTOR , TURN_SPEED);
  analogWrite(L_MOTOR , TURN_SPEED);
}
/*****************************************************************************************************/
void turnLeft()
{
  digitalWrite(LEFT_MOTOR_DIR, LOW);
  digitalWrite(RIGHT_MOTOR_DIR, HIGH);
  analogWrite(R_MOTOR , TURN_SPEED);
  analogWrite(L_MOTOR , TURN_SPEED);
}
/*****************************************************************************************************/
void autonomousIndicator()
{
  digitalWrite(AUTO_LED , HIGH);
  digitalWrite(MANU_LED , LOW);
}
/*****************************************************************************************************/
void manualIndicator()
{
  digitalWrite(MANU_LED , HIGH);
  digitalWrite(AUTO_LED , LOW);
}
/*****************************************************************************************************/

void colorModeOne()
{
  analogWrite(RED_PIN , 255);
  analogWrite(GREEN_PIN , 0);
  analogWrite(BLUE_PIN , 0);
}
void colorModeTwo()
{
  analogWrite(RED_PIN , 0);
  analogWrite(GREEN_PIN , 255);
  analogWrite(BLUE_PIN , 0);
}
void colorModeThree()
{
  analogWrite(RED_PIN , 0);
  analogWrite(GREEN_PIN , 0);
  analogWrite(BLUE_PIN , 255);
}
void colorModeOff()
{
  analogWrite(RED_PIN , 0);
  analogWrite(GREEN_PIN , 0);
  analogWrite(BLUE_PIN , 0);
}
/*****************************************************************************************************/
/* A function that makes the whole operation of the ultrasonic and returning the detected distance */
int getUltrasonicDistance(void)
{
  /* Variable to save the sound wave travel time in microseconds */
  long duration;

  /* Variable to save the detected distance in cm */
  int distanceReturned;

  /* Clears the TRIG_PIN */
  digitalWrite(TRIG_PIN, LOW);

  /* delay 2 micro seconds */
  delayMicroseconds(2);

  /* Sets the TRIG_PIN on HIGH state for 10 micro seconds */
  digitalWrite(TRIG_PIN, HIGH);

  /* delay 10 micro seconds */
  delayMicroseconds(10);

  /* Sets the TRIG_PIN on LOW state */
  digitalWrite(TRIG_PIN, LOW);

  /* Reads the ECHO_PIN, returns the sound wave travel time in microseconds */
  duration = pulseIn(ECHO_PIN, HIGH);


  /* Calculating the distance */
  distanceReturned = duration * 0.034 / 2;

  /* Returning the detected distance in cm */
  return distanceReturned;
}
/**************************************************************************************/
/* This function will be invoked each time a new command is given. */
void myFunction (String commandSpoken)
{
  char buff[200];
  unsigned int len = VoiceRecognition.getLastCommandLength() + 1;
  commandSpoken.toCharArray(buff, len);
  
  /* Print out the command spoken. */
  //Terminal.println(buff);
  
  //Compare the last command received by the Arduino Voice Recognition Shield with the command "activate autonomous"
    if(!strcmp(autonomous_command,buff))
    {
      autonomous = true;
      //Terminal.println("true");
    }
    //Compare the last command received by the Arduino Voice Recognition Shield with the command "activate manual"
    else if(!strcmp(manual_command,buff))
    {
      autonomous = false;
      //Terminal.println("false");
    }
}
/*************************************************************************************/
void prepareForObstacle()
{
  AUTO_SPEED = AUTO_SPEED - 5;
}
    

Credits

amrmostaafaa

amrmostaafaa

7 projects • 43 followers
Maker, Engineer, dreamer and passionate about technology.

Comments