Timer2 with prescaler 1024 too fast.

Hi,

I have set everything from other example of this website and from the DataSheet of the Atmega168 but the whole thing is going too fast. What is my error.

Here is the init of the timer:

volatile uint8_t countTimer;

void setupTimer()
{
 
   TCCR2A = 0;
   TCCR2B=(1<<20)|(1<<CS21)|(1<<CS22);  // Prescaler = FCPU/1024
   TIMSK2=(1<<TOIE2);               //Enable Overflow Interrupt Enable
   TCNT2=0;                                //Initialize Counter
   countTimer=0;                           //Initialize our varriable
   //sei();                                    //Enable Global Interrupts
}

Here is the interrupt:

ISR(TIMER2_OVF_vect)
{
   //This is the interrupt service routine for TIMER0 OVERFLOW Interrupt.
   //CPU automatically call this when TIMER0 overflows.

   //Increment our variable
   countTimer++;
   //Serial.println(countTimer,DEC);
   if(countTimer==61)//61 = 1 secondes
   {
        countTimer=0;
      moveLedForward = true;
   }
}

countTimer == 61 because : 16000000/1024 = 15645.
15625/256 = 61
256 is from 2^8 (timer 2 is 8 bits).

What am I doing wrong?

Probably not the error, but have you made the moveLedForward volatile?

No I haven't set moveLedForward volatile. I do not see how it can modify the delay humm I am newby, can you tell me why this variable would have an impact on the speed (faster)?

I have now set the variable to volatile and I still have the led flashing a lot more fast than every second. I would say that it flash around 4 times in 1 sec. :frowning:

The 61 in your routine is a tuneable parameter. If it's four times too fast, then set the value to 61*4=244 instead.

I just thought that the client code missed some of the ISR updates, but the case seems to be that the ISR triggers too frequently.

I know little-to-nothing about the timer bits and registers.

daok:

I think there's a problem here:

TCCR2B=(1<<20)|(1<<CS21)|(1<<CS22); // Prescaler = FCPU/1024

You have 1<<20 instead of 1<<CS20. If that term is ignored by the compiler you wind up with a divisor of 256 instead of 1024.

floresta

daok, if you are a newbie then you may be better off using the MsTimer2 library instead of trying to access the timer directly:
http://www.arduino.cc/playground/Main/MsTimer2

Or, even better, if you want to service something every second you can check the value of millis to see if a second has elapsed since the last service. millis() - Arduino Reference

...Or, even better, if you want to service something every second you can check the value of millis to see if a second has elapsed since the last service. http://www.arduino.cc/en/Reference/Millis

One could always use one of these libraries: (Both uses millis(), but hides the arithmetic from the client code)
This enables you to use the timer for something else, if you want. You do not really need timer resolution for events that occur every second. Both of these will work.

Metro

#include <Metro.h> //Include Metro library
#define LED 13 // Define the led's pin

//Create a variable to hold theled's current state
int state = HIGH;

// Instantiate a metro object and set the interval to 250 milliseconds (0.25 seconds).
Metro ledMetro = Metro(250); 

void setup()
{
  pinMode(LED,OUTPUT);
  digitalWrite(LED,state);
}

void loop()
{

  if (ledMetro.check() == 1) { // check if the metro has passed it's interval .
    if (state==HIGH)  { 
      state=LOW;
      ledMetro.interval(250); // if the pin is HIGH, set the interval to 0.25 seconds.
    } 
    else {
      ledMetro.interval(1000); // if the pin is LOW, set the interval to 1 second.
      state=HIGH;
    }
    digitalWrite(LED,state);
  }
}

TimedAction

#include <TimedAction.h>
 
//this initializes a TimedAction class that will change the state of an LED every second.
TimedAction timedAction = TimedAction(1000,blink);
 
//pin / state variables
const byte ledPin = 13;
boolean ledState = false;
 
 
void setup(){
  pinMode(ledPin,OUTPUT);
  digitalWrite(ledPin,ledState);
}
 
void loop(){
  timedAction.check();
}
 
void blink(){
  ledState ? ledState=false : ledState=true;
  digitalWrite(ledPin,ledState);
}

:slight_smile:

Thank you everybody!!!!!!! :slight_smile: so sweet to get all thoses answers! Thanks! ;D