Hello!
I've been having some trouble with cats fishing at our pond so I am trying to write a program that will shoot a water stream when it detects motion.
The program i am using right now works fine. I can turn the sound on and off and it has an LED to give a visual confirmation on activation. But at the moment the relay (and solenoid) for the water stream water stays on the for the time the PIR input stays high. I would like to control the time the relay stays high after a high input has been given.
I am looking into the milis() function and maybe using a boolean but i am not sure if this is the right direction.
I really could use some advice on what the best approach would be.
Thanks!
// Uses a PIR sensor to detect movement, buzzes a buzzer
// more info here: http://blog.makezine.com/projects/pir-sensor-arduino-alarm/
//
// based upon:
// PIR sensor tester by Limor Fried of Adafruit
// tone code by michael@thegrebs.com
int relay = 4; // choose the pin for the LED
int inputPin = 9; // choose the input pin (for PIR sensor)
int pirState = LOW; // we start, assuming no motion detected
int val = 0; // variable for reading the pin status
int pinSpeaker = 7; //Set up a speaker on a PWM pin (digital 9, 10, or 11)
int LEDPin = 5;
int Switch = 8;
int switchstate = LOW;
void setup() {
pinMode(relay, OUTPUT); // declare Relay as output
pinMode(inputPin, INPUT); // declare sensor as input
pinMode(pinSpeaker, OUTPUT);
pinMode(LEDPin, OUTPUT);
pinMode(Switch, INPUT);
// Serial.begin(9600);
digitalWrite(LEDPin, LOW);
while (millis() < 30000) { // time for PIR to initialize
tone(pinSpeaker, 4000, 100);
digitalWrite(LEDPin, HIGH);
delay(200);
digitalWrite(LEDPin, LOW);
delay(400);
}
digitalWrite(LEDPin, HIGH);
tone(pinSpeaker, 2500, 400);
delay(200);
tone(pinSpeaker, 3000, 400);
delay(200);
tone(pinSpeaker, 4000, 800);
digitalWrite(LEDPin, LOW);
delay(1000);
tone(pinSpeaker, 4000, 100);
delay(100);
}
void loop(){
switchstate = digitalRead(Switch);
val = digitalRead(inputPin); // read input value
if (val == HIGH) { // check if the input is HIGH
digitalWrite(relay, HIGH); // turn Relay ON
digitalWrite(LEDPin, HIGH);
if (switchstate == HIGH) {
playTone(150, 160);
}
delay(150);
if (pirState == LOW) {
// we have just turned on
// Serial.println("Motion detected!");
// We only want to print on the output change, not state
pirState = HIGH;
}
}
else {
digitalWrite(relay, LOW); // turn LED OFF
digitalWrite(LEDPin, LOW);
playTone(0, 0);
delay(300);
if (pirState == HIGH){
// we have just turned off
// Serial.println("Motion ended!");
// We only want to print on the output change, not state
pirState = LOW;
}
}
}
// duration in mSecs, frequency in hertz
void playTone(long duration, int freq) {
duration *= 1000;
int period = (1.0 / freq) * 1000000;
long elapsed_time = 0;
while (elapsed_time < duration) {
digitalWrite(pinSpeaker,HIGH);
digitalWrite(LEDPin, HIGH);
delayMicroseconds(period / 2);
digitalWrite(pinSpeaker, LOW);
digitalWrite(LEDPin, LOW);
delayMicroseconds(period / 2);
elapsed_time += (period);
}