Datum:
Hallo Auf der Seite : http://www-users.cs.york.ac.uk/~fisher/mkfilter habe ich ein kleines Prg gefunden zur berechnung von Filtern in C. Nach Eingabe einiger Parameter habe ich das folgende Prg in C bekommen
/* Digital filter designed by mkfilter/mkshape/gencode A.J. Fisher Command line: /www/usr/fisher/helpers/mkfilter -Bu -Bp -o 2 -a 2.0000000000e-03 2.0000000000e-02 -l */ #define NZEROS 4 #define NPOLES 4 #define GAIN 3.334227841e+02 static float xv[NZEROS+1], yv[NPOLES+1]; static void filterloop() { for (;;) { xv[0] = xv[1]; xv[1] = xv[2]; xv[2] = xv[3]; xv[3] = xv[4]; xv[4] = next input value / GAIN; yv[0] = yv[1]; yv[1] = yv[2]; yv[2] = yv[3]; yv[3] = yv[4]; yv[4] = (xv[0] + xv[4]) - 2 * xv[2] + ( -0.8521922521 * yv[0]) + ( 3.5419422394 * yv[1]) + ( -5.5270764018 * yv[2]) + ( 3.8373241082 * yv[3]); next output value = yv[4]; } } |
Es ergeben sich dadurch ein paar Fragen. Die Abtastung erfolgt bei mir mit 10 Bit. Dadurch habe ich Zahlen im Bereich von 0 bis 1023. Die Spannung kann in abhängigkeit der Frequenz im Bereich von 0 bis 5V liegen. Dieser Filter soll von 30Hz bis ca 300Hz gehen.Leider ist mir die Funktion bei diesem C-Code nicht klar. was ist der Eingnang und der Ausgang (Variable)(Spannung)? Kann ich mehrere Filter mit unterschiedlichen Daten hintereinander setzen? achim
Datum:
filterloop muss du immer dann aufrufen, wenn der ADC eine neue Wandlung fertig hat. Wenn dein uC es tatsächlich schafft, innerhalb dieser Zeit filterloop komplett auszuführen ( wegen der vielen floats ), dann kannst Du so tun, als ob "next_output_value" dein eigentlicher ADC-Wert wäre. etweder haust Du "filterloop()" in den ADC-Interrupt oder du setzt im ADC-Interrupt ein Flag und führst "filterloop()" in der Main aus. "next_input_value" innerhalb von "filterloop()" ist dein Datenregister vom ADC Besser kann ichs nicht erklären... AxelR.
Datum:
ar schrieb: > filterloop muss du immer dann aufrufen, wenn der ADC eine neue Wandlung > fertig hat. kann so leider nicht stimme, denn filterloop ist ja eine entlosschleife. Also input und output stehen ja fest: (next input value) (next output value) was diese werte absolut bedeuten spiel überhaupt keine rolle, ob nun 10 oder 100 reingegben werden spielt für die berechnung keine rolle. Der Ausgang ist dann in der gleichen "einheit". Was mir unklar ist, ist das timing. Also wie oft pro zeiteinheit die schleife durchlaufen werden soll. Klar kannst du auch mehre solcher filter hintereinander machem, du musst nur den teil innerhalb von for(;;) zusammenketten, und dort ausgang und eingang miteinander verbinden.
Datum:
Sorry, das versteh ich nicht ganz. Ich bekomme doch von meinem ADC einen ständigen Zahlenstrom (Werte der angelegten Spannung). Dieser ändert sich doch ständig im Rythmus der z.B. NF. In diesem Zahlenstrom ist doch das gesamte NF-Band drin. Wenn ich das NF Band in 3 Teile zerlegen will (Tief, Mittel, Hoch), so müssen doch an jedem Eingang eines Filters das gesamte Band anliegen. Jeder Filter errechnet einen Teil daraus und gibt es an seinen Ausgang aus, als Spannung mit entsprechender Grösse. Diese Spannung kann ich weiter verwenden um etwas zu schalten oder anzuzeigen. Habe ich das soweit richtig begriffen? Wenn ich zweite Filter, mit unterschiedlichen Frequenzen vergleiche, bekomme ich unterschiedliche Berechnungen. Brauche ich zur Abtastung noch unterschiedliche Sampling Fr. ? oder steckt das bereits in der Rechnung mit drin. Bei der Eingabe der Parametr musste ich auch die Freq. mit angeben. Eine sehr gute Beschreibung habe ich bei Spurt gefunden. Es werden die Abtastung und Filter im Prinzip sehr gut erklärt. (Leider im Prinzip. Die Umsetzung in einen C-Code ist wieder was ganz anderes. achim
Datum:
Peter II schrieb: > Also wie oft pro zeiteinheit die schleife durchlaufen werden soll. Die Schleife muß pro Abtastung genau einmal durchlaufen werden, d.h. jedes mal, wenn ein neuer Eingangswert zur Verfügung steht, deshalb auch "next input value" ;-)
Datum:
Werner schrieb: > Peter II schrieb: > >> Also wie oft pro zeiteinheit die schleife durchlaufen werden soll. > Die Schleife muß pro Abtastung genau einmal durchlaufen werden, d.h. > jedes mal, wenn ein neuer Eingangswert zur Verfügung steht, deshalb auch > "next input value" ;-) so einfach kann es leider nicht sein, denn der Filter hat ja eine filterfreqenz. > Dieser Filter soll von 30Hz bis ca 300Hz gehen. Damit muss der loop zwangsweise mit einen konstanen und bekannten anzahl pro sekunde gefüttert werden, sonst würde das überhaupt nicht funktionieren.
Datum:
Hallo ich nehme einen Atmega 128 mit 16M. Wie kann ich den erfahren, ob der ADC fertig ist? Wandelt er nicht ständig den angelegten Wert in einen entsprechenden Zahlenstrom? achim
Datum:
Achim Seeger schrieb: > ich nehme einen Atmega 128 mit 16M. Wie kann ich den erfahren, ob der > ADC fertig ist? steht im Datenblatt.
Datum:
Schön unübersichtlicher Code. schau dir mal das Tool an: http://www.winfilter.20m.com/ Lasse es einen FIR-Filter nach deinen Vorgaben rechnen und stelle das Ausgabeformat für die Koeffizienten auf INTEGER. So hat dein AVR auch noch eine Chance neben dem Filtern überhaupt noch zu etwas anderem zu kommen. Das Tool sorgt dann auch dafür das GAIN immer = 2^x ist, damit der µC die Division mittels Verschiebung realisieren kann. Nix mit x/3.334227841e+02... da rechnet der ja Morgen noch.
Datum:
Peter II schrieb: > Damit muss der loop zwangsweise mit einen konstanen und bekannten anzahl > pro sekunde gefüttert werden, sonst würde das überhaupt nicht > funktionieren.Beitrag melden Bearbeiten Löschen Beim Filterdesign hast du die Abtastfrequenz eingegeben und genau mit dieser Frequenz muß das Eingangssignal abgetastet und die Filterschleife gefüttert werden.