PIR Motion Detector and Blink without Delay

Hi Guys,

I'm using a PIR Motion sensor in a model i've made. On motion detection the 2 LED eyes flicker for a few seconds, remain on for a few seconds then a gradual fade out, I've also installed an override switch, which bypasses the PIR code and keeps the LED eyes permanently on.

if (digitalRead (switchPin) == LOW )
  {
    Serial.println ("Switch Closed.");
    if (digitalRead(pirPin) == HIGH )
    {

 Code for blinking and fading eyes goes here
 
   }
    }
 
else {
    Serial.println ("Switch Open.");
    ledState = HIGH;
    digitalWrite(ledPin, ledState);
  }

If the first and third line of the above code are TRUE (ie the switch is in the off position and motion detected) then it will go through the sequence of blinking the eyes and then fading them. If the first line is not TRUE then it means the switch is on and it will jump to the ELSE statement which means it wont check for motion and the LED's will be permanently on.

Or it should do!

Unfortunately whats happening is, the PIR detects motion, sends a HIGH signal to the pin (I think the signal length is about 3 seconds) and the LED's start to blink and just start the fade process, but don't complete the fade process because the PIR has now sent a LOW signal to the pin, which means the third line down of the above code is now FALSE, which means that the code now jumps to the ELSE statement.

The problem is caused because I'm using the well documented blink (and fade) without Delay() code, so the code doesn't pause at a Delay() command and then continue in a linear fashion, but continues cycling through the loop until currentMillis - previousMillis has reached a specified value, this means that the IF statement at line 3 is constantly being checked if TRUE.

Any ideas on how to fix this would be greatly appreciated.

Im not home at the moment, but think I may of come up with a solution -

if (digitalRead (switchPin) == LOW )
  {
    Serial.println ("Switch Closed.");
    if (digitalRead(pirPin) == HIGH )
    {
      PIRoverride = 1;
     }
    if (PIRoverride == 1)
    {

 Code for blinking and fading eyes goes here
 PIRoverride = 0;
   }
    }
 
else {
    Serial.println ("Switch Open.");
    ledState = HIGH;
    digitalWrite(ledPin, ledState);
  }

Just have to wait now till I get home to try it out.

OK that solved it :slight_smile:

Just posting this for reference in case anybody else finds themselves with a similar problem.

After thinking about it, the problem is almost identical to wanting a series of events to occur after pressing a push button, the button is only momentarily pressed, therefore you should not check on its current state each iteration of your loop, but assign its previous value to a flag variable ie

Pseudo code -

Void loop {

If button is pressed
{ Flag = True }

If Flag == True
{ flash LED's in a certain pattern

If LED sequence is complete
{Flag = False}}
}

It may seems very simple to most of you, but it had me scratching my head for a few hours yesterday.