Go Down

### Topic: Understanding timers Arduino uno (Read 2701 times)previous topic - next topic

#### Vindhyachal_Takniki

##### Aug 11, 2015, 12:12 pm
1. What are timers used in arduino uno

2. Delay() function Timer0 which is 8 bit
3. Then link here says there are Timer1 -16 bit and Timer3 whose bit size is not mentioed.
http://playground.arduino.cc/Code/Timer1

4. Arduino uno have Atmega328P whose datasheet says it has three timers: two 8 bit & one 16 bit.

5. Does that mean it has three timers: Timer0-8 bit , timer1-16 bit , timer3-8 bit?

6. i am using uno r3 with arduino 1.6.5

#### PaulS

#1
##### Aug 11, 2015, 12:25 pm
Quote
1. What are timers used in arduino uno

Quote
3. Then link here says there are Timer1 -16 bit and Timer3 whose bit size is not mentioed.
http://playground.arduino.cc/Code/Timer1
And yet you know that there is one 16 bit timer and two 8 bit timers. It does not take a degree in advanced calculus to figure out that the third timer must, therefore, be an 8 bit timer.

Quote
5. Does that mean it has three timers: Timer0-8 bit , timer1-16 bit , timer3-8 bit?
Yes.

#### Vindhyachal_Takniki

#2
##### Aug 24, 2015, 09:18 am
For UNO

1. Timer0, Timer2: 8 bit
2. Timer1: 16 bit
3. Timer3: There is no timer3 in UNO

#### GoForSmoke

#3
##### Aug 24, 2015, 09:51 amLast Edit: Aug 24, 2015, 10:06 am by GoForSmoke
For Arduino, use the functions

unsigned long millis();

unsigned long micros();

Both begin counting up from startup. The micros() has a granularity of 4.

So you save the millis at an event to a variable the you can any time subtract the saved time from the current time always yields the difference up to the limit of 32-bit unsigned. For millis the limit is 49.71-some days and for micros() it is a bit over 90 minutes.

You can have as many "timers" as you can store start times and intervals to compare the differences to.

Example including user control through 115200 baud Serial:

Code: [Select]
`/* Blink without Delay -- with unsigned long fixes and user IO.  Turns on and off a light emitting diode(LED) connected to a digital   pin, without using the delay() function.  This means that other code can run at the same time without being interrupted by the LED code.  The circuit: * LED attached from pin 13 to ground. * Note: on most Arduinos, there is already an LED on the board that's attached to pin 13, so no hardware is needed for this example.   created 2005 by David A. Mellis modified 8 Feb 2010 by Paul Stoffregen modified more by GFS ;oP  This example code is in the public domain.   http://www.arduino.cc/en/Tutorial/BlinkWithoutDelay */// constants won't change. Used here to // set pin numbers:const int ledPin =  13;      // the number of the LED pin// Variables will change:int ledState = LOW;             // ledState used to set the LEDunsigned long previousMillis = 0;        // will store last time LED was updated// the follow variables is unsigned long because the time, measured in miliseconds,// will quickly become a bigger number than can be stored in an int.unsigned long waitMillis = 750; // interval at which to blink (milliseconds)void setup() {  // set the digital pin as output:  pinMode(ledPin, OUTPUT);  Serial.begin( 115200 );  }void loop(){  // here is where you'd put code that needs to be running all the time.  // check to see if it's time to blink the LED; that is, if the   // difference between the current time and last time you blinked   // the LED is bigger than the interval at which you want to   // blink the LED.  unsigned long currentMillis = millis();  if ( currentMillis - previousMillis >= waitMillis )   {    // save the last time you blinked the LED     previousMillis = currentMillis;       // if the LED is off turn it on and vice-versa:    ledState = !ledState; // ! is logical not, opposite      // set the LED with the ledState of the variable:    digitalWrite( ledPin, ledState );  }  if ( Serial.available() )  {    char  serChar = Serial.read();    if ( serChar >= '0' && serChar <= '9' )    {      waitMillis = (unsigned long)( serChar - '0' ) * 100UL;    }   }}`

