Intruder Scarer, Laughing Skull

by claudiaclave in Circuits > Arduino

487 Views, 2 Favorites, 0 Comments

Intruder Scarer, Laughing Skull

Intruder Scarer, Laughing Skull
20221101_221122198_iOS.jpeg
20221101_221138886_iOS.jpeg
20221101_220802422_iOS.jpeg

Looking for an easy to make and scary DIY element for Halloween? Here we bring you the solution!

We are AlĂ­cia, Claudia and Joaquim, three university students that invented a prototype for those Halloween fanatics that want to scary their neighbors with different elements you can easily find.

This is a skeleton head that seeks to attract its prey with scary sounds and music so that when someone approaches.... BOO! It brings out its darkest laugh and then looks for its next target.

Scheme of Electrical Connections

6.png
7.png
7 còpia.png

In this section, you can see how the different components are connected to the Arduino UNO. To make it easier to read, it has been explained element by element according to the function they play in the code and in the prototype.

Flow Diagram

8.png

Downloads

Code

// First of all, we include all the libraries we are going to use for the code.


#include <DFRobotDFPlayerMini.h>

#include <SoftwareSerial.h>

#include <Servo.h>


//Then, we declare the diferent variables and some of the pins of each element.


//Variables for each servo, one for the mouth and another for the head.

Servo servo_boca;

Servo servo_cap;


//Pins we will use for the ultrasonic distance sensor.

const int Trigger = 10;

const int Echo = 11;

long limit = 10; // Limit distance at which the actions that we declare, will start or not.


//Variables to control de timing of the actions with the millis() function

unsigned long lastTime, lastTime2;


//Boolean variables so that the Arduino let us know if an action it has been done or not.

bool estatPir = false;

bool cap = false;

bool led1 = false;

bool led2 = false;


float velocitat = 0.0343;


//We define the Tx and Rx pins of the DF player

SoftwareSerial myserial(6, 5); //conect Tx and Rx or vice versa

DFRobotDFPlayerMini myMP3;   //Here we declare the name we want for the SD



void setup() {


 //Here we declare the servo pins

 servo_boca.attach(A5);

 servo_cap.attach(A3);


 //The LEDs pins

 pinMode(3, OUTPUT);

 pinMode(4, OUTPUT);


 //The Distance sensor pins

 pinMode(Trigger, OUTPUT);

 pinMode(Echo, INPUT);


 Serial.begin(115200);


 //Here we set an initial state for the head.

 servo_cap.write(0);


 //This is a way for the Arduino to communicate to us if the Audio system is working or not.

 myserial.begin(9600);

 if (!myMP3.begin(myserial)) {

  Serial.println(F("ERROR!!"));

  while (true)

   ;

 } else {

  Serial.println(F("It is working"));

 }


 // Here we define the different coding elements to set up the audio system

 myMP3.setTimeOut(500); //Set serial communicacion time out 500ms

 myMP3.volume(10);   //Set volumen (0~30).

 myMP3.EQ(DFPLAYER_EQ_NORMAL);

 myMP3.outputDevice(DFPLAYER_DEVICE_SD);

 

}



void loop() {


 long temps; //It is used to determinate the time it takes to reach the Eco

 long dist; //It is used to determinate the distance in cm that the sensor detects


 //We detarminate for how long the sensor is going to read what is ahead of him, each time he repeats the action

 digitalWrite(Trigger, HIGH);

 delayMicroseconds(10);

 digitalWrite(Trigger, LOW);


 // Here we transform the time and the velocity he takes to get the information to a cm distance

 temps = pulseIn(Echo, HIGH);

 dist = velocitat * temps / 2;



 /* We determinate which actions the prototipe will perform when someone approaches to the sensor.

 To do so, we declare the variable representing the sensor as true, so that even if no one is near,

 the actions will continue until the entire cycle is finished. */


 if (dist < limit && dist > 8) {

  estatPir = true;

 }


 if (estatPir == true) {


  //First we set the program to analyze whether the head is turned or not and if the sensor has sensed anything.


  if (cap == false && estatPir == true) {

   servo_cap.write(180);

   delay(150);

   cap = true;     //We set the variable head to true, as we have already given the command to rotate.

   lastTime = millis(); //Here the time starts running with the millis() function and everything is saved inside the lasTime variable.

   led1 = false;    //We define both leds as flase since they are initially turned off

   led2 = false;

  }


  // We set the music to start with the laughter sound.

  myMP3.play(3);

  delay(1000);


  /* Here we configure that since the varible lastTime started to run, when the difference between it and the actual time

   is more 1000ms and the leds are off, to turn them on. We use this to know if the Ardunino understood and exectuted our command. */


  if (millis() - lastTime > 1000 && led1 == false && led2 == false && estatPir == true) {

   digitalWrite(3, HIGH);

   digitalWrite(4, HIGH);

   led1 = true; //We define both leds as true since they are now on

   led2 = true;

   lastTime2 = millis(); //Here the time starts running again, but this time everything is saved inside the lasTime2 variable.

  }


  /* Here we configure again that since the varible lastTime2 started to run, when the difference between it and the actual time

   is more 1000ms and both ot the leds are on, to start moving the servo mouth */


  if (millis() - lastTime2 > 1000 && led1 == true && led2 == true && estatPir == true) {

 


   //We put a for loop so that the servo moves in different degrees simulating the movement of the mouth. This action is repeated 4 times.

   for (int i = 0; i < 4; i++) {

    servo_boca.write(30);

    delay(250);

    servo_boca.write(10);

    delay(100);

    servo_boca.write(45);

    delay(150);

    servo_boca.write(20);

    delay(350);

   }


   //We turn off the leds as well as declare their variables as false.

   digitalWrite(3, LOW);

   digitalWrite(4, LOW);

   led1 = false;

   led2 = false;


   // We close the mouth and rotate the head again as well as declare their variables as false.

   servo_cap.write(0);

   servo_boca.write(0);

   myMP3.pause();

   myMP3.play(2);

   delay(1000);

   cap = false;

   

  }

 }


 /* Finally, once all the variables are false and their components are off, we declare the sensor variable as false.

 Thus, once the cycle is finished, the action loop does not start again, unless the sensor detects something. */


 if (led1 == false && led2 == false && cap == false && estatPir == true) {

  estatPir = false;

 }

}

Building the Prototype

10.png
11.png
11 c&ograve;pia.png

Building the Electronics

12.png
12 c&ograve;pia.png

Conclusion

Thanks to this work we have been able to deepen our knowledge of tools such as Arduino, both at the level of programming the code and at the level of using inputs and outputs such as proximity sensors or servos. In addition, we also have been able to achieve the goal that was proposed to us to create a Halloween object that incorporates all the elements studied throughout the quarter.

We have realised that in terms of decoration, any small detail that has an electronic part with a code behind it is much more impressive than an immobile object.

However, throughout the process we have encountered several problems when programming, especially because for its subsequent resolution, we lacked sufficient knowledge to be able to find what was failing us.

Some of them were to define the relationship that each action would have with its respective time (expressed with the millis function), which we solved thanks to the Boolean variables. Another one of them was when connecting the audio system and delaying it with the code, since it overlapped with the startup of other components and even some of them stopped working correctly.

Nevertheless, by analyzing the code step by step and thanks to the fact that nowadays everything related to Arduino programming is opensource, we have been able to solve all the difficulties that were encountered to finally develop this fantastic prototype.