Squirt – Arduino, Motion Activated Water Cannon

Squirt is a motion activated water cannon using Arduino.


This was designed for use in the garden but as it’s winter we tested it in the bathroom. It works!

Motion Activated Water Cannon

[mom_video id=’zyzPr9R7RzI’]

True motion tracking is expensive and complicated so this system activates when the victim moves into range and randomises the position of the cannon and the firing time within a limited area. The sometimes fickle readings from the PIR sensor just adds to the cannon’s randomness, and therefore the fun.

This is my first Arduino project.

Step 1: Parts

Parts
 
 
 
Arduino
Windscreen washer pump
PIR motion detector
servo motor
TIP 120 npn transistor
10k resistor
1N4004 diode
12v rechargeable NiMH battery
on/off switch
watertight box to house the workings
Watertight reservoir
Various length 22 awg jumper leads
Soft tubing
Short length of pipe
Breadboard

Step 2: The Circuit

The Circuit
 
 
Connect the parts according to the circuit diagram below.
The PIR command wire goes to Digital pin 5 on the arduino and its positive wire goes to 3v pin and ground to ground.
Servo control wire is on pin10.
Pump is on pin 8 via the transistor 9which is protected by the diode).
The battery is a NiMH 12v connected to Vin pin via an on/off switch.

 

The battery, breadboard and arduino are housed inside a watertight sandwich box.
Mounted on top is the PIR which is inside a length of plastic tube to restrict its field of vision to directly ahead.

The servo is mounted on top of the water reservoir- in this case a plastic tub from the kitchen supplies department of the local supermarket. The pump is fitted near the bottom of the tub with its outlet connected to a flexible pipe from an aquarium supply shop and (rather messily) attached to the sevo arm with a lump of blu-tac.

Step 3: The Code

The Code
 
The arduino code (or “sketch”) runs when turned on. Essentially the PIR looks for motion. If it’s detected it waits a random length of time between half and 3 seconds, moves the servo arm to a random position 30 degrees either side of center, fires the pump for a half second and returns the servo to center. It then waits for another random length of time and repeats. It fires 3 times then checks the PIR again to see if it detects further motion. See sketch below:

 

#include <ServoTimer1.h>

/*

  • “Squirt”. Jonathan Robson Feb 2009.

*

*/

int transistorPin = 8; // transistor base connected to pin 8
ServoTimer1 servo1; // defines the servo

long randOff = 0; // Initialise a variable for the OFF time between shots
long randNumber; // Initialise a variable for servo position angle and delay between shots

void setup()
{
servo1.attach(10); //servo on pin 10
pinMode(8, OUTPUT); // set the transistor pin 8 as output to pump
pinMode(5, INPUT); // set the PIR pin 5 as input
digitalWrite(8, LOW); // defines LOW as movement
randomSeed (analogRead (0)); // randomize

}

int pinin = 0;
long countint = 0;

void loop()
{
pinin = digitalRead(5); // reads the PIR sensor
while (pinin == 0)
{
pinin = digitalRead(5);
}
servo1.write(90); //sets servo to center
randOff = random (500, 3000); // generate OFF time between 1/2 and 3 seconds
delay(randOff); // waits for a random time while OFF
servo1.write(randNumber = random(60, 120)); // servo to random position within 30 degrees of center
delay(400); //gives servo time to get there
digitalWrite(transistorPin, HIGH); // turns pump on
delay(500); //fires pump for 1/2 second
digitalWrite(transistorPin, LOW); // turns pump off
servo1.write(90); // moves servo back to center

randOff = random (500, 3000); // generate new OFF time between 1/2 and 3 seconds and repeat
delay(randOff);
servo1.write(randNumber = random(60, 120));
delay(400);
digitalWrite(transistorPin, HIGH);
delay(500);
digitalWrite(transistorPin, LOW);
servo1.write(90);

randOff = random (500, 3000); // generate OFF time between 1/2 and 3 seconds and repeat
delay(randOff);
servo1.write(randNumber = random(60, 120));
delay(400);
digitalWrite(transistorPin, HIGH);
delay(500);
digitalWrite(transistorPin, LOW);
servo1.write(90);

delay(3000); // gives the PIR time to “settle” before reading again

}

 

Leave a Comment

Your email address will not be published.

Scroll to Top