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.
-
Try counting how many times it fires in a secondBrettFolkins– BrettFolkins06/17/2016 20:09:03Commented 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.Gabriela Marinho– Gabriela Marinho06/17/2016 20:44:37Commented Jun 17, 2016 at 20:44
-
1In your timer ISR add one to a counter. Every second print the counter.Nick Gammon– Nick Gammon ♦06/17/2016 22:47:17Commented Jun 17, 2016 at 22:47
1 Answer 1
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);
}