Notice: Any messages purporting to come from this site telling you that your password has expired, or that you need to verify your details, confirm your email, resolve issues, making threats, or asking for money, are
spam. We do not email users with any such messages. If you have lost your password you can obtain a new one by using the
password reset link.
Entire forum
➜ Electronics
➜ Microprocessors
➜ Elapsed time class
Postings by administrators only.
Refresh page
Posted by
| Nick Gammon
Australia (23,120 posts) Bio
Forum Administrator |
Date
| Wed 11 May 2011 02:54 AM (UTC) Amended on Sun 22 Jan 2012 06:40 PM (UTC) by Nick Gammon
|
Message
| One thing that seems to trip up beginners to the Arduino is the idea of implementing delays without using delay(). Hence the "blink without delay" example sketch. But that sketch is a bit confusing. You have to set up a "start" variable, assign the time to it, check it by doing subtraction rather than addition, and so on. And it gets more confusing if you want two time intervals.
The "elapsed" class below tries to simplify that. The class has a couple of member variables (startus and startms) which remember when you last "reset the timer". Then you simply call intervalMs (for milliseconds) or intervalUs (for microseconds) to see if your required time period is up. When it is, you can do something, like flash a LED. Then you can reset the timer if you want to.
Example snippet:
if (t2.intervalMs () > 200) // time up?
{
digitalWrite(2, !digitalRead (2)); // toggle the LED
t2.reset (); // reset the timer
} // end if time up
The Arduino library can be downloaded from here:
http://www.gammon.com.au/Arduino/Elapsed.zip (4 Kb)
Unzip the file into your Arduino sketch "libraries" folder.
To use it just:
Example code that flashes two LEDs at different rates:
#include <Elapsed.h>
void setup()
{
pinMode (2, OUTPUT);
pinMode (3, OUTPUT);
} // end of setup
static Elapsed t2, t3;
void loop() {
if (t2.intervalMs () > 200)
{
digitalWrite(2, !digitalRead (2));
t2.reset ();
}
if (t3.intervalMs () > 500)
{
digitalWrite(3, !digitalRead (3));
t3.reset ();
}
} // end of loop
The example code flashes two LEDs at different intervals. The variables t2 (for pin 2) and t3 (for pin 3) are used to see if the time is up to toggle the LED state.
Note that the millisecond interval wraps around after about 50 days, and the microsecond interval wraps around after about 70 minutes. The wrap-around itself is handled correctly, but if you need to time an interval longer than 70 minutes you would need to check intervalMs rather than intervalUs.
As with millis() and micros() if you turn off interrupts the times may be out.
Warning: If you try to move the variables inside a function you will probably need to make them static (or they will reset each time the function is entered), like this:
void loop() {
static Elapsed t2, t3; // must have static here
// ...
}
|
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|
Posted by
| Yair
(3 posts) Bio
|
Date
| Reply #1 on Sun 22 Jan 2012 01:31 PM (UTC) Amended on Sun 22 Jan 2012 01:46 PM (UTC) by Yair
|
Message
| hey nick, thanks for the many examples.
i *think* there is a typo in the closing code box
it has a void loop() in there.
also i would like to explore ways of dynamicly creating this elapsed timers. what is missing in this code?
void setup(){
}
void loop(){
for(int i=0;i<10;i++){
pulse(i);
}
}
void pulse(int pin){
if(time[pin].intervalMs() > 100) //how can i dynamicly create time01?
{
digitalWrite(pushPin[pin], LOW);
time[pin].reset();
}
}
| Top |
|
Posted by
| Nick Gammon
Australia (23,120 posts) Bio
Forum Administrator |
Date
| Reply #2 on Sun 22 Jan 2012 06:43 PM (UTC) |
Message
| I was illustrating that the timer was inside loop. I've modified the post to make that clearer.
As for dynamically creating timers, you mean an array, like this?
#include <Elapsed.h>
Elapsed time [10]; // array of timers
const byte pushPin [10] = { 2, 3, 4, 5, 6, 7, 8, 9, 10, 11 };
void setup(){
}
void loop(){
for(int i=0;i<10;i++){
pulse(i);
}
}
void pulse(int pin){
if(time[pin].intervalMs() > 100) //how can i dynamicly create time01?
{
digitalWrite(pushPin[pin], LOW);
time[pin].reset();
}
}
I don't see what you really get here that you couldn't just be using a single timer though. |
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|
Posted by
| Yair
(3 posts) Bio
|
Date
| Reply #3 on Sun 22 Jan 2012 07:06 PM (UTC) Amended on Sun 22 Jan 2012 07:16 PM (UTC) by Yair
|
Message
| my understanding was that loop itself is a function, being called every "cycle".
i was sure it a typo as i used function with the 500ms code , without the static inside the loop() and it seems to work.
#include <Elapsed.h>
int goo;
void setup()
{
Serial.begin (115200);
} // end of setup
static Elapsed time, time2;
void loop() {
if (time2.intervalMs () > 500)
{
Serial.println ("tick2\n");
H_pulseNod();
time2.reset ();
}
} // end of loop
void H_pulseNod(){
Serial.print("aaa > ");
Serial.println(millis());
if(time.intervalMs() > 1000)
{
goo++;
Serial.print("goo > ");
Serial.println(goo);
time.reset();
}
}
im currently using tons of methods from your generous examples. especially the Serial state machine, clearly writen and so needed. | Top |
|
Posted by
| Nick Gammon
Australia (23,120 posts) Bio
Forum Administrator |
Date
| Reply #4 on Sun 22 Jan 2012 09:49 PM (UTC) |
Message
| What you have is fine. However your two variables time and time2 are not inside the loop(). If they were, you would need "static" or they get reset every time through loop().
Quote:
im currently using tons of methods from your generous examples ... clearly writen and so needed
Thanks! It's nice to get feedback. :) |
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|
Posted by
| Yair
(3 posts) Bio
|
Date
| Reply #5 on Sun 22 Jan 2012 11:09 PM (UTC) |
Message
| im having difficulties getting my digital pins to run in sequence, like in the chase example (example >control>arrays)
basically im looking for array with no delay. currently im not using array, just trying to get the sequence going. but im missing something.
void HwaveLeft(){
if(timerChase.intervalMs() > waveIntrvl && waveState==0){
H_pulse(0);
waveState=1;
}
if(timerChase.intervalMs() > waveIntrvl*2 && waveState==1){
H_pulse(1);
waveState=2;
}
if(timerChase.intervalMs() > waveIntrvl*4 && waveState==2){
H_pulse(2);
waveState=3;
}
if(timerChase.intervalMs() > waveIntrvl*5 && waveState==3){
H_pulse(3);
waveState=0;
timerChase.reset();
}
void H_pulse(int pin){
if(time[pin].intervalMs() > intrvl_kick && Hstate[pin]==0)
{
H_bwd(pin);
Hstate[pin]=1;
}
if(time[pin].intervalMs() > intrvl_kick+intrvlOFF && Hstate[pin]==1) //50
{
H_fwd(pin);
Hstate[pin]=2;
}
if(time[pin].intervalMs() > intrvl_kick+intrvlON && Hstate[pin]==2) //15
{
H_off(pin);
Hstate[pin]=0;
time[pin].reset();
}
}
btw. feel free to direct me to the arduino forums if you see fit..
| Top |
|
Posted by
| Nick Gammon
Australia (23,120 posts) Bio
Forum Administrator |
Date
| Reply #6 on Mon 23 Jan 2012 01:00 AM (UTC) |
Message
| Yes, probably a good idea. People are always asking about doing things in sequence there. If you make a post (put the whole sketch there, not just parts of it) and send me a PM on the forum giving the post link, I'll take a look at it. |
- Nick Gammon
www.gammon.com.au, www.mushclient.com | Top |
|
The dates and times for posts above are shown in Universal Co-ordinated Time (UTC).
To show them in your local time you can join the forum, and then set the 'time correction' field in your profile to the number of hours difference between your location and UTC time.
22,072 views.
Postings by administrators only.
Refresh page
top