PIR Sensor and timer

This is the code I am using currently...... I've decided to 'try' to extend it a bit because what I'd like it to is stay on as long as someone is present..... Right now it detects motion turns on but fadeout after a set time.....

void fadeInRight() {
  for (int stair = 0; stair < NUM_LEDS; stair += LEDS_PER_STAIR) {
    for (int b = 0; b < 175; b += 100) {
      for (int led = stair ; led < stair + LEDS_PER_STAIR; led++) {
        leds[led] = CHSV(0,0,b);
      }
      FastLED.show();
      delay(fadeTimeDiff);
    }
  }
}

I tried to add to that with an if statement basically as long as the PIR is reading HIGH to stay on.... if not then fadeout...... well so far I've not been able to get it working...
Not asking for anyone to do it for me but I would really appreciate a bit of help :slight_smile:
Thank you!

For that you have to post the code you wrote.

This is where I tried to add ..

I changed this:

void loop() {
  if (digitalRead(MOTION_LEFT) == HIGH) {
    fadeInLeft();
    delay(onTime);
    fadeOut();
  } else {
    if (digitalRead(MOTION_RIGHT) == HIGH) {
    fadeInRight();
    delay(onTime);
    fadeOut();
  }
   }
}

To this:

void loop() {
  if (digitalRead(MOTION_LEFT) == HIGH) {
    fadeInLeft();
    delay(onTime);
    fadeOut();
  } else {
    if (digitalRead(MOTION_RIGHT) == HIGH) {
    fadeInRight();
    while (digitalRead(MOTION_RIGHT) == HIGH){
    delay(onTime); }
    else {
    fadeOut();
    }
  }
   }
}

You didn't mention what the outcome of that sketch was... but I think it might be like:

void loop() {
  if (digitalRead(MOTION_LEFT) == HIGH) {
    fadeInLeft();
    delay(onTime);
    fadeOut();
  } else {
    if (digitalRead(MOTION_RIGHT) == HIGH) {
    fadeInRight();
    while (digitalRead(MOTION_RIGHT) == HIGH){
    delay(onTime);
    }
    fadeOut();
  }
 }
}

Here is the entire sketch :slight_smile:

#include "FastLED.h"
#define LED_DATA_PIN 9
#define NUM_LEDS 200
#define LEDS_PER_STAIR 10           // Number of Leds per stair.
CRGB leds[NUM_LEDS];
int onTime = 15*1000;               // 15 seconds
int MOTION_LEFT = 10;
int MOTION_RIGHT = 11;
int fadeTimeDiff = 15;
uint8_t hue = 0;


void setup() {
  FastLED.addLeds<WS2812, LED_DATA_PIN, BRG>(leds, NUM_LEDS);
  pinMode(MOTION_LEFT, INPUT);
  pinMode(MOTION_RIGHT, INPUT);
  startupLEDsTest();
}

void loop() {
  if (digitalRead(MOTION_LEFT) == HIGH) {
    fadeInLeft();
    delay(onTime);
    fadeOut();
  } else {
    if (digitalRead(MOTION_RIGHT) == HIGH) {
    fadeInRight();
    delay(onTime);
    fadeOut();
  }
   }
}
void fadeInRight() {
  for (int stair = 0; stair < NUM_LEDS; stair += LEDS_PER_STAIR) {
    for (int b = 0; b < 175; b += 100) {
      for (int led = stair ; led < stair + LEDS_PER_STAIR; led++) {
        leds[led] = CHSV(0,0,b);
      }
      FastLED.show();
      delay(fadeTimeDiff);
    }
  }
}

What it does is lights up a light bar basically in my hallway :slight_smile:

Try my proposed code

No that's the problem I've been having...... it comes on... stays on for the timer amount and goes back off.... I was thinking I'd need some type of timer..... just not sure how to write that. I was thinking a 30 second timer that resets back to 30 if movement is still detected then when motion is not detected then fadeout();

Your timer is:

    delay(onTime);

if it's not long enough then:

void loop() {
  if (digitalRead(MOTION_LEFT) == HIGH) {
    fadeInLeft();
    delay(onTime);
    fadeOut();
  } else {
    if (digitalRead(MOTION_RIGHT) == HIGH) {
    fadeInRight();
    while (digitalRead(MOTION_RIGHT) == HIGH){
    delay(aVeryLongTime);
    }
    fadeOut();
  }
 }
}

but any kind of timer that involves any response or action while it is running, requires the use of millis() multitasking, not delay().

For that, you will have to learn to use millis(), and completely restructure your code.

1 Like

This is the other thing I've been playing with which does use millis()

