I'm just looking for some help with the syntax on a program with a delay.
THE PROGRAM: when the motion sensor is triggered a motor runs for 15 seconds while timer runs. When the timer ends the motor stops. If motion sensed during the 15 seconds the timer resets.
This is what I have based on 'Avoid Delay' tutorial on Arduino Playground (which was quite helpful - thanks!)
I'm waiting on a sensor and can't test it as yet. I looked for a working example of the Avoid Delay on this forum and can't find the answer (only the Blink without Delay direction with previous/current/etc). I figured an example of this might be helpful for others as well. Does the syntax look right? Thanks.
Think of how you use a calendar or meeting reminders - what people dont do is this:
Look to see the time of the next appointment, subtract the current time from that
and then fall asleep for that duration.
What people actually do is:
Check to see if they should be somewhere yet, and if so start going there,
if not then continue with the current "background task" and keep checking
(or be interrupted by an alarm).
So the way to code this second model is to code a series of checks for when
its time to start each particular activity, and keep running around loop() doing
the checks. Other checks might not be in terms of time, but checking for inputs
from buttons or serial or whatever - again you keep running around loop()
doing the checks.
Each time a check succeeds you do the next step for that activity, updating
various variables that record the state of that activity (and perhaps updating
the time at which to deal with the activity again).
So you have to breakdown a complex activity into parts, use some "state variables"
to keep track of where you are in the sequence (including time values if delays
are required).
[ in your case there is clearly a check for the sensor, a check for the delay
finishing (conditional on whether you are in the part that waits) ]
Of course the simple case, where there is only one thing happening, is easy as
you can use delay since it wont block progress for anything else (as there isn't
anything else).
Thanks for the responses. Both helpful.
I've rewritten it here. I think this would work unless I still need an additional state. Also assuming that if sensor is not triggered for a long time there won't be an issue with the endless counting of currentMillis
The code in the previous post will turn on the motorpin 15 seconds after the program starts and it will stay turned on when sensorPin is HIGH.
15 seconds after startup, currentMillis will always be > timerDelay when if the sensorPin is HIGH.
Rethink a few things.
Do you realize millis() returns the time in milliseconds since the Arduino has been on.
Therefore at the 16 second mark millis() will be 16000 and the value will be > than 15000, this happens until it overflows in ~50 days.
You have:
unsigned long currentMillis = millis();
And:
if(currentMillis <= timerDelay) this will be true only for the first 15 seconds after restart and if the switch is not pressed.
Now:
if(digitalRead(sensorPin)==LOW)
currentMillis = 0;
Will turn off the motor for as long as you the sensor is triggered. The moment the sensor goes false unsigned long currentMillis = millis(); makes currentMillis equal to millis which could be > 15000 for example if the Arduino has been on for an hour it would be 60000.
Obviously, the motor would turn off immediately, when you want it to turn on for time timeDelay.
Rethink your sketch
I did know that the millis() returns in milliseconds but I did not realize the millis() counter could not be reset to begin count at 0 again.
My leaning towards using millis() over a for statement was that it would be easier to measure the duration of the time, where as with the for statement the timing (to my knowledge) would be measured more by trial and error. I'm also reluctant to throw something like a delay(15) to slow down the ++ just in case I miss the sensor switch.
Here's what I have using 'for'. If millis() can be reset to begin counting at 0 when the sensor is triggered that would be better.
int sensorPin = 5;
int motorPin = 6;
void setup()
{
Serial.begin(9600);
pinMode (sensorPin, INPUT);
pinMode (motorPin, OUTPUT);
digitalWrite(sensorPin, HIGH); // sensor triggers low
int time = 0;
int timeDelayed = 3000;
}
void loop()
{
if(digitalRead(sensorPin)==LOW){ // sensor triggered
time = 0;
}
if(time <= timeDelayed){
digitalWrite(motorPin, HIGH);
} else {
digitalWrite(motorPin, LOW);
}
time++;
}
millis() keeps marching on, that is it keeps incrementing with.
When the sensor detects something the code locks the current millis value into the currentmillis variable.
Lets say millis was 60000 then at lock in currentmillis 60000.
The difference is zero ( < 15000) so the motor is turned on.
Each time through loop() millis becomes larger but currentmillis stays at 60000.
At some point (15000 milliseconds) the difference between them will be > timerDelay at which point the motor is turned OFF.