4

I'm trying to set a 33 ms interrupt on my Arduino Mega and I'm not sure if I a in fact getting that kind of delay time. Is there a way to check?

I've calculated that that I need 515.6 ticks to achive this kind of delay with a prescaler of 1024 and I've coded it up like so:

void setupInterupt()
{
 noInterrupts();
 TCCR2A = 0; 
 TCCR2B = 0; 
 TCNT2 = 0; 
 OCR2A = PERIOD - 1; 
 TIMSK2 = _BV(OCIE2A); 
 TCCR2B |= _BV(CS12) | _BV(CS10); // prescale by 1024
 interrupts();
}

I followed the information on the Arduino Playground page and if my math is correct this interrupt should be going off every 33 milliseconds. I tried to test that using the millis(); method but it only returns the time that program was on.

asked Jun 17, 2016 at 19:51
3
  • Try counting how many times it fires in a second Commented Jun 17, 2016 at 20:09
  • Can you expand on that? This is my first Arduino project so I'm not totally sure how to do what you just said. Commented Jun 17, 2016 at 20:44
  • 1
    In your timer ISR add one to a counter. Every second print the counter. Commented Jun 17, 2016 at 22:47

1 Answer 1

2

It doesn't fire every 33 milliseconds. First, you missed setting the CSn1 bit necessary for a 1024 prescaler; second, It looks like you want CTC mode (where the timer resets at OCRnA) but you didn't set the WGM21 bit necessary for that mode. After that your problem is that timer2 is an 8 bit timer and so OCR2A cannot store 515, but you math is correct.

You can get the period you want on a 16-bit timer; on the arduino mega thats timers 1,3,4, and 5.

Anyway here is a simple sketch for finding the average interval between interrupts. It just keeps track of the total time elapsed and the number of times the interrupt fired; the ratio of these two is the average time per interrupt.

In this case, with a prescaler of 1024, OCRA = 0xFF, and CTC mode, it runs at an interrupt every 16.384 ms.

volatile uint16_t interruptCount;
volatile uint32_t start;
ISR(TIMER2_COMPA_vect){
 interruptCount++;
}
void setup(){
 Serial.begin(9600);
 noInterrupts();
 TCCR2A = _BV(WGM21);
 TCCR2B = _BV(CS22) | _BV(CS21) | _BV(CS20); // prescale by 1024
 OCR2A = 0xFF;
 TIMSK2 = _BV(OCIE2A);
 // start the timer
 interruptCount = 0;
 start = micros();
 interrupts();
}
void loop(){
 // read interrupt count into a local variable atomically
 noInterrupts();
 uint16_t localCount = interruptCount;
 interrupts();
 uint32_t time = micros() - start;
 // time elapsed
 Serial.print(time);
 Serial.print(" ");
 // number of times the interrupt handler fired
 Serial.print(localCount);
 Serial.print(" ");
 // average number of microseconds per interrupt
 Serial.print(time / localCount);
 Serial.println();
 delay(30);
}
answered Jun 17, 2016 at 22:20

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.