Cat Sprayer

Problem - My elderly cat has suddenly decided that she doesn’t want to use the litter box and is instead peeing on the hardwood floor under the dining table. I’ve tried a bunch of things to dissuade her but nothing has worked. The only thing she hates worse than the spray bottle is the vacuum*. So, I built motion sensor spray bottle. Here’s how to build your own.

*If this doesn’t work, maybe I’ll have automate the vacuum next

Components -

Arduino Uno clone

Spray Bottle

MG996 Servo https://www.amazon.com/gp/product/B01N4QD32E

PIR sensor https://www.adafruit.com/product/189

Hose clamp

100uF Capacitor https://www.adafruit.com/product/2193

Steel Picture hanging wire

Assorted wires, heatshrink, solder, zip ties

Breadboard layout

Step 1 - Breadboard and Test

Connect the red wires to the power pin on your PIR and Servo.

Connect the black wires to the ground connections

Connect digital Pin 6 to the PIR and Pin 9 the servo control.

Connect the capacitor to the red and black wires as shown. The longer lead of the capacitor is the positive lead and this should be connected to 5V.

When running off a strong USB power source from my computer, I didn’t need the capacitor, but when running off any other source, the arduino would reset immediately when the servo powered up. Before I found the capacitor solution in the Adafruit tutorial, I tried upping the voltage and using stronger power supplies connected to the Vin pin and ended up frying an Arduino. Using a cap seems to work fine.

Load the following script into the arduino and test that the servo rotates when the motion sensor trips. Use the serial monitor to monitor what’s happening.

/*PIR Cat sprayer Peter Quinn 2018
  detect cat
  yes, there is a cat
     wait 10 sec. Is it still there?
        Yes, squirt it
        No, do nothing
  wait 15 sec
  end of loop
  squirt it
  fire squirter twice
*/
#include <Servo.h>
Servo myservo;
int calibrationTime = 30;
//the time when the sensor outputs a low impulse
long unsigned int lowIn;
//the amount of milliseconds the sensor has to be low
//before we assume all motion has stopped
long unsigned int pause = 500;
boolean takeLowTime;
int pirPin = 6;    //the digital pin connected to the PIR sensor's output
int ledPin = 13;

void setup() {
 Serial.begin(9600);
 pinMode(pirPin, INPUT);
 pinMode(ledPin, OUTPUT);
 digitalWrite(pirPin, LOW);
 myservo.attach(9);  // attaches the servo on pin 9 to the servo object
 delay(1000);
 myservo.write(0);
 //give the sensor some time to calibrate
 Serial.print("calibrating sensor ");
 for (int i = 0; i < calibrationTime; i++) {
   digitalWrite(ledPin,HIGH);
   Serial.print(".");
   digitalWrite(ledPin,LOW);
   delay(1000);
 }
 Serial.println(" done");
 Serial.println("SENSOR ACTIVE");
 delay(50);
}

void loop() {
 delay(10);
 Serial.println("main loop");
 if (digitalRead(pirPin) == HIGH) {
   Serial.println("---");
   Serial.print("motion detected at ");
   Serial.print(millis() / 1000);
   Serial.println(" sec");
   digitalWrite(ledPin,HIGH);
   digitalWrite(pirPin, LOW);
   delay(10000);//wait 10 sec to see if it's still there
   if (digitalRead(pirPin) == HIGH) {//still high. time to squirt
     Serial.println("still there");
     squirt_it();
   }
   digitalWrite(ledPin,LOW);
 }
}

void squirt_it() {
 Serial.println("squirt");
 for (int i = 0; i <= 1; i++)...
Read more »