Creating a 1ms interrupt using the TCCR

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;

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 ?

    Led2(int pin) {

        ledPin = pin;
        pinMode(ledPin, OUTPUT);

The hardware is not necessarily ready to be diddled with when your constructor is called. You should, therefore, NOT be diddling with the hardware in the constructor. You SHOULD have a begin() method where the hardware diddling is done.

It seems that i am missing something here

The complete sketch.

@PaulS Thanks for your reply, but this is not an answer to the question.

In the mean time i have been googling around to find some useful documentation that clearly explains how to set timers and interrupts. These articles from maxembedded clearly explain how to set timers and interrupts.

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 ;
     
     // 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();


}

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);
            }
            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



}

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


ISR(TIMER0_COMPA_vect) {

    led.Update();

}

As a heads up to anyone thinking of using this - be aware that it trashes millis(), since it reconfigures the builtin timer0 which is used for millis (and PWM on 2 pins)