Hallo zusammen,
ich habe einen Zwischenkreis, den ich kontinuiertlich messe mit ~50kHz.
Dann teile ich die Werte runter (Alle Werte addieren und dann Teilen)
auf ca. 500Hz. Das ganze füttere ich dann in einen Ringpuffer.
1
void dclink_submit_value(float v){
2
dclink_ringbuffer_pos=dclink_ringbuffer_pos+1;
3
if(dclink_ringbuffer_pos>(DCLINK_FIR_TABS-1)){
4
dclink_ringbuffer_pos=0;
5
}
6
dclinkfirbuffer[dclink_ringbuffer_pos]=v;
7
}
Eine weitere Rutine rechnet dann den FIR Filter. Der Code ist angepasst
und auf dem Computer vorgetestet. Er basiert auf einem FIR-YouTube
Tutorial.
Das ganze läuft auf einem Cotex M4.
Jetzt ist das Problem, dass ich irgendwie keine Tiefpasswirkung habe.
Gewünscht ist, dass alle Störungen ab 60 Hz durchkommen, ab 80 Hz alles
weggefiltert wird. Der FIR Filter hat 100 Taps.
Ich habe Gleichsspannung am Zwischenkreis getestet. Perfekt, kaum
rauschen. Ich habe 100Hz, 200Hz ... 500Hz am Zwischrenkreis mit einem
Netzteil angelegt. Manchmal wird der Minimalwert und manchmal der
Maximalwert zurückgegeben der Amplitude zurürckgegeben.
Da nix schaltet im Netzteil sind es keine schlechten ADC-Werte.
Ich vermute, dass ich irgendwo einen konzeptionellen Fehler habe. Darf
ich das Mitteln vor dem FIR nicht? Ich bin einstiger in die Signalwelt
=) Das ist meine erste FIR.
By the way: Ich habe den Code am Computer vorgetestet und da scheint es
gut zu funktionieren.
1. Läuft das denn schnell genug? Die direct form ist halt die langsamste
aller Implementierungen...
Edit: habe Punkt 2 gestrichen (rückwärts aus dem Ringbuffer lesen), denn
es ist richtig so.
Allerdings ist das glaube ich falsch:
float output_ = 0;
hier sollte das aktuelle Sample statt 0 genommen werden.
Hallo Joe, vielen Dank für dein Feedback!
Welche Implementierung ist denn schneller?
>float output_ = 0;
Du hast, recht, dass es nicht stimmt, mit der Output_=0, wenn man sich
das diagram anschaut.
https://de.wikipedia.org/wiki/Filter_mit_endlicher_Impulsantwort#/media/File:Fir_filter_cascade.png
Danke für den Hinweis, für sowas liebe ich das Forum!
Hinsichtlich meines Fehlers: Doing! Ich Idiot. Ich hatte das
runterteilen Falsch implementiert.
Ich habe das runterteilen korrigiert und in die submit value funktion
integriert. Für alle, das ist der Code, der funktioniert.
Michael H. schrieb:> Welche Implementierung ist denn schneller?
Bei 100 Taps lohnt sich mit Sicherheit der Weg über eine FFT.
Ansonsten liegt viel Geschwindigkeitspotential darin von Float auf
Fixpoint zu wechseln.
Da du deinen Algorithmus ja sinnvollerweise auf dem Desktop-Rechner
überprüfst, kannst du das Ergebnis einer Fixpoint-Implementierung direkt
mit der Float-Version vergleichen.
Alternativ könnten auch ein paar BiQuads in Reihe ausreichen.
Die haben recht wenig Rechenbedarf, und mit 3-4 Stück hintereinander
erreicht man auch eine schöne Filtersteilheit.
Ich habe die Filterkoeffizienten mal an mein Testprogramm verfüttert.
Das Ergebnis sieht eigentlich ganz gut aus. Allerdings sind das 101
Tabs.
Da mein Programm deine Abtastrate nicht unterstützt, habe ich meinen
Standardwert von 8000Hz eingesetzt, was man aber anhand der relativen
Frequenz umrechnen könnte.
>> Dann teile ich die Werte runter (Alle Werte addieren und dann Teilen)...
Das hört sich für mich nach so etwas wie "gleitendem Mittelwert" an. Je
nachdem wie der realisiert wird kann das effektiv oder eine richtige
Performancebremse sein.
Mich würde aber mal interessieren, mit welchem Algorithmus der TP
berechnet wurde bzw. welche Fensterfunktion verwendet wurde.
Michael H. schrieb:> Jetzt ist das Problem, dass ich irgendwie keine Tiefpasswirkung habe.> Gewünscht ist, dass alle Störungen ab 60 Hz durchkommen, ab 80 Hz alles> weggefiltert wird. Der FIR Filter hat 100 Taps.
Dein Filter sieht ja auch Sch... aus. Ich häng dir das mal als
Testfilter_wobble dran.
Mein Rat: berechne dir deine Filter selber, dann weißt du wenigstens,
was du kriegst. Dein Filter ist zum einen ein simpler Tiefpaß, dann
einer mit ner Grenzfrequenz von nur 25 Hz (wenn man mal 500 Hz
Samplefrequenz voraussetzt) und mit einem nicht guten Fenster.
So, ich hab dir mal zwei andere Filter drangehängt: beides Bandpässe von
so etwa 45..80 Hz bei 500 Hz Fsample.
W.S.