Introduction: Cat Fishing Pole

This instructable was created in fulfillment of the project requirement of the Makecourse at the University of South Florida (

For my project I designed a Cat Fishing Pole. I have two cats, one that is extremely playful and one that only likes laser pointers and cardboard boxes. I came up with the idea for this project because my cat, Bari, loves cat fishing poles. This project gives him a new fishing pole toy to interact with while also giving me the option of playing with him or setting it on random so that I can get back to whatever I was doing before he decided it was playtime.

Step 1: Block Diagram

My project uses an Arduino Uno to control the IR sensor, LED, and servo motors.

The remote sends IR signals to the IR sensor/receiver that is connected to the Arduino. The Arduino decodes these signals and directs the servos to move. A green LED diode is also attached to the Arduino to indicate when the Arduino has power. When the Arduino is turned on the green LED will illuminate. When the Arduino is turned off, the green LED will also turn off.

Step 2: Part List

The parts I used in my project are as follows:
- Arduino Uno x1

- IR Sensor/Receiver x1

- Green LED Diode x1

- TowerPro SG90 9G Mini Servo x2

- 220 Ohm Resistor x1

- Jumper Wires

- Mini Breadboard x1

- 9V Battery x1

- 9V Battery Case w/ On/Off switch x1

- Plastic cap x1 (Picked up at a local hobby store)

- Chicago screw post x1

- 4-hole Angle Bracket x1

- Speed Nut x1

- Plastic Super Glue x1

- Plastic Epoxy (JB Weld) x1

- IR Remote (sends IR signals) x1

- Felt x1 (to cover the hole on the lid)

- Springy cat toy (or whatever you want to put on top of the cat pole)

Step 3: 3D Printed Parts

The box, lid, servo connector, servo mounts, and pole were all 3D printed using the 3D printing lab (Advanced Visualization Center) on campus at the University of South Florida.

I printed:

- 1x Box.stl

- 1x Lid.stl

- 2x ServoMounts.stl

- 1x ServoConnector.stl

- 1x Pole.stl

The Box.stl is the box that I used to hold my project. The Lid.stl is the lid that sits on top of the box and allows the Pole.stl to move.

The ServoMounts.stl hold the servos and secures the first servo to the box and the second servo to the first servos arm. The Pole.stl is broken up into two parts: the part that sits on the ServoConnector.stl and the cylindrical pole. The cylindrical pole needs to be super glued to the part that sits on the ServoConnector.stl.

Step 4: Arduino Code

Below is the code for the Cat Fishing Pole (also available for download):

/* Title: Cat Fishing Pole
* Author: Amy Malkowski * Date: 5/1/2018 * Description: Uses two servos to create movement for a "cat fishing pole" that was 3D printed. A remote is used to send IR signals * to an IR sensor connected to the Arduino on pin 3. The signal gets decoded and depending on the code/button that was pressed, a * different movement will occur. The servos can move individually and synchronously. Buttons 1-9 on the remote have been programmed * to enable up, down, left, right, and diagonal movements. The "play/pause" button on the remote has been programmed for "random mode" * which chooses 1 of the 9 remote movements randomly 10 times with a 5 second delay in the loop when it has moved 10 times. * */

#include <IRremote.h> #include <Wire.h> #include <Servo.h>

int IR_pin = 3; // Sets the IR pin to pin 3 int LED = 6; // Sets the LED that indicates power to pin 6 IRrecv rec(IR_pin); // Sets the receiver pin to be the IR_pin decode_results results; // Sets the results returned from the decoder to results Servo firstServo; // The first servo is called firstServo Servo secondServo; // The second servo is called secondServo long unsigned int origIRval; // Assigns the possible remote values tied to servo movement to an array for random movement to pick from long unsigned int possIRval[] = {16724175,16718055,16743045,16716015,16726215,16734885,16728765,16730805,16732845}; int x = 0; // Assigned all servo angles to variables so they can all be changed in one place (if needed) const int s1topCorners = 40; const int s1topM = 35; const int s1Middle = 55; const int s1botCorners = 70; const int s1botM = 75; const int s2LCorners = 65; const int s2RCorners = 29; const int s2Middle = 47; const int s2MiddleL = 70; const int s2MiddleR = 24; const int btn_1=1; const int btn_2=2; const int btn_3=3; const int btn_4=4; const int btn_5=5; const int btn_6=6; const int btn_7=7; const int btn_8=8; const int btn_9=9; const int btn_play=10; const int btn_ch=11; int current = -1; int randomIndex = 0;

void setup() { Serial.begin(9600); pinMode(LED, OUTPUT); rec.enableIRIn(); // Start the receiver firstServo.attach(4, 800, 2500); // firstServo uses pin 4 secondServo.attach(5, 800, 2500); // secondServo uses pin 5 firstServo.write(55); // Sets the firstServo to its initial starting position (this position is the default position) secondServo.write(47); // Sets the secondServo to its initial starting position (this position is the default position) }

void loop() { digitalWrite(LED, HIGH); // If the receiver detects a command it will interpret the results if (rec.decode(&results)){ Serial.println(results.value); Serial.println(origIRval); Serial.println("in the if loop"); // The switch/case takes the possible button values and associates them with the buttons, which are referred to in a later switch/case statement. switch(results.value){ case 16724175: current=btn_1; break; case 16718055: current=btn_2; break; case 16743045: current=btn_3; break; case 16716015: current=btn_4; break; case 16726215: current=btn_5; break; case 16734885: current=btn_6; break; case 16728765: current=btn_7; break; case 16730805: current=btn_8; break; case 16732845: current=btn_9; break; case 16761405: current=btn_play; break; case 16769565: current=btn_ch; break; } rec.resume(); } // This switch/case statement actually assigns the servos to positions depending on which button is pressed switch(current){ // Button 1: Top left corner case btn_1: firstServo.write(s1topCorners); secondServo.write(s2LCorners); break;

// Button 2: Top Middle case btn_2: firstServo.write(s1topM); secondServo.write(s2Middle); break;

// Button 3: Top Right Corner case btn_3: firstServo.write(s1topCorners); secondServo.write(s2RCorners); break;

// Button 4: Middle Left case btn_4: firstServo.write(s1Middle); secondServo.write(s2MiddleL); break;

// Button 5: Middle-Middle (Centered) case btn_5: firstServo.write(s1Middle); secondServo.write(s2Middle); break;

// Button 6: Middle Right case btn_6: firstServo.write(s1Middle); secondServo.write(s2MiddleR); break;

// Button 7: Bottom Left Corner case btn_7: firstServo.write(s1botCorners); secondServo.write(s2LCorners); break;

// Button 8: Bottom Middle case btn_8: firstServo.write(s1botCorners); secondServo.write(s2Middle); break;

// Button 9: Bottom Right Corner case btn_9: firstServo.write(s1botCorners); secondServo.write(s2RCorners); break;

// Button Play/Pause: Random Mode case btn_play: randomIndex = random(0,8); results.value = possIRval[randomIndex]; //Remote: 1 if (results.value == 16724175){ //diagonal left firstServo.write(s1topCorners); // norm 35 secondServo.write(s2LCorners); // norm 70 //origIRval = results.value; } //Remote: 2 if (results.value == 16718055){ firstServo.write(s1topM); secondServo.write(s2Middle); //origIRval = results.value; } //Remote: 3 if (results.value == 16743045){ firstServo.write(s1topCorners); secondServo.write(s2RCorners); //origIRval = results.value; }

//Remote:4 if (results.value == 16716015){ firstServo.write(s1Middle); secondServo.write(s2MiddleL); //origIRval = results.value; } //Remote:5 if (results.value == 16726215){ firstServo.write(s1Middle); secondServo.write(s2Middle); //origIRval = results.value; } //Remote:6 if (results.value == 16734885){ firstServo.write(s1Middle); secondServo.write(s2MiddleR); //origIRval = results.value; }

//Remote:7 if (results.value == 16728765){ firstServo.write(s1botCorners); secondServo.write(s2LCorners); //origIRval = results.value; }

//Remote:8 if (results.value == 16730805){ firstServo.write(s1botM); secondServo.write(s2Middle); //origIRval = results.value; }

//Remote:9 if (results.value == 16732845){ firstServo.write(s1botCorners); secondServo.write(s2RCorners); //origIRval = results.value; } delay(550); // Brief pause between each servo movement. if(x==10){ // When in random mode, pause every 10 movements to give the servos a break. x=0; delay(5000); } x++; Serial.println(x); break;

case btn_ch: break;

default: break;

} }

Step 5: Assembly

Once all the parts have been gathered, you can begin the assembly of the Cat Fishing Pole.

1. Load the sketch on the Arduino. Change the remote codes to match your remote control.

2. Insert each servo into their mount. Super glue the second servo to the first servos arm. Put the 3D printed servo connector on the second servos gear.

3. Hold the first servo in the box and make sure that the angles are correct in the sketch for the first and second servo. Alter the code to match your angles as needed (this is because the initial angle of the first servos arm may not be the same as mine).

4. Drill a hole for the IR sensor/receiver. Super glue the IR sensor/receiver and the green LED where this hole is. Make sure you have enough room for the jumper wires to connect to the Arduino and these components!

5. Super glue the first servo into the box. It will be glued in the place you determined in the previous step.

6. Glue the plastic cap to the second servo, as close as you can to the axis of rotation (it is at the back of the servo where it actually turns).

7. Insert your chicago screw post through the 4-hole angle bracket and into the plastic cap. This is to stabilize the servos. Verify that the servos will be properly stabilized.

8. Remove the chicago screw post and put the lock washer toward the cap of the screw. Reinsert partly through the 4-hole angle bracket. Put the speed nut on the end and push the rest of the chicago screw through the L-bracket and into the plastic cap. Tighten the speed nut to ensure that the chicago screw post does not move.

9. Make sure the 4-hole angle bracket is in the proper position to stabilize the servos and use the epoxy to glue it to the bottom of the box.

10. Put your Arduino and mini breadboard into the box and connect all jumper wires properly. Remember to put the 220 Ohm resistor between the wire that is connected to the pin used to power on the green LED and the positive end of the LED.

11. Verify all components are connected and test that the servos perform as expected. If you have a problem with the servos, verify that you have the first servo connected to pin 4 and the second servo connected to pin 5.

12. Glue the felt to the lid and cut a hole large enough for the pole to fit through and move.

13. Connect the pole and whatever toy you have to the top of the pole.

14. Turn the Arduino on again and test your completed project!

Step 6: Final Project Demonstration

In the video you can see my completed project and all of its features:

- I have a green LED that indicates when the Arduino is powered on, which also indicates where the IR sensor is located.

- Buttons 1-9 are programmed on the remote to control the servo(s) movement. The "play/pause" button on the remote controls the "random" mode. While in random mode, the servos will move 10 times at a random button (1-9) position. If the random position is the same as the position before, the servo(s) will not move but this still counts as one of the 10 movements in the code. Because of this, the Cat Fishing Pole may move less than 10 times. After the 10 random movements the Cat Fishing Pole will pause for 5 seconds before beginning random movement again. This allows the servos to rest and not be constantly moving. It also entices the cats as they prefer their "prey" to not be constantly moving (at least this is true for my cats). To stop "random" mode, any of the buttons 1-9 can be pressed which stops the random movement and puts the Cat Fishing Pole in the position designated by the pressed button.

- The actual "pole" is removable so that the cat doesn't break the servos if they yank on the fluffy ball at the top of the toy. The toy also has a spring which takes the tension off of the servos, allowing the pole/toy to bend instead of servos.

Step 7: Find a Willing Participant

Getting footage of my cat, Bari, actually playing with the Cat Fishing Pole proved to be difficult. I initially made a nice tripod setup and lured him with treats to try to get footage of him playing with the project, but, like a typical cat, he ate the treats and walked away. Finally, I was able to get spontaneous footage of him playing with the project. Sorry for the shaky cam! The video shows Bari playing with the project and how it holds up to his heavy paws.

Thanks for taking a look at my project!

Microcontroller Contest

Participated in the
Microcontroller Contest