Go Down

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

Vindhyachal_Takniki

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

Quote
1. What are timers used in arduino uno
You answered that question yourself.

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.
The art of getting good answers lies in asking good questions.

Vindhyachal_Takniki

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 am Last 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 LED
unsigned 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
1) http://gammon.com.au/blink  <-- tasking Arduino 1-2-3
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

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

@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

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

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.

CrossRoads

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