Go Down

Topic: LEDs blinking duration and without motion (Read 577 times) previous topic - next topic

Umair_Khalid_Khan

Hi!
I am just toying with the Arduino and a PIR sensor. I made the circuit and got everything up and running, however, there are certain inefficiencies I want to reduce. One is that I want to change the time that the LEDs stay on and that at times there is a delay in registering a motion, for example if the LEDs were already on, after turning off, the system(I don't know which part to blame, code or sensor) takes couple of seconds before it actually registers the next motion to the turn the LEDs on again. is there anyway to solve these problems. I tried using the delay function but it did not help.

P.S: I am a complete newbie to the Arduino and C++ ( can understand the code to some extent due to knowledge in VB) so you will have to dumb it down for me, since google has failed me in finding a solution.
(I have attached the current code)
thanks

slipstick

Try reading "How to use this forum - please read" at the top of every forum. Then post your code correctly as described in #7. That way people reading on their phones/tablets will be able to see it and you have a better chance of getting some answers.

Steve

septillion

delay() will never fix delays ;) Heck, delay()'s area a big source of problems, never use them in your program.

About PIR sensors, a lot of the standard PIR sensors have a minimum time which has to pass before they can retrigger. To see if that's the problem, simply (also) add a led (with resistor) to the output of the PIR and see if that does react immediately.
Use fricking code tags!!!!
I want x => I would like x, I need help => I would like help, Need fast => Go and pay someone to do the job...

NEW Library to make fading leds a piece of cake
https://github.com/septillion-git/FadeLed

Umair_Khalid_Khan

Sorry i have added the code below.


 
Code: [Select]
void setup() {
  // put your setup code here, to run once:
   pinMode(ledPin, OUTPUT);
   pinMode(inputPin, INPUT);
  // Serial.begin(9600);

}


void loop() {
  // put your main code here, to run repeatedly:
  val = digitalRead(inputPin);

  if( val == HIGH)
  {
    digitalWrite(ledPin, HIGH);
   
    if(pirState == LOW)
    {
     // Serial.println("motion detected");
      pirState = HIGH;
    }
  }
  else
  {
    digitalWrite(ledPin, LOW);
     if(pirState == HIGH)
       {
       // Serial.println("motion ended");
       pirState = LOW;
       }
   }
 }
 

Umair_Khalid_Khan

delay() will never fix delays ;) Heck, delay()'s area a big source of problems, never use them in your program.

About PIR sensors, a lot of the standard PIR sensors have a minimum time which has to pass before they can retrigger. To see if that's the problem, simply (also) add a led (with resistor) to the output of the PIR and see if that does react immediately.
How many Ohms should it be? Also what will this determine. I think you are right about the problem with the sensor itself, As it does have a sensitivity(which I have turned to maximum) and timing settings( which I have set to a minimum). That was also my initial thinking, however, I was looking for a workaround through coding.


thanks

#5
Sep 11, 2019, 01:06 pm Last Edit: Sep 11, 2019, 06:04 pm by HKJ-lygte
Turn the timer on the PIR all the way down, as short as possible then try something like this:
Code: [Select]

#define inputPin 3
#define ledPin 13

unsigned long timer;

void setup() {
  //Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
  pinMode(inputPin, INPUT);
  timer = millis();
}

void loop() {
  // When PIR active set timer to 0.3 second
  if (digitalRead(inputPin)) timer = millis() + 300;

  // When timer is active the output will be turned on
  digitalWrite(ledPin,timer>millis());
}



It uses a timer to maintain output on without interruptions as long as the PIR signals movement, depending on how fast the PIR changes it output you may have to increase the "+ 300" value.

Umair_Khalid_Khan

Turn the timer on the PIR all the way down, as short as possible then try something like this:
Code: [Select]

#define inputPin 3
#define ledPin 13

unsigned long timer;

void setup() {
  //Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
  pinMode(inputPin, INPUT);
  timer = millis();
}

void loop() {
  // When PIR active set timer to 0.1 second
  if (digitalRead(inputPin)) timer = millis() + 300;

  // When timer is active the output will be turned on
  digitalWrite(ledPin,timer>millis());
}



It uses a timer to maintain output on without interruptions as long as the PIR signals movement, depending on how fast the PIR changes it output you may have to increase the "+ 300" value.

Thanks for your reply, will implement your code. I have already reduced the timer to the minimum( which one article states was 3 seconds for the sensor I.e the LED will stay on for 3 seconds) will let you know how it goes.
But before that could you please explain your  code a little more?

Thanks

But before that could you please explain your  code a little more?

The idea is to keep the timer at maximum time while the PIR is active. This is done by recording a time 0.3 second in the future.

