Y'know, for kids. We call it "Squirt".
This is my first arduino project and I'm amazed it got it to this stage so fast with virtually zero knowledge of electronics or coding just over a month ago. I think that's more down to the arduino than me!
A PIR sensor activates a windscreen washer pump whose nozzle is mounted on a servo. The PIR is in a tube so that it only detects motion in front of it - or when a target is in range. When activated the servo moves to a random position within 30 degrees right or left of center and shoots. It waits a random length of time between half and 3 seconds and moves and shoots again , then repeats and waits to detect further movement. Actual motion tracking is a bit beyond my current abilities so this is a reasonable facsimile that is fun for kids. The sometimes fickle readings of the PIR just add to the randonmess and hence the fun.
Here's the circuit and the code. Any suggested improvements to either are welcomed (sorry the circuit diagram's a bit small!).
#include <ServoTimer1.h>
/*
* "Squirt". Jonathan Robson Feb 2009.
*
* A PIR activates a servo & pump. Servo moves its arm to a random position between 60 and
* 120 degrees, fires a pump for half second and returns to center (90 degrees). Cycle repeats
* 3 times at random intervals between half and 3 seconds then waits to detect further movement.
* Circuit based on http://itp.nyu.edu/physcomp/Tutorials/HighCurrentLoads
* PIR code adapted from http://www.liquidware.org/view.php?id=63
* Random code adapted from www.arduino.cc/en/Tutorial/Blink & www.arduino.cc/en/Reference/Random
* Servo code adapted from http://www.ladyada.net/make/mshield/use.html
*/
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
}