Cat Exorcisor

I bought a pair of PIR detectors 'tother week, however have been pretty busy recently.

This afternoon i got them on board!

So the PIR sensors are mounted on a box, pointing at 90degrees to each other. They are effectivley covering a "left quadrent" and a "right quadrent".

i have arranged the code so that if the Left PIR sensor is activated, the Horizontal constrains are rewritten as "centre, to "rightmost limit". If the Right PIR sensor is activated, the constraints are rewritten at "centre, to left-most"

So in summary, the laser now wiggles in one of two boxes, one on the left or one on the right: the one the cat ISNT in.

it works with me wandering around the room, so now i need to go and find a cat.....

 

(im quite tempted to solder this project up on veroboard as a "shield" :) im pretty pleased with it.

though if i soldered it up, i wouldnt be able to "add features" as easily anymore)

 

**************** ^ ^ Update ^ ^ ******************

Having run the batteries down on a cheapo laser pen, i decided to break it up and pinch the laser diode. The cat LOVES (Hates) it.

So i took a Model sized servo, and onto the Arm, glued a mini servo, which i got with my Oomlout ARDX kit. Onto the mini servos arm, i attatched the Laser LED.

Now i have a two axis pointer thingy! It has gone through many itterations, and ive learnt alot! starting off just getting it to move! moving onto:

  • "random" movement
  • variable speed movement (rather than as fast as the servo can)
  • adding "constraints" to the motion within the program
  • referenceing potentiometer values for the constrains
  • adding an Xbox thumbstick controller to move the pointer
  • modifying the thumbstick code, so that rather than returning to centre upon stick release, it stays where it is (like a FPS game)
  • Toggle between two modes using button (thumbstick) press

and finally!

Now it starts at centre, static. Clicking the stick toggles to "constrain mode (1)". In this mode, you draw a box (using the thumb stick), and then clicking the stick, returns it to "random movement cat annoyance mode (0)", which makes random movements, at random speeds with random delays, while staying within the constrains defined in mode 1.

I reccomend this as a good beginner project, as getting it going is easy, but every addition makes it more and more complex!

also, unlike the rover, it doesnt require any batteries to be constantly charged and recharged, or space to drive around on.

Exorcises our Cat

  • Actuators / output devices: 2 servos, led's, red laser
  • Control method: Random, manual calibration
  • CPU: arduino uno
  • Power source: 9v battery, USB power for Arduino
  • Programming language: Arduino C++
  • Target environment: desktop

This is a companion discussion topic for the original entry at https://community.robotshop.com/robots/show/cat-exorcisor

Nice work

Well written. Maybe some code if you care to share. :slight_smile: Not that I am asking for the code.

I would be happy to share.

I would be happy to share. Nice someone is interested. Pressume i can paste it here with code tags?

Its on my computer at the mo, but i already posted it on www.ifyoulive.tumblr.com

Exorcism?? :smiley:

Well at first I really thought you had a demon-possessed cat :wink: Then I saw what you were up to, I actually bought a consumer cat toy that emitted a laser (fixed patterns, I think). In the end I had to return it because the motors moving the laser were so noisy my cat ended up staring at the laser tower instead of chasing the laser dot. Also, if the cat (at least mine) isn’t stimulated enough by the “random pattern” she just looses interest quickly. So basically the movements must be taunting. I mused some thoughts that if I could make a cheap and easy system which detected the dot being “caught” I would go forward … but then I put it off :slight_smile:

I hope your cat loves (hates) it and is also demon free. :stuck_out_tongue:

 

The servos are pretty quiet,
The servos are pretty quiet, so not distracting for her. She gets tired (and frustrated) after a little while, but I have set all the movement factors to random (each within appropriate constraints) so there is a random delay between half and 3 seconds between each move so it doesn’t get predictable. this definatly works, as when it does pause, she goes for a pounce.
I agree with the tracking idea. I figure the easiest way to do this would be to have two or three PIR sensors defining sectors (right and left quadrents perhaps?), and have the laser move to a sector she isnt in!

// Cat irritator randomise

I bought the PIR detectors today, so should be able to have a play at the zoning idea in the next few days…


// Cat irritator randomiser turret.