As long as the timer has a value in the future the output is turned on, when the timer has not been reset for some some time (0.3second) the milles() will be larger than the timer and the output will turn off.
For the digitalWrite I used a boolean parameter instead of HIGH/LOW, this works just as well (TRUE=HIGH, FALSE=LOW).

septillion

@ HKJ-lygte , change the logic around. Do the comparison with subtraction, that way the millis() roll over has no effect. Now it has.

Code: [Select]
const byte InputPin = 3;
const byte LedPin =  13;

unsigned long timer;

void setup() {
  //Serial.begin(9600);
  pinMode(LedPin, OUTPUT);
  pinMode(InputPin, INPUT);
}

void loop() {
  // When PIR active, store millis()
  if (digitalRead(InputPin)){
    timer = millis();
  }

  // When millis() has not advanced more then 300ms from timer
  digitalWrite(ledPin, millis() - timer < 300);
}


PS 300ms is afwfully short.

@Umair_Khalid_Khan In what mode is the PIR? Retriggerable or Non-retriggerable?
Use fricking code tags!!!!
I want x => I would like x, I need help => I would like help, Need fast => Go and pay someone to do the job...

NEW Library to make fading leds a piece of cake
https://github.com/septillion-git/FadeLed

@ HKJ-lygte , change the logic around. Do the comparison with subtraction, that way the millis() roll over has no effect. Now it has.
I agree that is better coding, but it will first have an affect if the Arduino runs for more than 49 days without a reset.


PS 300ms is afwfully short.

Probably, it is some time ago I last used PIR sensors and I do not remember how fast they retrigger, that was also the reason I added a comment about adjusting the 300 value.

septillion

I agree that is better coding, but it will first have an affect if the Arduino runs for more than 49 days without a reset.
You know that, the newbie that will copy your code does not ;) So better to get in the habit of always writing it the right way :)
Use fricking code tags!!!!
I want x => I would like x, I need help => I would like help, Need fast => Go and pay someone to do the job...

NEW Library to make fading leds a piece of cake
https://github.com/septillion-git/FadeLed

Umair_Khalid_Khan

@ HKJ-lygte , change the logic around. Do the comparison with subtraction, that way the millis() roll over has no effect. Now it has.

Code: [Select]
const byte InputPin = 3;
const byte LedPin =  13;

unsigned long timer;

void setup() {
  //Serial.begin(9600);
  pinMode(LedPin, OUTPUT);
  pinMode(InputPin, INPUT);
}

void loop() {
  // When PIR active, store millis()
  if (digitalRead(InputPin)){
    timer = millis();
  }

  // When millis() has not advanced more then 300ms from timer
  digitalWrite(ledPin, millis() - timer < 300);
}


PS 300ms is afwfully short.

@Umair_Khalid_Khan In what mode is the PIR? Retriggerable or Non-retriggerable?
It is in a retrigger able mode.

Umair_Khalid_Khan

The idea is to keep the timer at maximum time while the PIR is active. This is done by recording a time 0.3 second in the future.

As long as the timer has a value in the future the output is turned on, when the timer has not been reset for some some time (0.3second) the milles() will be larger than the timer and the output will turn off.
For the digitalWrite I used a boolean parameter instead of HIGH/LOW, this works just as well (TRUE=HIGH, FALSE=LOW).
Hi! I implemented your code however, it does not help. As increasing the 0.3 seconds just increased the the time the LED was on and when I decreased it the LED started blinking on its own. Yet I did notice(on my code) that sometimes there is a delay in turning the LED on. this means that after some initial motion which causes the LED to turn on, when it switches off and there is motion, it does not light up immediately, rather it takes 1-2 seconds which needs to be fixed but even using your code and changing the timer value the results were pretty much the same.

Then your problem must be with the PIR detector and how fast it activates.
Maybe try another brand of PIR detector. When feeding the signal into a computer I would prefer a PIR detector with as short output signal as possible and let the computer stretch the pulse.

The timer value defines of long it stay on after the PIR turns off, it is used to keep the output permanently on if the PIR output flickers off/on (In retrigable mode it is not supposed to do that very much).

Umair_Khalid_Khan

Then your problem must be with the PIR detector and how fast it activates.
Maybe try another brand of PIR detector. When feeding the signal into a computer I would prefer a PIR detector with as short output signal as possible and let the computer stretch the pulse.

The timer value defines of long it stay on after the PIR turns off, it is used to keep the output permanently on if the PIR output flickers off/on (In retrigable mode it is not supposed to do that very much).
Probably it. but for now will stick to what I got.  thanks for your help anyway. :)

Go Up