I'm working on a sketch that uses a PIR sensor to detect motion. Once motion is detected I'm using PWM (fade) to brighten an LED and set a timer. Once the timer completes the LED fades to darkness.
Currently if motion is detected during the fade part of the sketch it needs to complete that section before brightening the light again. I'd like to be able to sense movement during the fade and if movement is detected the LED would brighten again. I think what I need to do this is an interrupt but I've never used interrupts before.
Do I need an interrupt to do this? If so what would my code look like?
// example for the PIR motion sensor SE-10
int long delay_time = 1000; // 1
int long delay_time_2 = 30000; // 2
int long delay_time_3 = 30000; // 3
int long delay_time_4 = 180000; // 4 + 5
int alarmPin_1 = 12;
int ledPin_1 = 9;
int long time_on_1 = 0;
int alarmPin_2 = 12;
int ledPin_2 = 3;
int long time_on_2 = 0;
int alarmPin_3 = 10;
int ledPin_3 = 5;
int long time_on_3 = 0;
int alarmPin_4 = 7;
int ledPin_4 = 6;
int long time_on_4= 0;
int alarmPin_5 = 2;
int ledPin_5 = 11;
int long time_on_5= 0;
void setup () {
Serial.begin (9600);
pinMode(ledPin_1, OUTPUT);
pinMode(alarmPin_1, INPUT);
pinMode(ledPin_2, OUTPUT);
pinMode(alarmPin_2, INPUT);
pinMode(ledPin_3, OUTPUT);
pinMode(alarmPin_3, INPUT);
pinMode(ledPin_4, OUTPUT);
pinMode(alarmPin_4, INPUT);
pinMode(ledPin_5, OUTPUT);
pinMode(alarmPin_5, INPUT);
analogWrite(ledPin_1, 0);
digitalWrite(ledPin_2, LOW);
digitalWrite(ledPin_3, LOW);
digitalWrite(ledPin_4, LOW);
digitalWrite(ledPin_5, LOW);
delay (2000); // it takes the sensor 2 seconds to scan the area around it before it can detect infrared presence.
}
void loop (){
time_on_1 = lightsOn(alarmPin_1, ledPin_1, time_on_1, delay_time);
time_on_2 = lightsOn(alarmPin_2, ledPin_2, time_on_2, delay_time_2);
time_on_3 = lightsOn(alarmPin_3, ledPin_3, time_on_3, delay_time_3);
time_on_4 = lightsOn(alarmPin_4, ledPin_4, time_on_4, delay_time_3);
time_on_5 = lightsOn(alarmPin_5, ledPin_5, time_on_5, delay_time_3);
delay (10);
}
/*
* Return the time that the lights went on. Zero if they are off
*/
int long lightsOn(int alarmPin, int ledPin, int long lights_on, int long delay_m) {
int alarmValue = digitalRead(alarmPin);
if (lights_on == 0) { // lights off
if (alarmValue == LOW){
// motion detected
Serial.println(">>> Turning lights on");
// analogWrite(ledPin, 255); // turn them on
for(int fadeValue = 0; fadeValue <= 255; fadeValue +=1) {
// sets the value (range from 0 to 255):
Serial.println(fadeValue);
analogWrite(ledPin, fadeValue);
delay(1);}
return millis();
}
}
else { // lights on
if (alarmValue == LOW) {
// lights are on AND there's motion
// keep timer start to now
return millis();
}
else {
int long time_now = millis();
// Serial.println("Millis since motion: "+(time_now-time_on));
if ((time_now - lights_on) > delay_m) {
Serial.println(">>> Turning lights off");
// turn them off
// analogWrite(ledPin, 0);
for(int fadeValue = 255; fadeValue >= 0; fadeValue -=1) {
// sets the value (range from 0 to 255):
Serial.println(fadeValue);
analogWrite(ledPin, fadeValue);
delay(10);
}
}
else {
// use the previous time_on
return lights_on;
}
}
}
return 0L;
}
Thanks!
Rich