Need help with Arduino Interrupts

Hi All;

I am a new user of Arduino. I used to work with PIC Microcontrollers. This is the first time I am using an Arduino board.

The board I am using is the Arduino Duemilanove. I have written a sample C code using Interrupt Service Routine (ISR). According to what I have learnt about Arduino my code should work correctly. But I have a problem.

I have attached an LED to the PIN13 of the Arduino. Considering the code I have provided below, The LED should flash. But it does not. Can anyone please let me now what I am doing wrong?

Regards
Ehsan :slight_smile:

Here is the code:

int ledPin = 13;

void setup()
{
pinMode(ledPin, OUTPUT);
cli(); // Disable interrupts while setting registers
TCCR2A = 0; // Reset control registers
TCCR2B = 0; // Reset control registers
TCCR2A |= (1 << WGM21); // Clear Timer on Compare Match (CTC) Mode
TCCR2B |= (1 << CS20); // Prescaler x1
OCR2A = 100000; // Set compared value
ASSR &= ~(1 << AS2); // Use system clock for Timer/Counter2
TIMSK2 = 0; // Reset Timer/Counter2 Interrupt Mask Register
TIMSK2 |= (1 << OCIE2A); // Enable Output Compare Match A Interrupt
sei(); // Enable interrupts once registers have been update
}

void loop()
{
digitalWrite(ledPin,HIGH);
}

ISR(TIMER2_COMPA_vect) // Interrupt service run when Timer/Counter2 reaches OCR2A

{
digitalWrite(ledPin,LOW);
delay(1000);
}

You can't call delay from within the ISR - the millisecond advancement it uses depends on timer0 interrupts which are disabled while inside your ISR.

and OCR2A is only a byte, it can't hold 100000.

Thanx for qiuck reply;

I have changed the ISR part to:

ISR(TIMER2_COMPA_vect) // Interrupt service run when Timer/Counter2 reaches OCR2A
{
digitalWrite(ledPin,LOW);
for(i=0; i<10000000; i++)
j=i;
}

But I still can't see the blinking!

Do you have any suggestions for me?, I would likr to make sure that the ISR is working properly!

Thank you!

Maybe gcc optimized out the delay loop. Make "i" volatile to avoid that and reduce the count by at least a factor 10.

...any suggestions...

Suggestion number 1:
Make the ISR as simple as possible (but no simpler).

Suggestion number 2:
Don't use loops trying to get predictable, repeatable delays.

//
// Set up Timer2 for an interrupt every 10 usec.
// Toggle the LED and print the value of millis()
// after every 100,000 interrupts.  (Every second
// or so.)
//
// The Interrupt Service routine simply increments a
// global variable.
//
// When the variable reaches 100,000, the loop() resets
// the variable, toggles the LED state, and performs a
// printout.
//

int ledPin = 13;

void setup()
{
    Serial.begin(9600);
    pinMode(ledPin, OUTPUT);

    // Disable interrupts while setting registers
    cli();

    // Reset control registers
    TCCR2A = 0;
    TCCR2B = 0;

    // Clear Timer on Compare Match (CTC) Mode
    TCCR2A |= (1 << WGM21);

    // Prescaler x1
    TCCR2B |= (1 << CS20);

    // Interrupt every 160/16e6 = 10 usec
    OCR2A = 159;

    // Use system clock for Timer/Counter2
    ASSR &= ~(1 << AS2);

    // Reset Timer/Counter2 Interrupt Mask Register
    TIMSK2 = 0;

    // Enable Output Compare Match A Interrupt
    TIMSK2 |= (1 << OCIE2A);

    // Enable interrupts once registers have been updated
    sei();
}

unsigned long int_count = 0;
unsigned long max_count = 100000;
int led_state = 0;

void loop()
{
    if (int_count >= max_count) {
        int_count = 0;
        Serial.println(millis());
        digitalWrite(ledPin, led_state);
        led_state = 1 - led_state;
    }
}


// This ISR is run when Timer/Counter2 reaches OCR2A
ISR(TIMER2_COMPA_vect)
{
    ++int_count;
}

Regards,

Dave

Maybe the problem is hardware not software. I have two Arduino (Decimilia and Mega) they both come with an inbuilt LED connected to Pin 13. Maybe by connecting another LED to pin 13 you created a hardware problem? So try disconnecting your LED and see if the in-built LED flashes :slight_smile:

Also the Arduiono development environment includes a simple program example for flashing a LED. You'll find it at File>Examples>Digital>Blink. If this work at least you know you don't have a hardware problem !

Use davekw7x's code - It works really well.