// constraints are defined by use of Xbox thumbstick
// definition of constraints is by use of “FPS” type movement, ie: input slews servo, release of input leaves servo where it is, rath
// r than returning to centre

#include <VarSpeedServo.h>

VarSpeedServo HoriServo; // create servo object to control a servo
VarSpeedServo VertServo; // create servo object to control a servo

//Connections
const int HoriPotPin = 1; // analog pin used to connect the potentiometer
const int VertPotPin = 2; // analog pin used to connect the potentiometer
const int stickbutton = 7; // Click the stick (Green)
const int ledPin = 13; // indicator LED

//Servo movement variables
int HoriPosVar = 5000; // variable to be used for calculating position
int VertPosVar = 5000; // variable to be used for calculating position
int HoriServPos; // HoriPosVar scaled and constrained for servo use
int VertServPos; // HoriPosVar scaled and constrained for servo use

//Servo constraint integers (start at centre)
int HoriMin = 90;
int HoriMax = 90;
int VertMin = 90;
int VertMax = 90;

// Toggle function
int prevState = HIGH; // variable for reading the pushbutton status
int currState; // variable for reading the pushbutton status
byte mode = 0; // byte used for storing “mode” (case 1 or case 0)

void setup()

  Serial.begin(9600); // serial port output for debugging.
  HoriServo.attach(9); // attaches the servo on pin 9 to the servo object
  VertServo.attach(10); // attaches the servo on pin 10 to the servo object
  randomSeed (analogRead (0)); // Randomizer seed for motion
  pinMode(ledPin, OUTPUT);
  pinMode(stickbutton, INPUT);

void loop()

  //toggle function:
  {
    // read the state of the pushbutton value:
    currState = digitalRead(stickbutton);

    if(currState != prevState)
    {
      if (currState == LOW) {
        mode =!mode;
      } 
      prevState = currState;
    }  

  }
  switch (mode) {

  case 1://**** mode 1: set constrains

    digitalWrite(ledPin, HIGH);

    // decreases in postion variable depenant on thumbstick push
    if (analogRead(HoriPotPin) < 450) {
      HoriPosVar-=1;
    }
    // increases in postion variable depenant on thumsbtick push
    if (analogRead(HoriPotPin) > 650) {
      HoriPosVar+=1;
    }
    HoriServPos = map(HoriPosVar, 0, 10000, 180, 0); // maps the position variable (large number) to servo position (180) to provide slow movement when adding 1 unit per processor cycle

    HoriServo.write(HoriServPos),10; // sets the servo position according to the scaled value

    //Vertical movement
    // decreases in postion variable depenant on thumbstick push
    if (analogRead(VertPotPin) < 450) {
      VertPosVar-=1;
    }

    // increases in postion variable depenant on thumsbtick push
    if (analogRead(VertPotPin) > 650) {
      VertPosVar+=1;
    }
    VertServPos = map(VertPosVar, 0, 10000, 180, 0); // maps the position variable (large number) to servo position (180) to provide slow movement when adding 1 unit per cycle
    VertServo.write(VertServPos),10; // sets the servo position according to the scaled value

    //movement Ends
    delay(1);

    // record the maximum sensor value
    if (HoriServPos > HoriMax) {
      HoriMax = HoriServPos;
    }
    // record the minimum sensor value
    if (HoriServPos < HoriMin) {
      HoriMin = HoriServPos;
    }
    // record the maximum sensor value
    if (VertServPos > VertMax) {
      VertMax = VertServPos;
    }
    // record the minimum sensor value
    if (VertServPos < VertMin) {
      VertMin = VertServPos;
    }

    break;

  case 0: // **** mode 0: Random movement within constraints defined during mode 1

    digitalWrite(ledPin, LOW);

    HoriServo.slowmove(random((HoriMin),(HoriMax)), 10); // move the servos randomly, within constraints defined by target size & elevation

    VertServo.slowmove(random((VertMin),(VertMax)), 10); // format is : (lower limit, upper limit, speed selection from range of 1:255)

    delay(random(500, 3000)); //wait and settle

    break;
  }
  // Serial.println(HoriPotPin); // serial port output for debugging. Replace value as required.