I think I need an interrupt but don't know how.

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

That is because of the use of the for's and the delay's. You only see the motions in this part of your sketch:

  int alarmValue = digitalRead(alarmPin);

One way to do what you want is to implement a state machine.

EDIT: Other way (dirtier) is to read the alarmValue inside each for and break if the motion is sensed.

Do I need an interrupt to do this?

No. Embrace the principle of the BlinkWithoutDelay example sketch.

Save the time when something starts, such as a step of the fade, then check again next time round loop() to see whether the required fade step period has elapsed. If so move to the next fade value and save the start time again. This way you can introduce a delay without using delay() and the loop() function keeps repeating so that you can do other things such as detecting movement and reacting to it.

You have used this method, or at least partially, in your program but have not taken full advantage of it.

UKHeliBob:
No. Embrace the principle of the BlinkWithoutDelay example sketch.

...

You have used this method, or at least partially, in your program but have not taken full advantage of it.

^^yup^^

and make it easy on yourself... get it working with just one motion sensor and led. Then, extend it with the use of arrays.

It's rather like the concept that life came to this planet from somewhere else. It doesn't solve the problem of how life came to be, it just changes the location of the question.

The demo several things at a time is an extended example of the BWoD technique.

...R