Forum: Mikrocontroller und Digitale Elektronik IIR Filter mit Mega 16


von Daniel B. (yzdani)


Lesenswert?

Hallo,

möchte ein IIR Filter "basteln".
Fpass 100Hz
Fs=1Khz

Der Wert nach dem Filte soll danach auf Port C ausgegeben werden
Umso mehr ich die Frequenz erhöhe sollten dann immer ein kleinerer binär 
wert am Port C anliegen.
Nun ja bei einem Hz blinken die Leds am Port C aber wenn ich die 
Frequenz erhöhe leuchten die Leds dann immer gleich.

Der Sinus hat 1V offset und 1V Amplitude
ADC funktioniert

Was mach ich falsch?
Hat mir jemand ein Lösungsansatz?

Code:
1
int main(void)
2
{
3
  float a[3], b[3], w[3]={0,0,0};
4
  //koeffizienten
5
  a[0]=1;
6
  a[1]=-1.9961;
7
  a[2]=0.5157;
8
  b[0]=1;
9
  b[1]=1.9961;
10
  b[2]=1;
11
  float y=0;
12
  float sample;
13
  DDRA=0x00;
14
  DDRC=0xff;
15
  ADMUX|=(1<<REFS0);
16
  ADCSRA|=(1<<ADEN)|(1<<ADSC);
17
18
    while (1) 
19
    {
20
  ADCSRA|=(1<<ADSC);
21
  while(ADCSRA &(1<<ADSC));
22
  sample = ADC;  
23
    w[0]=a[0]*sample-a[1]*w[1]-a[2]*w[2];
24
    y=b[0]*w[0]+b[1]*w[1]+b[2]*w[2];
25
    //w[2]=w[1];
26
    //w[1]=w[0];
27
    PORTC=y;
28
    _delay_ms(1);
29
    }
30
}

Koeffizienten habe ich mit Matlab (fdatool) ausgerechnet.

von Jim M. (turboj)


Lesenswert?

Mit den Auskommentierten 2 Zeilen ist das eine 1-Stufige IIR, da w[1] 
und w[2] immer Null sind.

Höhere Frequenzen würden einen Logic analyser erfordern, menschliche 
Augen sind eher langsam und können zu schnelles Blinken nicht erkennen.

Workaround: Delay verlängern und mit so niedrigen Frequenz testen, wo 
die Augen noch schnell genug fürs LED Blinken sind.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Daniel R. schrieb:
> PORTC=y;

Schau dir mal an, wie ein float intern im AVR representiert wird und was 
passiert, wenn man das ohne jedes Casting auf einen 8-Bit Port schreibt. 
Da kann nichts vernünftiges bei passieren. Du kannst mal wenigstens 
einen 16-bit Timer für PWM konfigurieren und den als Ausgang nach einer 
float2short Umsetzung benutzen.
https://gcc.gnu.org/wiki/avr-gcc
https://people.ece.cornell.edu/land/courses/ece4760/Math/Floating_point/

: Bearbeitet durch User
von Peter II (Gast)


Lesenswert?

Matthias S. schrieb:
> Schau dir mal an, wie ein float intern im AVR representiert wird

das spielt überhaupt keine rolle.

> wenn man das ohne jedes Casting auf einen 8-Bit Port
> rauswirft.
das ist klar in C definiert.

Ob es das ist was er will, kann ich aber nicht erkennen. Grundsätzlich 
falsch ist es zumindest nicht.

von Matthias S. (Firma: matzetronics) (mschoeldgen)


Lesenswert?

Peter II schrieb:
> das ist klar in C definiert.

Definiert ist es, sonst hätte sich der Kompiler geweigert. Aber es ist 
nicht das, was der TE am Ausgang erwartet.

von Peter II (Gast)


Lesenswert?

Matthias S. schrieb:
> Definiert ist es, sonst hätte sich der Kompiler geweigert. Aber es ist
> nicht das, was der TE am Ausgang erwartet.

und was soll da der Hinweis auf die interne Darstellung von Float?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.