I am using a IR photo photodiode / Receiver pair to light up leds connected to a TLC5940. Everything works fine with that, but I want there to be a delay after the sensor stops receiving data before the leds turn off. I cannot actually use " delay(500);" because the sensor will not be able to take in information during that delay.
I have looked intensely at the Arduino Stopwatch example to help solve my problem, Arduino Playground - Stopwatch, but what they are reading is digital... my readings from the IR sensor are analog. What I need specifically to happen in the code is this....
IR sensor is ALWAYS taking in readings and being compared to a threshold found in the setup to see if something is over the sensor...(FIGURED THIS OUT ALREADY)
IF the sensor detects motion the lights turn on, if not the lights stay off.... (FIGURED THIS OUT ALREADY)
IF the sensor does NOT detect motion JUST AFTER it has previously detected motion, a timer starts and the lights stay on until the timer reaches an arbitrary value.. ( .5 seconds ) .. ( HAVE NOT FIGURED THIS OUT YET)
Here is the code that works perfectly to perform the first 2 functions above...
#include "Tlc5940.h"
int Threshold;
void setup()
{
Tlc.init();
Threshold = analogRead(A0);
}
void loop()
{
int NewThreshold = (Threshold - 7);
int ReceiverVal = analogRead(A0);
int Value;
if(ReceiverVal < NewThreshold)
{
Value = 2000;
}
else if(ReceiverVal > NewThreshold)
{
Value = 0;
}
for(int i=0; i<16; i++)
{
Tlc.set(i,Value);
}
Tlc.update();
}
Yes sorry I am aware of how to actually measure time.. where I need guidance is how to tell the arduino " When the sensor stops sensing something above it AFTER it has been sensing something, start the timer"
So.. the problem I have is putting this into an if statement... if (( Receiver > Threshold )&&(Receiver WAS JUST PREVIOUSLY < Threshold)).. start the timer... ??? Not sure how to code this part.. especially because it is an analog value, not digital, as the stopwatch example uses.
Thanks
This just turns the led on for .5 seconds when the sensor first detects movement. I need the led to be on WHILE the sensor detects something and for an ADDITIONAL .5 seconds after it is done detecting.
Example:
My hand could be over the sensor for
1 second
3 seconds
100 seconds... but the led should be on for
1.5 seconds
3.5 seconds
100.5 seconds
It needs to check that if the sensor is NOT sensing anything and It JUST GOT DONE sensing something, the timer begins and tells the led to stay on for .5 more seconds. I don't know how to ask..
" (is nothing being sensed? AND was something just being sensed?) "
This just turns the led on for .5 seconds when the sensor first detects movement.
No. Remember these statements are being repeatedly called in loop(). So long as the first if statement remains true (hand in detector) startTime keeps getting updated and light remains on. The second if statement is always false. Once the first if statement is no longer true (you move your hand away from detector) stopTime stops being updated and if .5 sec goes by without the first if re-triggering the second if goes true and light turns off. It is doing exactly what you want.
if(Receiver < Threshold){ // if hand is detected
startTime = millis(); // start timer
digitalWrite(ledPin, HIGH); // turn led on
}
if(millis()-startTime > 500){ // if it has been .5 seconds since hand was detected
digitalWrite(ledPin, LOW); // turn led off
}
That is what it looks like to me... is this code supposed to be mixed into my code or just inserted as is?
if(Receiver < Threshold){ // is hand detected?
startTime = millis(); // the current time as hand is detected
digitalWrite(ledPin, HIGH); // make sure led is on
}
if(millis()-startTime > 500){ // has it been .5 sec since hand was LAST detected?
digitalWrite(ledPin, LOW); // turn led off
}
Maybe "startTime" isn't the best name for the variable. Here it is dropped into your code, so you can try it
#include "Tlc5940.h"
int Threshold;
int ledPin = 13; //pin # driving LED
unsigned long detectTime; //time of last detection
void setup()
{
Tlc.init();
Threshold = analogRead(A0);
pinMode(ledPin, OUTPUT); //set mode for LED
}
void loop()
{
int NewThreshold = (Threshold - 7);
int ReceiverVal = analogRead(A0);
int Value;
if(ReceiverVal < NewThreshold)
{
Value = 2000;
detectTime = millis();
digitalWrite(ledPin, HIGH);
}
else if(ReceiverVal > NewThreshold) //this can just be an else statement, don't need else if
{
Value = 0;
}
if(millis()-detectTime > 500) //turn off LED after .5 sec since last detection
{
digitalWrite(ledPin, LOW);
}
for(int i=0; i<16; i++)
{
Tlc.set(i,Value);
}
Tlc.update();
}
EDIT: I declared detectTime in the wrong scope in my original posting. It should be global so it is remembered each time through loop().
EDIT AGAIN: looking closer at your original post. I guess the Tlc is the lights you want to turn on and off. I did it for the onboard LED. I'm sure you can modify it so the Tlc lights have the .5 sec delay.
The code looks good to me. Check that your hardware is still working. Is your photodiode trigger still aligned with the receiver and / or the photodiode still emitting?
HA! got it. The problem I had is updating the TLCs outside of the if statements. I needed to update them at the end of each if statement. Thanks so much TedCook!!!
It does make sense! But now I have a new problem. With this running, my range for the IR sensor has gone from about 8 inches down to 2. WTF. It also has problems now with the lights in the room. Whereas without this delay stuff there was never a problem. I've created a new topic under Leds and multiplexing