I've an Arduino almost entirely reconfigured with the software as optimised as I can get it. Interrupts do little work, set flags and work is done in the loop.
There are some features always taking cycles, like PID control, LCD printing, stuff like that.
The ADC measures four channels continuously and looks at one for a zero-cross. When one is detected it goes into "record" mode and accumulates values for the channels. At the next zero-cross record is disabled and computation on the results begins (RMS, real/apparent power etc). Once complete the process starts over. This way I can capture as many samples as possible without the CPU becoming a block. Now I'm onto how many samples is possible.
According to the datasheet the maximum frequency for 10 bit resolution is about 125KHz, so that is set.
ADMUX = adc.currentChannel->pin; ADCSRB = bit (ADTS1) | bit (ADTS0); // trigger of timer 0 compare ADCSRA = bit (ADEN) | bit(ADATE) | bit (ADIE) | bit(ADPS2) | bit(ADPS1) | bit(ADPS0); // enable, auto-trigger interrupt, prescaler = 128 (125KHz) adcPrintDisplay1Full();
The datasheet also says the ADC takes 13 ticks which indicates a maximum resolution of 9.84KHz.
I configure to fire it off the timer at 5KHz.
// timer 0 - trigger adc TCCR0A = bit (WGM01); // ctc mode OCR0A = 50U; // 5KHz (ADC requires 13 ticks min) OCR0B = 0; TIMSK0 = 0; TCCR0B = bit(CS00) | bit(CS01); // 16000000/64 = 250000
Assuming the CPU can keep up, that's 1.25KHz per channel.
A typical channel frequency (for zero-cross) is 50Hz.
That means I'm only getting 25 reads per period, which is really not enough to be accurate for measuring the RMS of an AC wave.
So you know what's coming :).
1. have I messed up the Hz the ADC can run at, misunderstood something?
2. any optimisations that can be done?
3. ditch the AtMega1280 and go for something much more powerful?