bool personPresent=false;
bool lightsOn=false;
ulong timeLimit=0;  // wall time when lights should turn off after being on
ulong fadeTime=/* (15 seconds in ms)*/   15 * 1000;
loop(){
    // get current clock time in ms
    ulong now = millis()
    // if there is a sensor detecting
    if (digitalRead(MOTION_SENSOR_LEFT) == HIGH || digitalRead(MOTION_SENSOR_RIGHT) == HIGH){
       personPresent=true
    } else {
        personPresent = false;
    }
 
    // if someone is around
    if (personPresent) {
        // if lights not on,
        if(lightsOn==false){
            // turn on
            fadeIn()
            // record the fact // I would put this in fadeIn
            lightsOn=true
            // set the timeout time
            timeLimit=now+onTime;
        }  else{
            // lights are on
            // reset next timeout time as person is still present
            timeLimit=now+onTime
        }
    } else { 
        // no person present
        if(lightsOn){
            // if the timer has expired
            if(timeLimit<now){
                // turn the lights off
                fadeOut()   
                // record the fact // I would put this in fadeOut
                lightsOn=false  
            }
        }
    }

But this turns on the lights but never back off.... couldn't figure out why...

We can't figure out either, unless you post the entire sketch. Reason - you make calls to functions we can't see. Also we need to see all the variable declarations.

This is how I have it laid out..... trying to make changes.....

#include "FastLED.h"
#define NUM_LEDS 200
#define LED_DATA_PIN 9
#define MOTION_SENSOR_LEFT 10           //added        
#define MOTION_SENSOR_RIGHT 11          //added
//#define MOTION_SENSOR_MIDDLE 12       //added 
CRGB leds[NUM_LEDS];

int onTime = 15*1000; // 15 seconds -- changed from 30, 5 seconds for just testing
int fadeTimeDiff = 50;

bool personPresent=false;
bool lightsOn=false;
ulong timeLimit=0;  // wall time when lights should turn off after being on
ulong fadeTime=/* (15 seconds in ms)*/   15 * 1000;

void setup() {
  FastLED.addLeds<WS2812B, LED_DATA_PIN, BRG>(leds, NUM_LEDS);  //changed led type from WS2811 to WS2812B
  pinMode(MOTION_SENSOR_LEFT, INPUT);  
  pinMode(MOTION_SENSOR_RIGHT, INPUT); 
  pinMode(LED_DATA_PIN, OUTPUT);            //added
  digitalWrite(MOTION_SENSOR_LEFT, LOW);    //added
  digitalWrite(MOTION_SENSOR_RIGHT, LOW);   //added
}
void loop(){
    // get current clock time in ms
    ulong now = millis();
    // if there is a sensor detecting
    if ( digitalRead(MOTION_SENSOR_LEFT) == HIGH 
            || 
         digitalRead(MOTION_SENSOR_RIGHT) == HIGH)
         {
       personPresent=true;
    } else {
        personPresent = false;
    }

    // if someone is around
    if (personPresent==true) {
        // if lights not on,
        if(lightsOn==false){
            // turn on
            fadeIn();
            // record the fact // I would put this in fadeIn
            lightsOn=true;
            // set the timeout time
            timeLimit=now+fadeTime;
        }  else{
            // lights are on
            // reset next timeout time as person is still present
            timeLimit=now+fadeTime;
        }
    } else { 
        // no person present
        if(lightsOn){
            // if the timer has expired
            if(timeLimit<now){
                // turn the lights off
                fadeOut();   
                // record the fact // I would put this in fadeOut
                lightsOn=false  ;
            }
        }
    }
}


void fadeIn() {
  for (int led = 0; led < NUM_LEDS; led++) {
    leds[led] = CRGB( 134,235,255);    // RGB Color
  }
  for (int b = 0; b < 125; b += 2) {  // b = brightness level, it's set at 75 because in the middle of the night I don't want to be blinded
    FastLED.setBrightness(b);
    FastLED.show();
    delay(fadeTimeDiff);
  }
}

void fadeOut() {
  for (int led = 0; led < NUM_LEDS; led++) {
    leds[led] = CRGB( 134,235,255);     // RGB Color
  }
  for (int b = 125; b > 0; b -= 2) {   // b = brightness level, it's set at 75 because in the middle of the night I don't want to be blinded
    FastLED.setBrightness(b);
    FastLED.show();
    delay(fadeTimeDiff);
  }
  for (int led = 0; led < NUM_LEDS; led++) {
    leds[led] = CRGB::Black;
  }
  FastLED.show();
}

One casual observation. If I'm not mistaken, I see the use of delay() along with millis(). That has frequently been seen to cause problems. Your fade routines seem to take a long time to complete. Such a delay won't work with multitasking.

1 Like

I will go back and kind of 'chart' this thing to see the 'flow'....... should be able to figure out what it's doing then..... should have thought of that before I made this post LOL.

Thank you for your input!!!

I started over.... it's just easier...... but the I cannot get a reading from the most basic sketch....
any suggetions?


#include "FastLED.h"
#define NUM_LEDS 200
#define LED_DATA_PIN 9
#define MOTION_SENSOR_LEFT 10           //added        
#define MOTION_SENSOR_RIGHT 11          //added
//#define MOTION_SENSOR_MIDDLE 12       //added 
CRGB leds[NUM_LEDS];


void setup() {
  FastLED.addLeds<WS2812B, LED_DATA_PIN, BRG>(leds, NUM_LEDS);  //changed led type from WS2811 to WS2812B
  pinMode(MOTION_SENSOR_LEFT, INPUT);  
  pinMode(MOTION_SENSOR_RIGHT, INPUT); 
  pinMode(LED_DATA_PIN, OUTPUT);            //added
  digitalWrite(MOTION_SENSOR_LEFT, LOW);    //added
  digitalWrite(MOTION_SENSOR_RIGHT, LOW);   //added 
}


void loop(){
    // if there is a sensor detecting
    if ( digitalRead(MOTION_SENSOR_LEFT) == HIGH || digitalRead(MOTION_SENSOR_RIGHT) == HIGH){
     Serial.print("We are reading motion");
  } else if ( digitalRead(MOTION_SENSOR_LEFT) == LOW || digitalRead(MOTION_SENSOR_RIGHT) == LOW) {
    Serial.print("NO motion");
    }
}

That should at least be returning something... it's returning nothing from the serial monitor

EDIT: Got it......you have to use Serial.begin(9600); before there's anything to read ..duh LOL

So everything works now?

1 Like

Yes all works great!!! :slight_smile: Thank you!! It's all on github now

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