Samstag, 19. November 2016

Automated Laser cat toy. The Jack-O-Mat

Well at some point in the life of a cat owner (or like me if you are living with a cat) you will try out one of those little Laser pointers. Problems begin not if your cat does not like it but when it loves it so much it demands loudly to be switched on no matter the time of the day. And you wish your hand would not get tired. Also would it not be great if he could play with it when you are gone so he is less bored?

So here is what I grabbed to make life for the both of us easier..:
- Old Arduino Uno
- Phone charger
- Two 3€ servos
- The cat laser pointer (I do not want to hurt him with it so I used the one from the Pet store and but a piece of scotch over it to attenuate it further)
- A bit of plywood
- Leftover screws, wires and some rope.



Glue everything together..

Using the easy standard servo libraries provided by Arduino (see the examples)
you can move the servos around. I mapped our hallway using a serial interface to get the points in space and wrote a few simple functions. Code below


I did not solder on the laser but simply stuffed in two wires to the connections instead of the battery and the Arduino can drive it perfectly well without additional amplification.
The switch is operated by the cat itself and it works wonders. Once he got used to pulling the rope he would not stop any more hunting the pointer that day. He still uses it several times a day and night.



1:  #include ;  
2:  Servo servo1;  
3:  Servo servo2;  
4:  int currx,curry;  
5:  void setup()  
6:  {  
7:   pinMode(7, INPUT_PULLUP);  
8:   pinMode(13, OUTPUT);  
9:   digitalWrite(13,LOW);  
10:   run();   
11:  }  
12:  int returnbigger(int x,int y){  
13:   if (x>y) return abs(x);  
14:   else return abs(y);  
15:  }  
16:  void move(int x,int y,double speed=0)  
17:  {  
18:   if (speed==0){  
19:    servo1.write(x);  
20:    servo2.write(y);  
21:    delay(110);  
22:   }  
23:   else{  
24:    int stepi = currx - x;  
25:    int stepj = curry - y;  
26:    speed = speed/returnbigger(abs(stepi),abs(stepj));  
27:    for (int i = 0; i< returnbigger(abs(stepi),abs(stepj)); i++){  
28:     servo1.write(currx-i*(stepi/returnbigger(abs(stepi),abs(stepj))));  
29:     servo2.write(curry-i*stepj/returnbigger(abs(stepi),abs(stepj)));   
30:     delay(speed);  
31:    }  
32:   }  
33:   currx=x;  
34:   curry=y;  
35:  }  
36:  void run(){  
37:   servo1.attach(9);  
38:   servo2.attach(8);  
39:   laseron();  
40:   move(110, 110);  
41:   move (110,30,6000);  
42:   move (110,140,8000);  
43:   move (110,30,6000);  
44:   move (110,140,8000);  
45:   move (110,30,8000);  
46:   move (110,140,6000);  
47:   move (110,30,8000);  
48:   move (110,140,8000);  
49:   move (110,30,3000);  
50:   circle(110,30,3,1100);  
51:   circle(110,30,4,1100);  
52:   circle(110,30,3,1100);  
53:   circle(110,30,4,1100);  
54:   circle(110,30,3,1100);  
55:   circle(110,30,3,1100);  
56:   move (110,140,8000);  
57:   circle(110,140,5,1100);  
58:   circle(110,140,5,1100);  
59:   circle(100,135,5,1100);  
60:   circle(100,140,5,1100);  
61:   circle(100,135,6,1100);  
62:   circle(100,140,7,300);  
63:   circle(110,140,7,200);  
64:   circle(110,140,9,500);  
65:   circle(100,135,7,400);  
66:   circle(100,140,8,600);  
67:   circle(100,135,8,300);  
68:   circle(100,140,8,200);  
69:   circle(110,140,8,200);  
70:   circle(100,135,9,300);  
71:   circle(100,140,8,300);  
72:   circle(100,135,9,200);  
73:   circle(110,140,8,300);  
74:   move (110,30,6000);  
75:   move (110,140,8000);  
76:   move (110,30,6000);  
77:   move (110,140,8000);  
78:   move (110,30,8000);  
79:   move (110,140,6000);  
80:   move (110,30,8000);  
81:   move (110,140,8000);  
82:   laseroff();  
83:   servo1.detach();  
84:   servo2.detach();  
85:  }  
86:  void circle (int x, int y , int r, double speed)  
87:  {  
88:   move(x+r,y,speed);  
89:   move(x+r,y+r,speed);  
90:   move(x-r,y,speed);  
91:   move(x-r,y-r,speed);  
92:   move(x,y,speed);  
93:  }   
94:  void pause(int second){  
95:   delay(second*1100);   
96:  }  
97:  void laseron(){  
98:   digitalWrite(13, HIGH);  
99:  }  
100:  void laseroff(){  
101:   digitalWrite(13, LOW);  
102:  }  
103:  void loop()  
104:  {   
105:   int sensorVal = digitalRead(7);  
106:   if (sensorVal == LOW) {  
107:    run();  
108:   }   
109:  }