Forum: Digitale Signalverarbeitung / DSP / Machine Learning Filter in C programmieren


von Achim S. (achims)


Lesenswert?

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
1
/* Digital filter designed by mkfilter/mkshape/gencode   A.J. Fisher
2
   Command line: /www/usr/fisher/helpers/mkfilter -Bu -Bp -o 2 -a 2.0000000000e-03 2.0000000000e-02 -l */
3
4
#define NZEROS 4
5
#define NPOLES 4
6
#define GAIN   3.334227841e+02
7
8
static float xv[NZEROS+1], yv[NPOLES+1];
9
10
static void filterloop()
11
  { for (;;)
12
      { xv[0] = xv[1]; xv[1] = xv[2]; xv[2] = xv[3]; xv[3] = xv[4]; 
13
        xv[4] = next input value / GAIN;
14
        yv[0] = yv[1]; yv[1] = yv[2]; yv[2] = yv[3]; yv[3] = yv[4]; 
15
        yv[4] =   (xv[0] + xv[4]) - 2 * xv[2]
16
                     + ( -0.8521922521 * yv[0]) + (  3.5419422394 * yv[1])
17
                     + ( -5.5270764018 * yv[2]) + (  3.8373241082 * yv[3]);
18
        next output value = yv[4];
19
      }
20
  }
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

von ar (Gast)


Lesenswert?

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.

von Peter II (Gast)


Lesenswert?

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.

von Achim S. (achims)


Lesenswert?

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

von Werner (Gast)


Lesenswert?

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" ;-)

von Peter II (Gast)


Lesenswert?

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.

von Achim S. (achims)


Lesenswert?

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

von Peter II (Gast)


Lesenswert?

Achim Seeger schrieb:
> ich nehme einen Atmega 128 mit 16M. Wie kann ich den erfahren, ob der
> ADC fertig ist?

steht im Datenblatt.

von egbert (Gast)


Lesenswert?

Da fehlen die Grundlagen!

von myzyn (Gast)


Lesenswert?

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.

von Werner (Gast)


Lesenswert?

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.

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.