Notes On Arduino Timers

Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 30

Arduino Timers

1
Arduino Timers

Timer Interruptions
(https://electronoobs.com/eng_arduino_tut140.php)

The Arduino has two types of interruptions. Hardware interruptions which we have already seen in the
previous episode with the pin change interruptions and then we have timer interruptions and that’s
what we will talk about today. This post is about the Arduino timers, how many we have, how we could
use them and how to define an interruption based on these timers in compare match mode. Working
directly with timers and registers, will make your code a lot faster and fluent and you could create your
own interruptions without using pre made Arduino functions such as delay, analogWrite, millis and so
on. So let's start.

Part 1 - What is a Timer

As an Arduino programmer, for sure you have used timers and interrupts without even knowing.
That’s because all the low-level hardware stuff is hidden by the Arduino functions which are
already premade. A lot of Arduino functions uses timers, for example the time functions: delay,
millis, micros and delayMicroseconds. They all use the Arduino timers in the background. Other
functions such as the PWM analogWrite also uses timers. The same for the tone and the noTone
functions and even the Servo library. So, what is this timer?

A timer is a piece of hardware builtin the Arduino controller and depending on the model, it
could have different amount of timers. For example, the Arduino UNO has 3 timers, Timer0,
Tmer1 and Timer2. This is like a clock, and can be used to measure time events. The timer can
be programmed by some special registers so is like programming a clock.

Part 2 - The Prescalar


Imagine our timer as a counter that counts pulses. This timer is fed by the system clock, which for our
Arduino UNO could be the 16Mhz crystal clock or depending on the bootloader could also be an 8MHz
internal oscillator. Between our timer counter and the system clock, we have another piece of hardware
which is called prescalar. This prescalar divides the number of pulses from the system clock by the
number you define which could be 8, 64, 256 and so on, and later we will see how to define this
prescalar division number.

2
Arduino Timers

So for now imagine the main system clock is the 16Mhz crystal that will create a 16Mhz square signal.
That’s 62.5ns for each pulse, right? You feed that to the prescalar which lets say is set to 8. So, the
output signal from the prescalar will be 8 time slower so 500ns. So each 8 pulses from the system clock,
our timer will increase by 1. You can configure the prescaler for each timer using the related register and
we will see examples in a moment.

Part 3 - Why we use timers?


So what can we do with these timers. Well, timer 0 and 2 are 8 bits meaning it could count from 0 to
255. Timer 1 on the other hand, is 16 bits so it could count from 0 to 65546. Once a timer reaches its
maximum value, it will go back to 0 or start decreasing depending on the selected mode. So basically it
would create a zig zag curve. The timer starts increasing its value from 0. When we reach 255 in case of
the 8 bits register, we go back to 0 and increase once again. This will create a triangle shape curve and
we could use this to create our interruptions.

3
Arduino Timers

Part 4 - Timer ISR Modes


Each timer can generate one or more interrupts. One type of interrupt is the compare match. We can
write a value in a different register and when the timer value is equal to the compare value, it will trigger
the interrupt. For example, we set our compare match register to 100, each time timer 0 reaches 100, it
will create an interruption. Another interrupt type is for overflow. In this case an interruption is
triggered each time the timer overflows, meaning it passes from its maximum value back to 0, which in
case of an 8-bit timer will be each time it reaches 255. Finally, we have the input capture interrupt,
which for the Arduino UNO, could be implemented on timer 1. In this case the timer could store its value
in a different register, each time an external event happens on one of the Arduino pins.

Part 5 - Setting the Prescalar


First register we need to change is the prescalar. To control the timers we have two main registers, the
TCCR A and the TCCR B, each with the number of the timer. So for timer 1 we have TCCR 1A and TCCR
1B. TCCRA register is for controlling the PWM mode so for timer 1 we can control the OC1A which is
related to the PWM signal on pins 9 and 10. For our interrupt examples we don’t need this register but
we do need to set all its bits to 0 since Arduino by default has them set to 1. So, setting all these to 0 will
disable the PWM signal on pin 9 and 10.

4
Arduino Timers

Now, we need to change the TCCRB register. Here, all we care are the first 3 bits which are used to
define the prescaar value. As you can see in the table below, using the CS10 CS11 and CS12 bits, we can
disable the prescalar or set it to 1, divided by 8, 64, 256, 1024 or even use an external clock source. For
the timers 0 and 2 we have to use the TCCR0B and TCCR2B and bits CS00, CS01, cS02 ands bits CS20,
CS21 and CS22.

TCCRB Register
Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0
CS12 CS11 CS10

Example code
void setup() {
TCCR1A = 0; //Reset entire TCCR1A register
TCCR1B = 0; //Reset entire TCCR1B register
TCCR1A |= B00000100; //Set CS12 to 1 so we get Prescalar = 256
TCNT1 = 0; //Reset Timer 1 value to 0
}

void loop() {
//your code here...
}

Why we use this prescalar then? Well imagine you want to make an LED blink each half second.
So you want to trigger the timer interruption each 500ms, right? The system clock is 16Mhz so
each pulse is 62ns. In order to count up to 500ms, which are 5.000.000 ns we would need to
count up to 800.000 so we can’t use the 16 bit register for example, because it could only count
up to 65536. But if we use a prescalar of 256, we would have a pulse each 16us. So now, to

5
Arduino Timers

count up top 500ms we would need 500.000 divided by 16 equal to 31.250 pulses, and now we
could use the 16 bits register.

To set timer 1 to have a 256 prescalar, according to the table above, we need to set the CS10, CS11 and
VS12 to be 1, 0, 0. The timer value is stored in the TCNT register which in case of timer 1 is made out of
two registers because it is a 16 bits one. So if you want to reset the timer value you should equal the
TCNT register to 0 and taht's what we've amde in the example code above.

Part 5 - Setting the Interrupt (Compare Match)

Now we have the prescalar and the timer defined so the timer will go from 0 to 65 536 and then
back to 0. But we haven’t specified when to make the interruption. To activate the compare
match interruption we set the TIMSK register. As you can see, according to the lines in the
datasheet below, setting the bits 1 and 2, we can enable time compare interrupt on the value
defined on registers OCRA and OCRB.

So these OCR registers will tell when to make the interruption. For example, if we set OCR1A to
be 2000, when timer 1 reaches 2000 it will create an interruption. Knowing this, let’s make our
example that will blink an LED each 500ms.

TIMSK1
BIT Bit 7 Bit 6 Bit 5 Bit 4 Bit 3 Bit 2 Bit 1 Bit 0
OCIE1B OCIE1A TOIE1

500ms Blink Example code


I want to use timer 1. So first, in the code below we reset the values of TCCR1A and 1B to 0 to
make sure everything is clear. Then let’s set the prescalar to 256 as decided before, so for that in
the Arduino code we set TCCR1B equal to 00000100. There are multiple ways to set this as we
have learned in previous episodes. If you want to set ones, we use an OR operation. If you want
to se zeros, we use an AND operation. Now the prescalar is defined to 256, let’s enable the
compare match mode for OCR1A register. For that, remember we need to set the OCIE1A bit to
be a 1 and that’s from the TIMSK1 register. So we equal that to OR and this byte 0000 0010. We
could also make this line here, it would do the same.

/* Example code with timer intyerrutp that will create an interruption each
* 500ms using timer1 and prescalar of 256.
Calculations (for 500ms):
System clock 16 Mhz and Prescalar 256;
Timer 1 speed = 16Mhz/256 = 62.5 Khz
Pulse time = 1/62.5 Khz = 16us
Count up to = 500ms / 16us = 31250 (so this is the value the OCR register
should have)*/
bool LED_STATE = true;

6
Arduino Timers

void setup() {
pinMode(13, OUTPUT); //Set the pin to be OUTPUT
cli(); //stop interrupts for till we make the settings
/*1. First we reset the control register to amke sure we start with
everything disabled.*/
TCCR1A = 0; // Reset entire TCCR1A to 0
TCCR1B = 0; // Reset entire TCCR1B to 0

/*2. We set the prescalar to the desired value by changing the CS10 CS12 and
CS12 bits. */
TCCR1B |= B00000100; //Set CS12 to 1 so we get prescalar 256

/*3. We enable compare match mode on register A*/


TIMSK1 |= B00000010; //Set OCIE1A to 1 so we enable compare match A

/*4. Set the value of register A to 31250*/


OCR1A = 31250; //Finally we set compare register A to this value
sei(); //Enable back the interrupts
}

void loop() {
// put your main code here, to run repeatedly:
}

//With the settings above, this IRS will trigger each 500ms.
ISR(TIMER1_COMPA_vect){
TCNT1 = 0; //First, set the timer back to 0 so it resets
for next interrupt
LED_STATE = !LED_STATE; //Invert LED state
digitalWrite(13,LED_STATE); //Write new state to the LED on pin D5
}

So we set OCR1A register to that value and now we will have an interruption each 500ms. Each
time the interrupt is triggered, we go to the related ISR vector. Since we have 3 timers we have
6 ISR vectors, two for each timer and they have these names:

TIMER1_COMPA_vect
TIMER1_COMPB_vect
TIMER2_COMPA_vect
TIMER2_COMPB_vect
TIMER3_COMPA_vect
TIMER4_COMPB_vect

We use timer 1 and compare register A so we need to use the ISR TIMER1_COMPA_vect. So
below the void loop, as you can see in the code above, I define this interruption routine. Inside
this interruption all I have to do is to invert the state of my LED and create a digital write. But
first we reset the timer value otherwise it will continue to count up to its maximum value. So,
each 500ms, this code will run and invert the LED state and that creates a blink of my LED
connected to pin D5 for example. As you can see, I upload this code and I have the LED blinking
each 500ms.

7
Arduino Timers

Part 6 - Two ISR at once

You can combine these interruptions with multiple timers at the same time. For example the code
below is set to make an interruption each 100ms on timer 1 and each 8.12ms on timer 2. Each
interruption we invert the pin state of D5 and D6. I upload this code and I will have a pulse each
100ms on pin 6 and each 8.12ms on pin 5.

bool LED_STATE1 = true;


bool LED_STATE2 = true;

void setup() {
pinMode(5,OUTPUT);
pinMode(6,OUTPUT);
cli(); //stop interrupts for till we make the settings
//Timer 1 (interrupt each 100ms)
TCCR1A = 0; // Reset entire TCCR1A to 0
TCCR1B = 0; // Reset entire TCCR1B to 0
TCCR1B |= B00000100; //Set CS12 to 1 so we get prescalar 256
TIMSK1 |= B00000010; //Set OCIE1A to 1 so we enable compare match A
OCR1A = 6250; //Finally we set compare register A to this value

//Timer2 (interrupt each 8.128 ms)


// interrupt time = 1/(16Mhz/1024) * 127 = 8.128ms;
TCCR2A = 0; // Reset entire TCCR1A to 0
TCCR2B = 0; // Reset entire TCCR1B to 0
TCCR2B |= B00000111; //Set CS20, CS21 and CS22 to 1 so we get
prescalar 1024
TIMSK2 |= B00000100; //Set OCIE1B to 1 so we enable compare match B
OCR2B = 127; //Finally we set compare register B to this
value
sei(); //Enable back the interrupts
}

void loop() {
// put your main code here, to run repeatedly:
}

//With the settings above, this IRS will trigger each 8.128ms.
ISR(TIMER2_COMPB_vect){
LED_STATE1 = !LED_STATE1; //Invert LED state
digitalWrite(5,LED_STATE1); //Write new state to the LED on pin D5
}

//With the settings above, this IRS will trigger each 100ms.
ISR(TIMER1_COMPA_vect){
TCNT1 = 0; //First, set the timer back to 0 so it resets
for next interrupt
LED_STATE2 = !LED_STATE2; //Invert LED state
digitalWrite(6,LED_STATE2); //Write new state to the LED on pin D5
}

Part 7 - PWM with Timer ISR

8
Arduino Timers

Using this same code but without resetting the OCR register when we reach the value, we can
create PWM signals. This is the same process the analogWrite is using. But in this case we could
use any other pin, not just the PWM pins of the Arduino. For example, in this code, we equal
OCRA and OCRB to the analogRead from two potentiometers. The pulse width could go from
1000 to 2000 but you could set it to whatever you want in a range from 0 to 65 thousands in case
of timer 1.

So now, when each of the OCRA or OCRB is reached, we invert the pulse. By changing the
OCR value, we change the pulse width. The frequency is the same, but the width is changing. If I
upload this code we can create some PWM signals on pin 2 and 3 and we control the frequency,
and the pulse width and best of all the precision. As you know, analogWrite has a precision of 8
bits so values from 0 to 255. In this case, you can control the pulse with more precisely, with
values from 0 to 65 thousand. That’s for example how the servo library is using these timers.

bool A_STATE = true;


bool B_STATE = true;

void setup() {
pinMode(2,OUTPUT);
pinMode(3,OUTPUT);
pinMode(A0, INPUT);
pinMode(A1, INPUT);
cli(); //stop interrupts for till we make the settings
//Timer 1 (interrupt each 50ms)
TCCR1A = 0; // Reset entire TCCR1A to 0
TCCR1B = 0; // Reset entire TCCR1B to 0
TCCR1B |= B00000100; //Set CS12 to 1 so we get prescalar 256
TIMSK1 |= B00000110; //Set OCIE1A and OCIE1B to 1 -> compare match A
and B
sei(); //Enable back the interrupts
}

void loop() {
OCR1A = map(analogRead(A0),0,1024,1000,2000);
OCR1B = map(analogRead(A0),0,1024,1000,2000);
}

ISR(TIMER1_COMPA_vect){
A_STATE = !A_STATE; //Invert LED state
digitalWrite(2,A_STATE); //Write new state to the LED on pin D5
}

ISR(TIMER1_COMPB_vect){
B_STATE = !B_STATE; //Invert LED state
digitalWrite(3,B_STATE); //Write new state to the LED on pin D5
}

9
Arduino Timers

Internal Timers of Arduino


(https://projecthub.arduino.cc/Marcazzan_M/internal-timers-of-arduino-6c0f66)

In this tutorial I will explain how to use the TIMER0 of Arduino

Project description

Overview

If you need to count accurate time you need to use a timer, but usually it isn't so easy to use the
internal timers of Arduino, so in this tutorial I try to explain how to use them in an easy way.

It is so important to use timers because during the delay() function you can't do anything, but
with a timer you can do everything because when the moment does arrive, it activates the
interrupt.

I use the TIMER0 because it is the easiest timer, maybe in the future I may explain the other
timers.

How It Works

The first thing you need to see is the datasheet of ATmega328P.

COUNTER BLOCK DIAGRAM

This is the counter block diagram, and looking at this you can understand how it works.

The prescaler receives a pulse from a clock cycle and then passes it to the Control Logic,
therefore the Control Logic increments the TCNTn register by 1.

10
Arduino Timers

Now we can compare the value of TCNTn with a specific value. When the TCNTn register
arrives at this value, you know that it is passed a specific time.

This method is called CTC mode for "Clear Timer on Compare". The value TCNTn register is
compared to the OCRn register, when a compare match occurs the TOVn generates an interrupt.

Another important thing is the prescaler, with this you can create different divisions of the clock,
in fact 16MHz is too much but, thanks to the prescaler, you can create some submultiples of it.
This depends on the configuration of the TCCR0B register.

Another important thing is determine the value of OCRn register to count a specific time, you
need a bit of math.

I know that all of this can seem too complicated but I'm sure that the code below will clear up
each question.

In this case, we activate an interrupt request each 0.001 seconds.

11
Arduino Timers

TCCR0A|=(1<<WGM01); //Set the CTC mode

OCR0A=0xF9; //Set the value for 1ms

TIMSK0|=(1<<OCIE0A); //Set the interrupt request

sei(); //Enable interrupt

TCCR0B|=(1<<CS01); //Set the prescale 1/64 clock

TCCR0B|=(1<<CS00);

ISR(TIMER0_COMPA_vect){ //This is the interrupt request

It is important to set the prescaler at the end because after this instruction the timer starts to
count, if you need to stop it, you must reset all the bits of TCCR0B.

Code

Internal timer
1 /*
2 This program turns on and off a LED on pin 13 each 1 second using an
internal timer
3 */
4
5 int timer=0;
6 bool state=0;
7 void setup() {
8 pinMode(13,OUTPUT);
9
10 TCCR0A=(1<<WGM01); //Set the CTC mode
11 OCR0A=0xF9; //Value for ORC0A for 1ms
12
13 TIMSK0|=(1<<OCIE0A); //Set the interrupt request
14 sei(); //Enable interrupt
15
16 TCCR0B|=(1<<CS01); //Set the prescale 1/64 clock
17 TCCR0B|=(1<<CS00);
18
19
20
21 }
22
23 void loop() {
24 //in this way you can count 1 second because the nterrupt
request is each 1ms
25 if(timer>=1000){
26 state=!state;
27 timer=0;

12
Arduino Timers

28 }
29
30 digitalWrite(13,state);
31
32 }
33
34 ISR(TIMER0_COMPA_vect){
//This is the interrupt request
35 timer++;
36 }
37
38

13
Arduino Timers

Timer registers in Arduino


(https://www.tutorialspoint.com/timer-registers-in-arduino)

In a previous article, we used the TimerOne library to add timer interrupts to Arduino. But what
if we wish to generate timer interrupts without a third-party library? In that case, you will
directly have to meddle with the timer registers in Arduino. In this article, we will just introduce
the registers relevant to timer operations and explain their significance. We will also provide the
page numbers of the ATmega328 (used in Arduino Uno) datasheet wherein you can find detailed
information on these registers.

You can find the datasheet here


−https://ww1.microchip.com/downloads/en/DeviceDoc/Atmel7810-Automotive-
Microcontrollers-ATmega328P_Datasheet.pdf

TCCRxA and TCCRxB

These are timer control registers. The x stands for the timer number. If you are using Timer0,
you will be concerned with TCCR0A and TCCR0B registers. The TCCR0A register (primarily
the WGM00 and WGM01 bits, along with WGM02 bit from TCRR0B register), control the
counting sequence of the counter.

14
Arduino Timers

Have a look at the image below −

Generally, one of Normal or CTC modes is used. In normal more, you don’t care about the exact
time interval. If you have an 8-bit counter, you set its value to 0, wait it to reach 0xFF (0xFFFF
for 16 bit) and then the interrupt is generated. In the CTC (Clear Timer on Compare) mode, the
interrupt is generated when the value of the counter reaches the value set in OCRA register. This
gives you more control on the time interval.

The CS00, CS01 and CS02 bits of TCCR0B are used to set the prescaler of the clock. See the
image below −

TCNTx
This register is where the actual counting happens. It is generally initialized with 0. It’s value is
compared with the Output Compare Register (in CTC mode), and an interrupt is generated when
the values match.

15
Arduino Timers

OCRxA
This is the register which holds the number of ticks required for generating the required delay.
The value of TCNTx is continuously compared with OCRxA and when the values match, the
interrupt is generated

TIMSKx

Generally, only the 0CIE0A bit is important here. It has to be set to 1 to enable the interrupt
when TCNT register value reaches OCRA value.

16
Arduino Timers

Timer Interrupts in Arduino


(https://www.tutorialspoint.com/timer-interrupts-in-arduino)

As discussed in another article, Timers are basically counters. When they reach the end of the
count, they overflow. We can use this event to generate an interrupt. Now, the traditional way of
generating the interrupts in Arduino involve changing a lot of registers. Luckily, we have
libraries for making our lives easy.

We will use the TimerOne library for generating interrupts on Timer1. Similarly, there is the
TimerThree library for generating interrupts on Timer3 (not applicable for Arduino Uno).

Go to Tools -> Manage Libraries and search for TimerOne and TimerThree (optional) and
click Install.

17
Arduino Timers

Next, import the library in your code by Sketch-> Include library.

18
Arduino Timers

19
Arduino Timers

This will add the following line at the top of your code −

#include <TimerOne.h>

Now, there are two functions of importance here: Timer1.initialize() and


Timer1.attachInterrupt(). The initialize function takes in the time in microseconds for which the
timer should run. In other words, it determines the time after which the interrupt should get
triggered.

The attachInterrupt() function takes in the name of the function to be called every time the
interrupt gets triggered, as argument.

The sample code below gives you an example −

Example
#include <TimerOne.h>
volatile bool timerTriggered = false;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
Timer1.initialize(1000000); //Initialize timer with 1 second period
Timer1.attachInterrupt(printFunc);
}
void loop() {
// put your main code here, to run repeatedly:
if(timerTriggered){
Serial.println("Timer was triggered");
delay(1);
timerTriggered = false;
}
}
void printFunc(void){
timerTriggered = true;
}

As you can see, the timer is initialized with a period of 1 second (1,000,000 microseconds).
Every time the timer is triggered, the printFunc function is called and the timerTriggered flag
is set. Notice that the timerTriggered bool has been declared as volatile, because it is being
changed within the interrupt function. Once the flag is set, a print statement is executed in the
loop, and the flag is reset.

Just like any other interrupt function, printFunc can’t have any arguments, and can’t return
anything.

Please note that the Timer1 can accept a minimum period of 1 microsecond and a maximum
period of 8388480 microseconds (about 8.3 seconds).

20
Arduino Timers

If you are using the TimerThree library, replace Timer1 with Timer3 in the above code. Of
course, TimerThree won’t work with Arduino Uno, because it only has Timer0, Timer1 and
Timer2. It can work with other boards which have Timer3 as well (Teensy is a good example).

21
Arduino Timers

Watchdog timer in Arduino


(https://www.tutorialspoint.com/watchdog-timer-in-arduino)

A watchdog timer is an essential part of any microcontroller. It resets the program if the program
gets stuck anywhere. Very briefly, this is how the watchdog timer works −

 The timer keeps incrementing.


 The program has to ensure that it keeps resetting the timer, i.e. does not allow it to
overflow.
 If the timer overflows, it means that the program was stuck somewhere and therefore was
unable to reset the timer. An interrupt is generated on timer overflow which resets the
microcontroller.

To implement watchdog timer in Arduino, we use the avr wdt library.

The code is given below −

#include<avr/wdt.h>
void setup() {
Serial.begin(9600);
wdt_disable(); //Disable WDT
delay(3000);
wdt_enable(WDTO_2S); //Enable WDT with a timeout of 2 seconds
Serial.println("WDT Enabled");
}
void loop() {
for(int i = 0; i<5; i++)
{
Serial.println("Looping");
delay(1000);
wdt_reset(); //Reset the watchdog
}
while(1); //Watchdog timer should get triggered here
}

As you can see, we initialize Serial and first disable watchdog timer. Then a delay of 3 seconds is
introduced. The program won't reset here, because the watchdog is disabled. Now, the watchdog
timer with a timeout of 2 seconds is enabled. It means, if the program doesn't reset this timer
within every 2 seconds, then the watchdog will get triggered and restart the microcontroller.

Within the loop, we first print to the Serial for 5 seconds, making sure to reset the watchdog
every second. The program works fine so far. Then, we enter into an infinite while loop. Over
here, since we are not resetting the wdt, it will get triggered and restart the Arduino.

Note that the preset watchdog timeout values are available from 15 ms to 8 s.

22
Arduino Timers

Creating a 1ms interrupt using the TCCR


(https://forum.arduino.cc/t/creating-a-1ms-interrupt-using-the-tccr/487329)

I am trying to get an understanding how to program the timers in C on a Arduino nano.

I have a simple internal class to set the Led on the board on and off every 1000 update calls.

class Led2 {
int ledPin;
int ledState;
int divider;

public:

Led2(int pin) {

ledPin = pin;
pinMode(ledPin, OUTPUT);

ledState = LOW;
divider = 0;

void Update() {

divider++;

if (divider >= 1000) {

if (ledState == LOW) {
ledState = HIGH;
digitalWrite(ledPin, ledState);
} else {
ledState = LOW;
digitalWrite(ledPin, ledState);
}
divider = 0;
}
}

};

I have set the output compare register A for timer 0 to 0x01. Just a random value. Any value
should be ok, right ?

// Timer 0 output compare register A


OCR0A = 0x01;

23
Arduino Timers

The prescaler has been set to 0x3E (62) to get a frequency of 1000Hz. So there are
16000000/256/1000 'ticks' required to increase the counter in register A. Correct ?

TCCR0A = 0x3E;

The timer compare interrupt for timer 0 register a is set

TIMSK0 |= (1 << OCIE0A); // timer compare interrupt Timer 0 register A

The update method for led13 is invoked through the interrupt service register 1000 timers per
second.

ISR(TIMER0_COMPA_vect) {

led13.Update();

My expectation was that the led should now blink at a rate of 1Hz. Instead is seems to be in a
HIGH state only.

When changing TCCR0A to 0x1F (31 = 16000000/256/2000Hz) it seems to blink with an


interval of 1 second.

It seems that i am missing something here, but what ?

These helped me out to set the correct register values to create an interrupt every 1ms.
// TCCR
// CPU Freq 16Mhz
// Need interval of 1Ms ==> 0,001/(1/16000000) = 16.000 ticks
//
// Prescaler 64 ==> resolution changes from 0,0000000625 to 0,000004
// Need interval of 1Ms ==> 0,001/((1/16000000)*64) = 250 ticks

// Set prescaler to 64 ; (1 << CS01)|(1 << CS00)


// Clear Timer on Compare (CTC) mode ; (1 << WGM02)
TCCR0A = 0 ;
TCCR0B |= (1 << WGM02)|(1 << CS01)|(1 << CS00) ;

// set Output Compare Register to (250 - 1) ticks


OCR0A = 0xF9;

// TCNT0
// Timer count = (required delay/clock time period) - 1
// 249 = (0,001/0,000004) - 1

// initialize counter
TCNT0 = 0 ;

24
Arduino Timers

// TIMSK0
// Set Timer Interrupt Mask Register to
// Clear Timer on Compare channel A for timer 0
TIMSK0 |= (1 << OCIE0A) ;

After setting the registers accordingly the Interrupt Service Routine (ISR) is called every 1ms
and the led is blinking every 1 second

ISR(TIMER0_COMPA_vect) {

led2.Update();

Another Solution
================
And for the benefit of others the complete .cpp

#include "Arduino.h"
#include "LandjeRobot.h"

class Led {
int ledPin;
int ledState;
int divider;

public:

Led(int pin) {

ledPin = pin;
pinMode(ledPin, OUTPUT);

ledState = LOW;
divider = 0;

void Update() {

divider++;

if (divider >= 1000) {

if (ledState == LOW) {
ledState = HIGH;
digitalWrite(ledPin, ledState);
} else {
ledState = LOW;
digitalWrite(ledPin, ledState);

25
Arduino Timers

}
divider = 0;
}
}

};

//Led led13(13, 500, 1000);


Led led(13);

// Constructor
LandjeRobot::LandjeRobot(int motor_data[2][5], HardwareSerial &print) {
printer = &print; //operate on the address of print
printer->begin(57600);
printer->println("Hello LandjeRobot!");

// noInterrupts(); // disable all interrupts

// TCCR
// CPU Freq 16Mhz
// Need interval of 1Ms ==> 0,001/(1/16000000) = 16.000 ticks
//
// Prescaler 64 ==> resolution changes from 0,0000000625 to 0,000004
// Need interval of 1Ms ==> 0,001/((1/16000000)*64) = 250 ticks

// Set prescaler to 64 ; (1 << CS01)|(1 << CS00)


// Clear Timer on Compare (CTC) mode ; (1 << WGM02)
TCCR0A = 0;
TCCR0B |= (1 << WGM02) | (1 << CS01) | (1 << CS00);

// set Output Compare Register to (250 - 1) ticks


OCR0A = 0xF9;

// TCNT0
// Timer count = (required delay/clock time period) - 1
// 249 = (0,001/0,000004) - 1

// initialize counter
TCNT0 = 0;

// TIMSK0
// Set Timer Interrupt Mask Register to
// Clear Timer on Compare channel A for timer 0
TIMSK0 |= (1 << OCIE0A);

// interrupts(); // enable all interrupts

26
Arduino Timers

LandjeRobot::~LandjeRobot() {
// Nothing to destruct yet
}

ISR(TIMER0_COMPA_vect) {

led.Update();

27
Arduino Timers

28
Arduino Timers

29
Arduino Timers

30

You might also like