Sad Cat Project
I created this machine for my Grade 12 Computer Engineering course as an assignment to make sad cats, happy. The idea to make an automatic mouse chasing machine came from finding videos of cats online chasing mice and lasers. This made me think to create a machine that allows cats to chase mice and lasers without a person present to hold the toy.
Circuit Diagram:
The circuit diagram above shows all the connections for the physical circuit. Please use this as a reference along with the provided pictures to construct the toy.
How to use the device:
NOTE: There are two modes, automatic and manual. The program first begins in manual. Press the power button on the remote to change it to automatic.
How to use manual:
- upload the attached code to your Arduino
- "4" 180 degrees left side position
- "6" 180-degree right side position
- "2" 90-degree middle position
- "1" 45 degrees left side position
- "3" 45-degree right side position
- press the power button to switch to automatic if you would like
How to use automatic:
- when the cat is within 40 cm of the sensor, the servo motor will move
- to switch back to manual press and hold the button you wired on the breadboard
Here is a link to the google slide for my project pitch:
https://docs.google.com/presentation/d/1h3S-ffbXAlkM1V9yZS7Esq9rMlmbBPoGVr07toCeFuM/edit?usp=sharing
Code Explanation: Variables
#include <Servo.h> //inputs the servo library into the program
#include <IRremote.h> //inputs the IRemote library into the program
Servo myservo; //creates a my servo object used to control the servo motor
int Servogoto; //creates a variable to store the value that the motor will turn to
int RECV_PIN = 11; //assigns the variable RECV_PIN to pin 11
IRrecv irrecv(RECV_PIN); //tells the program the RECV_PIN will be reading the ultrasonic waves
decode_results results; //variable used to store the result from the remote
int sendPin = 5; // Trigger Pin of Ultrasonic Sensor assigned to pin 5
int receivePin = 6; // Echo Pin of Ultrasonic Sensor assigned to pin 5
long cm; //creates a variable cm to store the conversion from microseconds
long duration; //stores the microseconds read from the sensor
int mode = 1; //mode variable used to switch between the modes of the device
int buttonPin = 2; //assigned the button to pin 2
This section of the code includes all of the variables which allow the code to run properly.
Code Explanation: Setup Function
void setup()
{
myservo.attach(9);//attaches the servo on pin 9 to servo object
myservo.write(90);//moves the motor to 90 degree's
pinMode(buttonPin, INPUT); //sets the button to an input
delay(1000); //delay of 1 second
Serial.begin(9600); //sets the speed at which the program sends data to the serial monitor
pinMode(sendPin, OUTPUT); //sets the send pin from the ultrasonic sensor as an output
pinMode(receivePin, INPUT); //sets the receive pin from the ultrasonic sensor as as input
irrecv.enableIRIn(); //enables the IR input to be detected
}
This section of the code is used to prepare the Arduino for the loop function. It begins by attaching the servo motor to pin 9 and moving it to the 90-degree position. It then sets the button as an input allowing the Arduino to read the button input. The speed as which as communicate with the serial monitor is then set to 9600. The send and receive pins from the ultrasonic sensor are set to input and output. Finally, the IR is enabled allowing the remote to send signals.
Code Explanation: Loop Function (Manual Mode)
while (mode == 1) //while the mode is set to 1(manual control)
{
if (irrecv.decode(&results)) //if the remote receives a value it will decode it
{
irrecv.resume(); //allows the receiver pin to receive new information
switch (results.value) //telling the switch to read to results.value variable
{
case 0xFF10EF: //if the 4 key is pressed on the remote
myservo.write(180); //moves the servo motor to 180 degree's
break ;
case 0xFF30CF: //if the 1 key is pressed on the remote
myservo.write(135); //moves the servo motor to 135 degree's
break ;
case 0xFF18E7: //if the 2 key is pressed on the remote
myservo.write(90);//moves the servo motor to 90 degree's
break ;
case 0xFF7A85: //if the 3 key is pressed on the remote
myservo.write(45);//moves the servo motor to 45 degree's
break ;
case 0xFF5AA5: //if the 6 key is pressed on the remote
myservo.write(0);//moves the servo motor to 0 degree's
break ;
case 0xFFA25D: //if the power key is pressed on the remote
mode = 0;//switched the input to the sensor
break ;
}
irrecv.resume(); //resets the receiver after if has been pinged and prepares it to receive more information
}
}
This section of the code uses a switch function to check which button on the remote has been pressed. It will then move the servo motor to the corresponding angle once a button has been pressed.
Code Explanation: Loop Function (Automatic Mode)
while (mode == 0)
{
digitalWrite(sendPin, LOW); //turns the send pin off
delayMicroseconds(2); //delay to keep it off for 2 ms
digitalWrite(sendPin, HIGH); //turns the send pin on
delayMicroseconds(10); //delay to send waves for 10 ms
digitalWrite(sendPin, LOW); //turns the send pin off
duration = pulseIn(receivePin, HIGH); //turns the receive pin on to see read the waves returning
cm = converter(duration); //calls the converter function to convert the reading from duration to cm
if (cm < 40)//checks if the cm reading is less than 40 meaning the cat is close to the device
{
Servogoto = random(0, 180);//selects a number from 0 to 180
myservo.write(Servogoto);//moves the servo to the position in degree selected by the random function
delay(500); //delay of 500 ms to allow the servo motor to move
if (digitalRead(buttonPin) == HIGH)//checks if the button is pressed to turn off automatic
{
mode = 1;//sets the mode to manual
}
}
else
{
if (digitalRead(buttonPin) == HIGH)//checks if the button is pressed to turn off automatic
{
mode = 1;//sets the mode to manual
}
}
printSensor(); //calls the print sensor function
}
}
The section of the code is used to control the automatic mode. It will first ping the send pin sending out waves to bounce off objects. The program will then trigger the receive pin to read the duration of the waves. A conversion function will then be called to convert the waves to cm. If the cat is within 40 cm of the device the toy will select a random angle between 0 to 180. It will then move the servo motor to that position and repeat this process until the cat is farther than 40 cm from the device or the manual mode button has been pressed.
Code Explanation: Converter Function
long converter(long microseconds) //converter function used to convert duration in ms to cm
{
return microseconds / 29 / 2; //conversion ratio to convert ms to cm
}
This function is used to convert the microseconds to cm. it decides the duration first by 29 and then by 2.
Code Explanation: Serial Print
void printSensor()//print sensor function used to print the readings from the sensor
{
Serial.print("Sensor: "); //prints the word sensor
Serial.print(cm); //prints the cm read
Serial.print("cm"); //prints the word cm
Serial.println("");//moves to the next line
}
This function was used during the development of the device to check if the ultrasonic sensor is working correctly.
Downloads
Supplies
- Breadboard
- Arduino
- Breadboard wires (male-male) (male-female)
- ultrasonic sensor
- IR Remote
- servo motor
- button
- 1K resistor
- cardboard box
- tape
- stick
- string
- ball or fake mouse
Setup 5V and GND
Connect the 5V pin on the Arduino to the red rail on the breadboard using a red male-male wire. Then bridge the two red rails at the top and bottom of the breadboard using another red male-male wire. Next, connect the GND pin on the Arduino to the blue rail on the breadboard using a black male-male wire. Connect the two blue rails on the top and bottom of the breadboard using another black wire. (NOTE: the wire color allows you to keep track of all power and GND wires throughout the circuit. Color coordination is not mandatory.)
Setting Up the Button
Place the button on the very right or left of the breadboard in between the gap in the middle. Following, connect the left side of the button to one of the power rails on the breadboard. Thirdly, connect a 1k resistor to the other side of the button and the GND rail. Finally, in between the button and the GND connection use a male-male wire to connect the button to pin 2. You now have a functional button that will read "0" or negative when the button is not pressed. (NOTE: This can be done with the pull-up function however the code would have to be altered.)
Connecting the IR Remote
Place the IR receiver in the middle of the breadboard. Face the receiver module towards you to avoid mistakes. Connect the left pin to the GND rail on the breadboard using a male-male wire. Connect the middle pin on the receiver to the 5V rail on the breadboard using a male-male wire. Finally, connect the most right pin on the receiver to pin 11 on the Arduino. Your IR receiver should now be able to receive signals from the remote.
Connecting the Servo Motor
Connect a black male-male wire to the brown wire female connecter on the servo motor. Subsequently, connect the other end of the black wire to GND. Connect a red male-male wire to the red female connection on the servo motor. Then, connect the other end of the red wire to the 5V rail on the breadboard. Finally, connect a male-male wire to the orange female connector in the servo motor and connect the other end of the wire to pin 9 on the Arduino. Your servo motor is now connected to the circuit.
Connecting the Ultrasonic Sensor
Using a black female-male wire, connect the female end to the GND pin on the sensor and the male end to the GND rail on your breadboard. Using a red female-male wire, connect the female end to the VCC pin on the sensor and the male end to the 5V rail on your breadboard. Connect another female-male wire to the "trig" pin on your sensor and the other end to pin 5 on the breadboard. Finally, connect a female-male wire to the "echo" pin on your sensor and to pin 6 on your Arduino. Your ultrasonic sensor is now able to send and receive waves.
Constructing the Frame
Using a tall box, pick a side to face you. 4 to 6 cm from the button, cut two wholes 1 cm apart each, with a diameter of 1.5 cm. Secondly, with the same side facing you, cut a hole on the right or left side (depending and what side you placed the button on) roughly 3cm in length and 2cm in height. This is where the button will stick out in order for it to be pressed. Next, cut a hole below the ultrasonic sensor in order for the IR receiver to receive signals from the remote. This whole could be any size you like, however, I recommend leaving an inch on each side of the box to maintain structural integrity. On the side, cut the hole for the button, and cut a hole in the bottom left to fit the Arduino power port. Finally, cut a hole in the top of the box to fit the servo motor.
Slide the breadboard through the top of the box ensuring the button pokes out the button whole. Next, place the ultrasonic sensor in the two holes cut for the sensors, and slide the Arduino power port through the power whole. Ultimately, slide the servo motor through the hole at the top ensuring the wires are not caught, and secure it with tape.
Connecting Cat Toy
Attach a skewer to the servo motor using glue or tape. Ensure it is secure and balanced in order for the motor to easily move. Tie a string to the skewer, and lastly, tie the other end to the toy you chose to attach: mouse, ball, etc...