PaulStoffregen / TimerOne

TimerOne Library with optimization and expanded hardware support
http://www.pjrc.com/teensy/td_libs_TimerOne.html
470 stars 209 forks source link

setPeriod() starts new period with whatever is left over in TCNT1 #18

Open samcarson opened 8 years ago

samcarson commented 8 years ago

If a stop() is issued for a running timer, TCNT1 is not cleared and a subsequent setPeriod() will start with the residual initial value. The following will reproduce the problem

timer1.initialize(3000000); //start a three second timer delay(2000); //wait 2 seconds timer1.stop(); //stop timer1 // TCNT1 contains the residual unsigned long saveStartTime = millis(); timer1.setPeriod(2000000); // set new 2 second timer TIFR1 = _BV(TOV1); // Be sure overflow flag is cleared
while(!(TIFR1 & TOV1)); // wait for timer overflow Serial.print("Timer expired at "); Serial.print(millis() - saveStartTime); Serial.println(" milliseconds);

Note: the expire interval can be ANY value BUT IT WILL NOT BE 2000 MILLISECONDS!! This is a consequence of the calculation of the prescaler bits.

samcarson commented 8 years ago

Leave a comment

samcarson commented 8 years ago

Leave a comment

samcarson commented 8 years ago

Correction: Timer1 overflow test should be while(!(TIFR1 & _BV(TOV1))); // wait for timer overflow

samcarson commented 8 years ago

Further testing results:

If the timer was counting down when stopped, it will continue counting down after a setPeriod() thus setting the overflow when the residual TCNT1 count goes to 0. Thus the first interval after the setperiod() is incorrect. This probably does not matter for PWM but is critical it using the timer for timeout intervals, for example looking for a response from a device within a specific time after a command .

RossAWaddell commented 5 years ago

samcarson - did you ever get a workaround for this? I think this is exactly the problem I'm seeing with my project where I want to restart the count if a button is pushed, but it doesn't seem to work with the simple stop() and start() functions (or even using setperiod(x)). In my case, I initialize Timer1 with a period of 5 seconds in setup() but then use stop() so it doesn't start the compare until a button is pushed. I got this working but the second part is if the user pushes a 2nd button before the 5 secs it should restart from the beginning, but it doesn't.

samcarson commented 5 years ago

From: RossAWaddell Sent: Monday, April 08, 2019 11:17 AM To: PaulStoffregen/TimerOne Cc: samcarson ; Author Subject: Re: [PaulStoffregen/TimerOne] setPeriod() starts new period with whatever is left over in TCNT1 (#18)

samcarson - did you ever get a workaround for this? I think this is exactly the problem I'm seeing with my project where I want to restart the count if a button is pushed, but it doesn't seem to work with the simple stop() and start() functions (or even using setperiod(x)). In my case, I initialize Timer1 with a period of 5 seconds in setup() but then use stop() so it doesn't start the compare until a button is pushed. I got this working but the second part is if the user pushes a 2nd button before the 5 secs it should restart from the beginning, but it doesn't.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or mute the thread.

samcarson commented 5 years ago

No I did not. It has been a long time. I think I either used a different timer or changed processors. Sorry. Sam Carson

From: RossAWaddell Sent: Monday, April 08, 2019 11:17 AM To: PaulStoffregen/TimerOne Cc: samcarson ; Author Subject: Re: [PaulStoffregen/TimerOne] setPeriod() starts new period with whatever is left over in TCNT1 (#18)

samcarson - did you ever get a workaround for this? I think this is exactly the problem I'm seeing with my project where I want to restart the count if a button is pushed, but it doesn't seem to work with the simple stop() and start() functions (or even using setperiod(x)). In my case, I initialize Timer1 with a period of 5 seconds in setup() but then use stop() so it doesn't start the compare until a button is pushed. I got this working but the second part is if the user pushes a 2nd button before the 5 secs it should restart from the beginning, but it doesn't.

— You are receiving this because you authored the thread. Reply to this email directly, view it on GitHub, or mute the thread.