Hallo,
ich möchte den Goertzel Algorithmus auf einen Mega8 implementieren. Als
Grundlage habe ich den Code von
Beitrag "Goertzel auf ATMega1280: Seltsames Problem" benutzt. Ziel ist 1750Hz und
später DTMF zu erkennen.
Genau das selbe Problem, das der Kollege im anderen Thread beschrieben
hat, tritt bei mir auch auf: Grundlegend funktioniert es, aber egal was
für einen Koeffizienten(A) ich angebe, das Maximum bleibt bei 2400Hz.
Ich habe schon mit den Skalierfaktoren herumgespielt, aber das Problem
bleibt immer bestehen.
Der betreffende Code (aus adc.c:
1 | volatile int16_t signal = 0; // filter result (signal power)
|
2 | volatile bool new_value = 0;
|
3 |
|
4 | volatile int16_t v0 = 0; // goertzel filter variables
|
5 | volatile int16_t v1 = 0;
|
6 | volatile int16_t v2 = 0;
|
7 | volatile int16_t filtidx = 0; // current filter step
|
8 |
|
9 | #define N 128 // goertzel filter length;
|
10 | // frequency resolution B = Fs/N
|
11 | #define A 106 // filter coefficient: 2*cos(4761Hz*2*pi/Fs)*128
|
12 | // scaled with 128
|
13 | ...
|
14 |
|
15 | // goertzel algorithm in ADC conversion complete ISR
|
16 | ISR(ADC_vect)
|
17 | {
|
18 | uint16_t adcval;
|
19 |
|
20 | //read 16bit ADC value
|
21 | adcval = ADCW;
|
22 |
|
23 | //goertzel
|
24 | if (filtidx == N) // outer filter
|
25 | {
|
26 | filtidx = 0;
|
27 |
|
28 | v1 = v1/256; // scaling with 128
|
29 | v2 = v2/256;
|
30 | signal = (v1*v2*A)/512; // scaling with 256
|
31 | signal = v1*v1 + v2*v2 - signal;
|
32 | new_value = true;
|
33 | v1 = 0;
|
34 | v2 = 0;
|
35 |
|
36 | }
|
37 | else // inner filter
|
38 | {
|
39 | v0 = A*v1/128; // scaling with 128
|
40 | v0 = adcval + v0 - v2;
|
41 | v2 = v1;
|
42 | v1 = v0;
|
43 | filtidx++;
|
44 | }
|
45 | }
|
Im anderen Thread hat er das Problem ja lösen können - nur wie, das hat
er nicht verraten.
Kann mir jemand von euch einen Denkanstoß geben?