derieux:
I also tried plugging it into my Arduino and it is not working.
OK,
I tested the code and re-worked it a little...
Copy the code to your Arduino without making any changes (Make sure that buzzPin and lightPin are correct though) and just run it.
Here is what it will do:
When the IR beam is triggered, it will wait 20 seconds, then make noise and lights... what I wasn't clear on from your original post was whether or not you wanted the detection status to change based on whether or not someone was continuously standing in the beam or if you just wanted it to start a 20-second timer the moment the beam is interrupted then make noise after 20 seconds.
If you only wanted to make noise and light if the person is standing in the beam for 20 consecutive seconds, then change the first line in the loop to checkForPersonContinuously(). What that method does, is it changes the personDetected variable based solely on whether or not the beam is interrupted in that moment, but it only sets the mark time ONCE - and only when the beam was first interrupted, which happens when the personDetected variable goes from false to true. Remember that all the methods are constantly being run because of loop, so here is why that matters:
We have to set an initial mark time of when someone was detected. If the method that detects someone looked like this:
personDetected = analogRead(IR) < threshold;
alertTriggeredTime = millis();
Then the alert trigger time mark would be changing constantly (potentially a thousand times per second), whether or not the beam was interrupted, so we have to build in a safeguard to make sure that the time mark is set when someone is detected, but then is not changed again until the status of that variable goes back to false, then true again... you should be able to make sense of that method if you mentally step through it.
But remember, with that method ... if someone is standing in the beam for even 19.999 seconds, then moves out of it, nothing is going to happen in terms of sound and light. But that may be what you intended ... I wasn't sure.
Anyways, assuming that we've detected someone and 20 seconds later the alarm and light go off ...
10 seconds after the alarm starts, the light will turn off.
The buzzer will "bounce" a few times (beep, beep, beep, etc.) I left an alternate method in there to have the buzzer just turn on for however many seconds you designate ... not sure how you wanted it to sound, but obviously there are an infinite number of ways to play the buzzer, and depending on your buzzing speaker, you could even variate the pitch and play a show tune ... lol ...
OK, here's the code, then I have a few more comments
#include <Arduino.h>
#define IR A0
const int buzzPin = 6;
const int lightPin = 5;
const int threshold = 500;
//Used for bounceBuzzer()
const int buzzOnTime = 150;
const int buzzOffTime = 100;
//Number of seconds for continuous buzz
const int buzzSeconds = 5;
//This is the number of seconds to wait once someone is detected before alarming
const int secondsSinceDetection = 20;
//number of seconds to leave light on
const int lightOnTime = 10;
unsigned long alertTriggeredTime;
unsigned long lightTriggerTime;
bool personDetected = false;
bool lightIsOn = false;
//"Back End" methods
void buzzOn() {digitalWrite(buzzPin, HIGH);}
void buzzOff () {digitalWrite(buzzPin, LOW);}
void lightOn() {digitalWrite(lightPin, HIGH);lightIsOn = true;lightTriggerTime = millis();}
void lightOff() {digitalWrite(lightPin, LOW);lightIsOn = false;}
void allClear() {personDetected = false;}
bool lightHasBeenOnFor(int seconds) {return ((millis() - lightTriggerTime) / 1000) > seconds;}
//Loop Methods
void turnLightOffIn(int seconds) {
if (lightHasBeenOnFor(seconds)) lightOff();
}
void buzzFor (int seconds) {
long milliSeconds = seconds * 1000;
lightOn();
buzzOn();
delay(milliSeconds);
buzzOff();
allClear();
}
void bounceBuzzer(int repeatInterval) {
lightOn();
for (int x=0; x<repeatInterval; x++) {
buzzOn();delay(buzzOnTime);
buzzOff();delay(buzzOffTime);
}
allClear();
}
bool secondsPassedSinceDetection(int seconds) {
unsigned long millisPassed = millis() - alertTriggeredTime;
unsigned long secondsPassed = millisPassed / 1000;
return secondsPassed > seconds;
}
void checkForPersonContinuously() {
static bool lastDetection = false;
personDetected = analogRead(IR) < threshold;
if (personDetected != lastDetection) {
if (personDetected) alertTriggeredTime = millis();
lastDetection = personDetected;
}
}
void checkForPersonOneTime(){
if (!personDetected) {
if (analogRead(IR) < threshold) {
personDetected = true;
alertTriggeredTime = millis();
}
}
}
void setup() {
Serial.begin(9600);
pinMode(IR, INPUT);
pinMode(lightPin, OUTPUT);
pinMode(buzzPin, OUTPUT);
}
void loop()
{
checkForPersonOneTime();
if (personDetected && secondsPassedSinceDetection(secondsSinceDetection)) {
bounceBuzzer(6);
//Optional you could use BuzzFor(buzzSeconds) to do one continuous sound.
//buzzFor(buzzSeconds);
}
if (lightIsOn){
turnLightOffIn(lightOnTime);
}
}
Notice I used the delay() function with the buzzer methods... I did this because it's simpler and in this application we don't need to do anything else while the buzzer is buzzing ... if we do, then we need to make changes obviously. I assumed simplicity so I went ahead and used it, which in this application is perfectly acceptable ... normally when you're sounding an alarm in a simple application like this, you don't need to multitask, you just want noise.
Also notice at the top I added some constant integers that let you easily change some of the parameters of the events.... like how long the buzzer will stay on then off in the bounceBuzzer method, or how long the light needs to stay on after it's turned on etc.
Let me know how it goes.
Mike