-
Notifications
You must be signed in to change notification settings - Fork 9
Interrupt Overflow
The ATTINY85 can do some pretty neat stuff, but when its running at 8Mhz, you have to do some tricks to squeeze out the most of it for audio applications. Signal processing at 44.1Khz is not going to be easy to do.
8MHz/44.1KHZ = 181 clock cycles per interrupt.
You will spend a minimum of 10% of that just setting up and getting out of the interrupt.
So the key to using Arduino for audio applications is a balance between extreme engineering and scaled down expectations.
One of the strategies I have used in many of the sketches here is to just flip bits based on counter values. This is not a particularly horrible approach, if you understand and accept the limitations.
ACS-0002 is a pretty good example. It is not a complicated sketch. Just two analog reads and an interrupt timer that flips bits based on their respective counters. In addition, there is a third bit that I flip based on a mix of the first two.
Setup code is
TCCR1 = 0; //stop the timer
TCNT1 = 0; //zero the timer
OCR1A = 50; //set the compare value
OCR1C = 50; //set the compare value ??? needed
TIMSK = _BV(OCIE1A); //interrupt on Compare Match A
TCCR1 = _BV(CTC1) | _BV(CS11); // Start timer, ctc mode, prescaler clk/2
So we are setting up timer one to invoke the interrupt at
8 MHZ / ( Prescaler * (OCR+1)) = 8,000,000/2/51 = 78,431
The basic snippet used in the interrupt is:
if (oscCounter1 > oscFreq1) {
oscCounter1 = 0;
PORTB ^= (_BV(PB0));
}
oscCounter1++;
We read the value of the Analog pin and map it between 5 and 108 to oscFreq1 (somewhat arbitrary numbers)
Every time we enter the loop, if we have counted up to our number, we flip the pin and reset the counter.
For a counter value of 108, we find our theoretical frequency to be: Interrupt/(oscFreq1 * 2)
so
oscFreqCounter | Freq |
---|---|
5 | 7,834hz |
6 | 6535 |
7 | 5596 |
8 | 4896 |
9 | 4352 |
.. | .. |
106 | 369 |
107 | 366 |
108 | 362 |