mikrocontroller.net

Forum: Digitale Signalverarbeitung / DSP Filtereigenschaften Bestimmen


Autor: Kollege von oben (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Leute,

ich benötige die Filter eigenschaften eines FIR Filters.
ich habe die Koeffizienten und die Abtastrate.

Wie kann aus denn Koeffizienten die Grenzfrequenz bestimmen?

Habe natürlich auch ein Beispiel leider nur in Pascal:

filter wird in einem 2mSec Interrupt aufgerufen
     pmax_filter : fdaten = (n: 1;
                     a:(0.2  ,      0,     0,   0,   0);
                     b:(    1,   -0.8,     0,   0,   0);
                     x:(    0,      0,     0,   0,   0);
                     y:(    0,      0,     0,   0,   0));

function filter(var f : fdaten; inp: single) : single;
 var i : integer;
 begin
  with f do
  begin
   for i:=n downto 1 do
   begin
    x[i]:=x[i-1];
    y[i]:=y[i-1];
   end;
   x[0]:=inp;
   y[0]:=a[0] * x[0];
   for i:=1 to n do
    y[0]:=y[0] + a[i] * x[i] - b[i] * y[i];
   filter:=y[0];
  end; { with f }
 end;

Autor: Dergute W. (derguteweka)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Moin,

Aus den Koeffizienten und der Verschaltung des Filters oder der Software 
musst du die Uebertragungsfunktion H(z) bestimmen.
Grenzfrequenz bei Filtern ist so ne Sache. Das ist nicht ganz eindeutig. 
Oft ist's die Frequenz, bei der der Amplitudengang von H(z) gegenueber 
dem Amplitudengang bei der Frequenz 0, pi/2 oder sonstirgendeiner 
Referenzfrequenz auf irgendeinen Bruchteil (oft -3dB, aber manchmal auch 
-6dB) zurueckgegangen ist.
Such' dir eine dir genehme Definition aus und loese dann H(z) danach 
auf.
Kann aber unangenehme, nicht analytisch loesbare Gleichungen ergeben.

Alternativ kannst du auch durch deine Software einen Diracimpuls laufen 
lassen und das Ergebnis fouriertransformieren. Das ergibt zumindest in 
der Theorie auch den Frequenzgang.

Gruss
WK

Autor: Reinhard M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Aus der Differenzengleichung die Übertragungsfunktion H(z) bestimmen.

Die Grenzfrequenz liegt bei -3dB ( 1/sqrt(2) )

Tip: http://www.dspguide.com/pdfbook.htm

Kapitel33 zeigt wie es geht.

Autor: Kollege von oben (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke euch schon mal.

Aber ich bin nicht so das mathe Ass.... :-(..

Könnt ihr vielleicht noch weiter helfen

Autor: Dergute W. (derguteweka)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Moin,

Kollege von oben schrieb:
> Aber ich bin nicht so das mathe Ass.... :-(..

Und ich hab keinen Pascalcompiler da... Unn nu?

Geb' mal einen Dirac drauf und poste die Impulsantwort. Oder zumindest 
den Anfang.

Gruss
WK

Autor: Kollege von oben (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Hallo WK,

ich habs gerade mal auf die schnelle in C# umgebaut.

Könntest du mir weiterhelfen

Autor: Dergute W. (derguteweka)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Moin,

Du kannsts auch noch auf Java, Python, Postscript oder Assembler umbauen 
- es wird nicht wirklich weiterhelfen.
Die Impulsantwort ist das Mittel zur Filteranalyse, nicht die 
Programmiersprache.

Kollege von oben schrieb:
> Könntest du mir weiterhelfen

Ungern, so wie's aussieht.

Gruss
WK

Autor: Reinhard M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Angenommen deine Differenzengleichung im Programm ist

   y(n) = a0 * x(n) + b1 * y(n-1) + b2 * y(n-2)


mit z -Transformation: X(z) = Summe [x(n) * z^(-n)]

y(n) * z^0  = a0 * x(n) * z^0  + b1 * y(n) * z^(-1)  + b2 * y(n) * 
z^(-2)

// z^0 = 1

y(n)  = a0 * x(n)  + b1 * y(n) * z^(-1)  + b2 * y(n) * z^(-2)

Y(z) =  a0 * X(z)+   b1 * Y(z) * z^(-1)  + b2 * Y(z) * z^(-2)

. . .

Y(z)             a0
---- = ---------------------------- = H(z)
X(z)    1 - b1*z^(-1) - b2* z^(-2)


Bei Grenzfreq.  H(z) = 1/sqrt(2)

hilft das ein bisschen ?

Autor: Reinhard M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nachtrag:
ist ein IIR Filter, kein FIR, weil rekursiv
-- von vorangegangenen Ausgangswerten abhängig --

Sollte ein schmaler Bandpass sein,
mit den Eckfrequenzen 70Hz und 85Hz.

Autor: Burkhard K. (buks)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Reinhard M. schrieb:
> Nachtrag:
> ist ein IIR Filter, kein FIR, weil rekursiv
> -- von vorangegangenen Ausgangswerten abhängig --

Wirklich?

Wenn nur a0 <> Null mit x(n) multipliziert wird gibt es kein Feedback 
und damit auch keinen "infinite response". (Normalerweise würde man a0 
dann eher mit b0 bezeichnen).

In der Schleife
   for i:=1 to n do
    y[0]:=y[0] + a[i] * x[i] - b[i] * y[i];
   filter:=y[0];
mit (nur a0 <> Null):
     pmax_filter : fdaten = (n: 1;
                   a:(0.2  ,      0,     0,   0,   0);
     ...

ist das Glied (a[i] * x[i]) = 0 und könnte somit auch weggelassen 
werden.

Autor: W.S. (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Kollege von oben schrieb:
> ich habe die Koeffizienten und die Abtastrate.

Ach so.

Es wäre durchaus hilfreich, eben diese Koeffizienten mal zu posten.

Aus deinem seltsamen Stück Pascal kann ich nicht erkennen, was da 
eigentlich wie gefiltert werden soll.

Also, poste mal deinen Filterkernel in normaler Form, dann kann ich dir 
das mal simulieren, aber so wird das nix. Ich häng dir mal ne Textdatei 
und das Wobbelergebnis dran, wo du ein SSB-Filter sehen kannst. Kommt 
auf diesem PC bissel mies, da das Programm noch mit D6 gemacht wurde und 
unter Win7 nicht gut skaliert. Aber wie Filtertaps so aussehen, kannst 
du draus entnehmen - und wenn du den Zinnober in Excel o.ä. importierst, 
kannst du dir auch den Filterkernel mal grafisch angucken.

W.S.

Autor: Reinhard M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Burkhard K. schrieb:
> Wirklich?
>
> Wenn nur a0 <> Null mit x(n) multipliziert wird gibt es kein Feedback
> und damit auch keinen "infinite response". (Normalerweise würde man a0
> dann eher mit b0 bezeichnen).

Ja, wirklich

y[0]:=a[0] * x[0];  // aktueller Ausgang = a0 * aktuellem Eingang
   for i:=1 to n do
    y[0]:=y[0] + a[i] * x[i] - b[i] * y[i];
//          ^          ^          ^
            |          |          |______ b[i] * alte y- werte
                       |                     REKURSIVTEIL (IIR) !
                       |
                       |_________ NICHT REKURSIVER (FIR) TEIL
                                  kann in diesem Fall weggelassen werden
                                  weil alle a[i] mit i>0  gleich null 
sind
   filter:=y[0];

Autor: Burkhard K. (buks)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Du hast recht, hier gibt es (ausschliesslich) einen Feedback-Anteil - 
ich hab mich von den vertauschten Koeffizientenbezeichnern a vs. b 
verwirren lassen.

Worauf ich ursprünglich hinweisen wollte: eine rekursive Struktur allein 
ist noch kein hinreichendes Merkmal für einen IIR-Filter, es gibt 
durchaus FIR-Filter mit rekursiver Struktur, z.B. Moving Averager, CIC- 
oder Frequency-Sampling-Filter.

Autor: Reinhard M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
das C#-Teil mal mit Dirac erweitert


using System;
using System.Collections.Generic;
//using System.Linq;
using System.Text;
//using System.Threading.Tasks;

namespace FilterCsharp
{
    class Program
    {
        public struct filter
        {
            public int n;
            public float[] a;
            public float[] b;
            public float[] x;
            public float[] y;
        };

        static void Main(string[] args)
        {
            filter divFilter;

            divFilter.a = new float[4];
            divFilter.b = new float[4];
            divFilter.x = new float[4];
            divFilter.y = new float[4];

            divFilter.n = 1;
            divFilter.a[0] = 0.2F;
            divFilter.a[1] = 0;
            divFilter.a[2] = 0;
            divFilter.a[3] = 0;

            divFilter.b[0] = 1;
            divFilter.b[1] = -0.8F;
            divFilter.b[2] = 0F;
            divFilter.b[3] = 0;

            for ( int  samples = 0; samples < 16; samples++)
            {
                
                float returnValue;
                
                if(samples == 0)
                  returnValue = filterFunction(divFilter, 1);
                else
                  returnValue = filterFunction(divFilter, 0);

                Console.WriteLine("Filter Value {0}", returnValue);
            }

            Console.Write("Press any key to continue . . . ");
            Console.ReadKey(true);
        }

        public static float filterFunction(filter fil, float newSample)
        {

            int i = fil.n;

            for (i = fil.n; i >= 1; i--)
            {
                fil.x[i] = fil.x[i - 1];
                fil.y[i] = fil.y[i - 1];
            }

            fil.x[0] = newSample;
            fil.y[0] = fil.a[0] * fil.x[0];

            for (i = 1; i <= fil.n; i++)
            {
                fil.y[0] = fil.y[0] + fil.a[i] * fil.x[i] - fil.b[i] * fil.y[i];
            }

            return fil.y[0];
        }
    }
}




Ausgabe:
Filter Value 0,2
Filter Value 0,16
Filter Value 0,128
Filter Value 0,1024
Filter Value 0,08192001
Filter Value 0,06553601
Filter Value 0,05242881
Filter Value 0,04194305
Filter Value 0,03355444
Filter Value 0,02684355
Filter Value 0,02147484
Filter Value 0,01717987
Filter Value 0,0137439
Filter Value 0,01099512
Filter Value 0,008796096
Filter Value 0,007036877

Autor: Reinhard M. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
nach fft
schaut doch nach TP aus

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.