Hello!

I have a application which reads all ADC channels in (DIP) Atmega8. For one channel it does Goertzel filtering. For some reason goertzel doesn't work as expected. I can't find anything what could cause it. Do you?

volatile uint16_t adc_values[6]; volatile uint8_t adc7samplecount = 0;

....

ISR(ADC_vect) { static uint8_t ch=0; uint16_t result; result = ADCL; // low order result += ADCH << 8; // and high order if(ch == 5 && adc7ready == 0) { ProcessSample(result); adc7samplecount++; if(adc7samplecount >= N ) { adc7samplecount = 0; adc7ready = 1; } } adc_values[ch] = result; ADCSRA &= ~(1 << ADEN | 1 << ADFR); ch++; if(ch > 5) ch = 0; ADMUX = (ADMUX & 0xF0) | ch; ADCSRA |= ((1 << ADSC) | (1 << ADEN) | (1 << ADFR)); }

int main(void) { .... init_adc_int(); InitGoertzel(); .... sei(); .... while(1) { ... if(adc7ready == 1) { mag = GetMagnitudeSquared(); GetRealImag(&real, &imag); res = real*real + imag*imag; ResetGoertzel(); adc7ready=0; } .... } }

void init_adc_int(void) { // Select AVcc as ref and start from ch0 ADMUX = (1 << REFS0); // enable with prescale = 128 ADCSRA = (1 << ADPS2) | (1 << ADPS1) | (1 << ADPS0); // Enable ADC, enable interrupts, free running mode ADCSRA |= (1 << ADEN) | (1 << ADIE) | (1 << ADFR); // Start A2D Conversions ADCSRA |= (1 << ADSC); }

#define SAMPLING_RATE (F_CPU / 32 / 13) #define TARGET_FREQUENCY 1000.0 #define N 92 //Block size #define PI 3.141592654

/* Call this routine for every sample. */ void ProcessSample(uint16_t sample) { float Q0; Q0 = coeff * Q1 - Q2 + (float) sample; Q2 = Q1; Q1 = Q0; } /* Basic Goertzel */ /* Call this routine after every block to get the complex result. */ void GetRealImag(float *realPart, float *imagPart) { *realPart = (Q1 - Q2 * cosine); *imagPart = (Q2 * sine); } /* Optimized Goertzel */ /* Call this after every block to get the RELATIVE magnitude squared. */ float GetMagnitudeSquared(void) { float result; result = Q1 * Q1 + Q2 * Q2 - Q1 * Q2 * coeff; return result; } /* Call this routine before every "block" (size=N) of samples. */ void ResetGoertzel(void) { Q2 = 0; Q1 = 0; } /* Call this once, to precompute the constants. */ void InitGoertzel(void) { int k; float floatN; float omega; floatN = (float) N; k = (int) (0.5 + ((floatN * TARGET_FREQUENCY) / SAMPLING_RATE)); omega = (2.0 * PI * k) / floatN; sine = sin(omega); cosine = cos(omega); /*k= 0.45; sine = 0.2; cosine = 0.7; omega = 0.8; coeff = 2.0 * cosine; */ ResetGoertzel(); }