PIR to Run Blink w/o Delay

Hello Arduino Forum,

Have breadboarded the Blink w/o Delay
Blink Without Delay | Arduino Documentation
Now working on the Blink w/o Delay to to be activated by a motion sensor, The
aim is to have several different lights come on and stay on for a certain time based on when the different PIRs were triggered.

Code copied herewith below.

Trying to figure out whether to have the time comparator activate the PIR input read or conversely. Have tried a dozen or so different versions.
Any ideas would be most appreciated.
Thanks.
Allen Pitts

`/*
Blink without Delay
*/

// constants won't change. Used here to set a pin number:
const int ledPin = 12; // the number of the LED pin
const int inputPin = 11; // the number of the PIR input

// Variables will change:
int ledState = LOW; // ledState used to set the LED
int pirStateA1 =LOW;
int val1 = 0;

// Generally, you should use "unsigned long" for variables that hold time
// The value will quickly become too large for an int to store
unsigned long previousMillis = 0; // will store last time LED was updated

// constants won't change:
const long interval = 3000; // interval at which to blink (milliseconds)

void setup() {
// set the digital pin as output:
pinMode(ledPin, OUTPUT);
pinMode(inputPin, INPUT);
}

void loop() {
  // here is where you'd put code that needs to be running all the time.

  // check to see if it's time to blink the LED; that is, if the difference
  // between the current time and last time you blinked the LED is bigger than
  // the interval at which you want to blink the LED.
  unsigned long currentMillis = millis();

  if (currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;
val1 = digitalRead(inputPin); {
if (val1 == HIGH) {
    // if the LED is off turn it on and vice-versa:
    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;
    }
}
}
    // set the LED with the ledState of the variable:
    digitalWrite(ledPin, ledState);
  }
}

Please take a moment to review this: How to get the best out of this forum - Using Arduino / Installation & Troubleshooting - Arduino Forum

Then go back and edit your post so all of your code is within code tags. You should also get into the habit of formatting your code (Ctrl-T in the IDE)

The code you posted does not show anything at all dealing with a motion sensor. It is just the blink w/o delay sketch. What have you tried using the PIR sensor? It would be better to post that code.

Basically, when a PIR sensor is triggered, you want to record the time and set a flag saying the PIR is "activated"

You can then use this "activated" flag to determine if you should be blinking an LED or measuring how much time has elapsed since the PIR was triggered to determine if you need to stop or continue.

1 Like

Reading the PIR inside the millis timer, only fires every 3 seconds..
move things around a bit..

unsigned long currentMillis = millis();
val1 = digitalRead(inputPin); 

  if (currentMillis - previousMillis >= interval) {
    // save the last time you blinked the LED
    previousMillis = currentMillis;
    // if the LED is off turn it on and vice-versa:
    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;
    }
    // set the LED with the ledState of the variable:
if (val1 == HIGH) {
    digitalWrite(ledPin, ledState);
} else digitalWrite(ledPin, LOW);//turn off
  }

this should blink while motion is detected, untested sorry..
might want to blink faster than every 3 seconds..
or like previous advice extend the motion detection for a period..

good luck.. ~q

const int ledPin = 12; // the number of the LED pin
const int inputPin = 11; // the number of the PIR input
const int intervalPIR = 5000; // interval to blink further after PIR no more active
const int intervalMillis = 1000; // interval between change light
unsigned long previousPIR_Millis = 0; // will store last time PIR was active HIGH
unsigned long previousBlinkMillis = 0; // will store last time LED was updated
bool BlinkTime = false;

void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(inputPin, INPUT_PULLUP);
}
void loop() {
  if (digitalRead(inputPin)) {
    BlinkTime = true;
    previousPIR_Millis = millis();
  }

  if (BlinkTime) {
    if (millis() - previousBlinkMillis >= intervalMillis) {
      previousMillis += interval;
      digitalWrite(ledPin, !digitalRead(ledPin));
    }
    if (!digitalRead(inputPin) && millis() - previousPIR_Millis >= intervalPIR){
      BlinkTime = false;
      digitalWrite(ledPin,LOW);
    }
  }
}

Hello @blh64 , @qubits-us , @kolaha and the Arduino forum,

blh64 has a good point. The motion detector trigger was not in the code I posted because I was trying to bypass the PIR (passive infrared sensor) so as to simplify the code and just tell the code to turn the LED on and off.
The code called 'sketch to turn on light w PIR and Arduino 230617'
is copied herewith below and includes the PIR trigger.

Also attached is a schematic that was breadboarded, tested and operates as designed.
PIR to Arduino to LED 230617

The 'sketch to turn on light w PIR and Arduino 230617' relies on the motion detector (HC-SR501) to determine how long the LED will stay on.
The PIR has two pots on it. One to adjust the proximity sensitivity and
the other to adjust how long the PIR sends out it 3.3 v signal ( millisecods to about five minutes).
The context is a series of lights that would react as a walker descends
or ascends a staircase
Staircase system
The design was to use the timer pots on the PIRs to turn on a light
for about twenty seconds. But the PIR timer pots are pretty crude and
the variance from PIR to PIR is a large range so it is difficult to get
the lights to stay on for uniform amount of time.

The code posted by qubits-us was very helpful but in the end the code posted kolaha was installed. kolaha's excellent sketch is posted after
'sketch to turn on light w PIR and Arduino 230617' and is called
'Sketch to turn on light w/o delay using PIR and Arduino 230618'.

The ....'w/o delay'.... code, kolaha's code, from post #4, had a couple of 'not defined in this scope' variable name typos and I think I figured out what was meant. But if I may, kolaha (or anybody else who is willing to dive into it.) please accept a request to look at
'Sketch to turn on light w/o delay using PIR and Arduino 230618' ,
posted below, to see if I made the right adjustments.
I think I did make the right adjustments because the breadboard is operating pretty much as designed. The only deviation is,
I think, the time that the LED should stay on is determined by
const int intervalPIR = 5000;
That is the LED should stay on for five seconds. But the time that the
LED stays on has been timed w a stopwatch a half dozen times and the
LED stays on for closer to eight seconds which maybe the sum
of the intervalPIR and the time that the PIR sends the signal.
Working on eliminating the timer at the PIR and only using the
time set in the sketch to determine how long the light stays on.
I think just using the sketch to time how long the LED stays on will provide a much more precise operation.
Finally, the '...w/o delay...' sketch operates one light by one PIR. The next step is to expand the number of lights to six total and create two use cases, one for ascending and one for descending where the use case fired off would be determined by whether the walker approaches from above or below.
Thanks.
Allen Pitts

/**************************************************************
sketch to turn on light w PIR and Arduino 230617
*******************************************************/


// ++++  LED pin numbers ledPinX Output 2-10 ++++
int led1 = 12;
int inputPinA1 = 11;

// ++++ PIR State pirStateXX = LOW ++++
int pirStateA1= LOW;                // 220504 acp

// ++++ Input status variable valXX A5 - 12, 13
int valA1= 0;                    // 220504 acp


 // the setup function runs once when you press reset or power the board
void setup() {

// +++++ declare ledPinXX numbers as OUTPUT ++++ 
  pinMode(led1, OUTPUT);       // declare LED1 as output
 
// ++++ declare inputPinXX numbers as INPUT   ++++
    pinMode(inputPinA1, INPUT);     // declare sensor1 as input   220504 acp
}

 // the loop function runs continuously 
void loop(){
  
          //Connect PIR inputPinA1 (pin 11)  to '+LED1-' (Pin12)
      valA1 = digitalRead(inputPinA1);  // read input value
      if (valA1 == HIGH) {            // check if the input is HIGH
        digitalWrite(led1, HIGH);  // turn LED ON
      } else {
        digitalWrite(led1, LOW); // turn LED OFF
        if (pirStateA1 == HIGH){
         pirStateA1 = LOW;
        }
    }
    
}
/**************************************************************end of sketch to to turn on light w PIR and Arduino 230617
*******************************************************/

/********************************************************
Sketch to turn on light w/o delay using PIR and Arduino 230618
*************************************************************/
const int ledPin = 12; // the number of the LED pin
const int inputPin = 11; // the number of the PIR input
const int intervalPIR = 5000; // interval to blink further after PIR no more active
const int intervalMillis = 1000; // interval between change light
unsigned long previousPIR_Millis = 0; // will store last time PIR was active HIGH
unsigned long previousBlinkMillis = 0; // will store last time LED was updated
bool BlinkTime = false;

void setup() {
pinMode(ledPin, OUTPUT);
pinMode(inputPin, INPUT_PULLUP);
}
void loop() {
if (digitalRead(inputPin)) {
BlinkTime = true;
previousPIR_Millis = millis();
}

if (BlinkTime) {
if (millis() - previousBlinkMillis >= intervalMillis) {
previousPIR_Millis += intervalPIR;
digitalWrite(ledPin, !digitalRead(ledPin));
}
if (!digitalRead(inputPin) && millis() - previousPIR_Millis >= intervalPIR){
BlinkTime = false;
digitalWrite(ledPin,LOW);
}
}
}
/********************************************************
end of Sketch to turn on light w/o delay using PIR and Arduino 230618
*************************************************************/

the method to make your light switch on/off only with the time defined in your code is to do state-change-detection.

This means you have two variables
lastState and actualState your code does continiously comparing

if (lastState != actualState) {
  //switch_on-light
lastState = actualState; // update lastState
}

Now you are detecting not the state = PIR sends signal you are detecting state-change.

So give it a try on your own and post your attempt with new questions

best regards Stefan

1 Like

Please use code tags to make you code more readable.

Blinking seems an odd choice for aiding a walker up and down stairs. It seems like you want a "pulse stretcher" to keep the lights on steadily for 5 sec after the last motion detected, rather than blinking on and off at intervalMillis while a slow walker proceeds.

I'd set the PIR timeout to a low number of milliseconds, and upon detection reset the 5sec timer and turn the light on, and when the timer expires, turn the light off.

This completely untested snippet repurposes BlinkTime as a light state variable:

void loop() {
  if (digitalRead(inputPin)) {
    BlinkTime = true;
    previousPIR_Millis = millis();
    digitalWrite(ledPin,HIGH);
  }
  if (BlinkTime && millis() - previousPIR_Millis >= intervalPIR){
      BlinkTime = false;
      digitalWrite(ledPin,LOW);
  } 
}

This pulse stretcher essentially debounces the PIR to be at least intervalPIR long.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.