BUT if you really want to mess with the 328P Timers, knowing that you can easily conflict with libraries that are also built on that, there's a full explanation at this address:

http://www.gammon.com.au/timers
2) http://gammon.com.au/serial <-- techniques howto
3) http://gammon.com.au/interrupts
Your sketch can sense ongoing process events in time.
Your sketch can make events to control it over time.

#### MarkT

#4
##### Aug 24, 2015, 10:04 am
timer0 is in fast PWM mode and has a period of 1024us, and its overflow interrupt counts the
milliseconds (which is why millis() occasionally jumps by 2, since 1024us is not exactly 1ms).

timer1 is run in 8 bit phase-correct PWM mode despite being 16 bit, timer2 the same.  This
means they have a period of 2040us.

These default settings can be changed by writing the various control registers (see the datasheet
for all the many details).

timer0 does PWM for pins 5,6,
timer1 does PWM for pins 9,10
timer2 does PWM for pins 11,3

Some libraries take over one of timer1 or timer2 to perform specific tasks, thus preventing
PWM working on the relevant pins.  Example is the Servo library using timer1
[ I will NOT respond to personal messages, I WILL delete them, use the forum please ]

#### Vindhyachal_Takniki

#5
##### Aug 24, 2015, 02:35 pm
@GoForSmoke

Suppose your system is running for 50 day continuously. & millis() get roll_over to zero so currentMillis will be 0.
However previousMillis contain number close to 2^32 range, since last time timer was about to roll.
Now  currentMillis - previousMillis >= waitMillis, will be very large number.

That's why the error.
In other post I had asked how to solve thins, so that no such error occurs.

#### Delta_G

#6
##### Aug 24, 2015, 02:49 pm
Suppose your system is running for 50 day continuously. & millis() get roll_over to zero so currentMillis will be 0.
However previousMillis contain number close to 2^32 range, since last time timer was about to roll.
Now  currentMillis - previousMillis >= waitMillis, will be very large number.
No it won't be.  Maybe if you did it on a calculator or on paper you would get a large number, but in a computer the math has to be done with 32 bits and no more so you end up getting the right answer.

|| | ||| | || | ||  ~Woodstock

Please do not PM with technical questions or comments.  Keep Arduino stuff out on the boards where it belongs.

#### Delta_G

#7
##### Aug 24, 2015, 02:51 pm
Say previous millis was 4,294,967,290 and current millis is 10.  So what is 10 - 4,294,967,290?  On paper it is negative, but what happens when a computer tries to do this?

Run this program.  Are you surprised by the results?

Code: [Select]
`unsigned long a = 4294967290;unsigned long b = 10;void setup(){   Serial.begin(9600);   delay(20);   Serial.println(b - a);}void loop(){}`
|| | ||| | || | ||  ~Woodstock

Please do not PM with technical questions or comments.  Keep Arduino stuff out on the boards where it belongs.

#8
##### Aug 24, 2015, 03:56 pm
Doing the math in decimal does not really show the result.
Do it in hex shows it better.
You can see it easily using Windows calculator in programming mode in hex view.
Do this: elapsedMillis = currentMillis - previousMillis
Say currentMillis = 10 (just after the rollover) and
previousMillis = fffffff0 (just before the rollover)
10 - fffffff0 = ffffffff00000020
but that's 64 bits.
Throw away the top 8 digits, and you have 00000020, the time from just before rollover to just after rollover.
That's unsigned long, or 32 bit, math, which is what millis & micros return, and what the time related variables should be declared as.

micros() rolls over after 71+ minutes, not 90:
FFFFFFFF = 4294967295uS * 1 S/1000000uS * 1 min/60S = 71 min

Designing & building electrical circuits for over 25 years.  Screw Shield for Mega/Due/Uno,  Bobuino with ATMega1284P, & other '328P & '1284P creations & offerings at  my website.

Go Up