' schrieb:Nicht schlecht. Die FIR-Filter waren mir bisher zu undurchsichtig - zuviele gleich klingende VIs;)Aber wie ich sehe, lohnt es sich, mal einen Blick drauf zu werfen...
Es ist gar nicht so schwierig. FIR-Filter (für Punkt-zu-Punkt) sind einfach Sub-Vis mit einem nicht initialisierten Schiebregister, wobei die linke Seite entprechend der Anzahl der Koeffizienten auseinandergezogen ist. Die "Vorwärtskoeffizienten" sind die Gewichtsfaktoren, mit denen diese Werte aus der Vergangenheit zur Gesamtsumme beitragen.
Bei einer Glättung mit rechteckförmigem Mittelwert ist es besonders einfach: Alle Koeffizienten sind gleich, und die Summe muß 1 ergeben. Das Bild zeigt ein Punkt-zu-Punkt Glättungsfilter mit Halbwertsbreite 2 (= 2*2+1 Werte) (Habe es vereinfacht und nicht alle Werte einzeln mit 0.2 multipliziert).
[
attachment=9609]
Bei Halbwertsbreite 10 hat man 21 Koeffizienten mit dem gleichen Wert 1/21. Das VI zur Berechnung der Koeffizienten hätte man hier gar nicht unbedingt gebraucht, wenn die Berechnung so einfach ist. Das FIR-Filter schon, denn ein Schieberegister mit 21 auseinandergezogenen Elementen nimmt sich schon etwas komisch aus.
Vielen Dank für deine Erklärungen! Wie es der Zufall will, muss ich nächste Woche genau sowas in mein Projekt einbauen - Glättung von Messdaten... Nun kann ich mir einiges an Code sparen
Ok, noch eine Frage zu den FIR-Filtern: Ist es möglich, ein Array von Messwerten (jeweils ein Wert mehrerer Kanäle) zu filtern? Ich bräuchte dann im Prinzip mehrere Filter, die parallel laufen. Geht das? Oder fügt das FIR-VI bei einem erneuten Aufruf den Wert automatisch an die Messreihe an?
Oder gibt es einen FIR-Filter für mehrere Datenreihen?
Jetzt wo ich die Vorteile dieser Filter entdeckt habe, habe ich keine Lust mehr, das händig zu implementieren...
' schrieb:Ok, noch eine Frage zu den FIR-Filtern: Ist es möglich, ein Array von Messwerten (jeweils ein Wert mehrerer Kanäle) zu filtern?
Die Filter sind bereits "reentrant", von daher geht es schon mal. Diese Eigenschaft wird allerdings nur wirksam, wenn jedem Kanal ein eigenes Filter-Ikon zugeordnet ist. Man muß also, z.b bei 4 Kanälen mit den Einzelwerten in einem Array, innerhalb der indizierten For-Schleife noch mal eine Casestruktur mit 4 Cases für i=0,1,2,3 haben, wobei und obwohl in allen 4 Cases dasselbe Filter-Sub.vi drin ist.
Habe dazu ein Beispiel gemacht.
Ich selbst habe es aber immer anders gemacht. Für die Filterung verwende ich meist ein einfaches RC-Tiefpass-Glied, also in der Filtersprache ein "Tiefpass 1. Ordnung". Das einfache Sub-VI dazu habe ich selbst gebastelt. Darauf aufbauend, habe ich dann ein weiteres Sub-.VI für mehrkanalige Filterung gemacht.
Bin mit dem Beispiel nicht zufrieden, wie das Rücksetzen funktioniert: Der Ausgangswert sollte beim Rücksetzen den Wert des aktuellen x annehmen und nicht Null (Siehe den zweiten Kanal im Beispiel, dort verhält sich der Ausgangswert so, als ob zu Beginn ein Sprung stattgefunden hätte, was gar nicht der Fall ist)
Wenn ich Dir bei diesen Problemen weiter behilflich sein kann, melde Dich, für Dich tue ich das gern.
(VI LV 8.2)
Vielen Dank, ohne das VI dazu, hätte ich nicht verstanden, was du meinst!
Das Initialisierungsproblem ist zwar ärgerlich, aber es ist vordergründig erstmal nicht so schlimm. Viel eher hänge ich daran, dass ich eine variable Anzahl Kanäle habe. Es können also 1, 2 oder 20 sein. Ok, ich könnte jetzt 20 Cases anlegen, wenn nur 2 gebraucht werden, sind die restlichen eben umsonst...
Ich habe nur noch ein paar Verständigungschwierigkeiten bezüglich der Reentrant-VIs + nichtinitialisierte Schieberegister. Selbst, wenn ich einzelne Icons im Blockdiagramm anlege, woher weiß LV denn, welche Instanz ich gerade will? Hat jedes Icon einen internen Schlüssel, der mit übergeben wird? Und wenn der Schlüssel der selbe ist, dann wird die Instanz von letzten Mal (inklusive Schieberegister-Werten) geladen; wenn der Schlüssel verschieden ist, wird eine neue Instanz geöffnet? Dann erfolgt wohl diese Überprüfung bei nicht-reentrant VIs nicht, d.h. unabhängig vom Schlüssel wird immer die gleiche Instanz geöffnet (Prinzip funktionale globale Variable)?
Und wie können die Filter wieder zurück gesetzt werden? Folgendes Szenario: Wir führen mehrere verschiedene Tests aus, die alle in unterschiedlichen VIs liegen. Diese werden nacheinander von einem übergeordneten VI aufgerufen. Fast jeder Test benötigt einen Zugriff auf analoge In-/Outputs. Dazu existiert ein weiteres VI, was am Anfang eines Testmoduls gestartet und am Ende wieder beendet wird. Es erstellt den analogen Task, fügt eine beliebige Anzahl Kanäle hinzu und ist dann über funktionale globale Variablen zu steuern (wie z.B. "Starte Messung", "Beenden", ...). Die gemessenen Daten sollen, bevor sie über FIFOs an die Test-VIs geschickt werden, gefiltert werden. Wenn ich nun die FIR-Filter einfach dort einfüge, dann sind bestimmt beim nächsten Start des DAQ-VIs (im nächsten Test) die alten Werte noch im Filter...
Ok, das mit dem Zurücksetzen konnte ich mir selber erklären - dafür gibt's einen "Initialisieren"-Eingang am FIR-Filter.
Bleibt die Frage des prinzipiellen logischen Verständnisses
' schrieb:Ich habe nur noch ein paar Verständigungschwierigkeiten bezüglich der Reentrant-VIs + nichtinitialisierte Schieberegister. Selbst, wenn ich einzelne Icons im Blockdiagramm anlege, woher weiß LV denn, welche Instanz ich gerade will? Hat jedes Icon einen internen Schlüssel, der mit übergeben wird? Und wenn der Schlüssel der selbe ist, dann wird die Instanz von letzten Mal (inklusive Schieberegister-Werten) geladen; wenn der Schlüssel verschieden ist, wird eine neue Instanz geöffnet? Dann erfolgt wohl diese Überprüfung bei nicht-reentrant VIs nicht, d.h. unabhängig vom Schlüssel wird immer die gleiche Instanz geöffnet (Prinzip funktionale globale Variable)?
Vorweg muß ich Dir sagen, daß ich ein Hardware-Mann bin, und was grundlegende Software - Konzepte betrifft, über kein wirklich fundiertes Wissen verfüge. Also sei skeptisch, wenn ich mir anmaße über solche Dinge den Lehrer zu spielen.
Wenn man ein Sub-vi mit nicht initialisierten Schieberegistern benutzt und man will es in verschiedenen Instanzen benutzen (d.h. die Zwischenspeicherung soll getrennt erfolgen), so ist doch eine Möglichkeit die: Man kopiert das Sub-VI mehrere Male, jedes VI hat seinen eigenen Namen, und somit hat man, wenn man für jeden Kanal ein anders benanntes, aber ansonsten identisches VI verwendet, kein Probleme mehr.
Bei einem reentrantem Sub-VI stelle ich mir das ähnlich vor, d.h Ikon ist nicht gleich Ikon, sondern LV registiert, von welchem Ikon innerhalb des Haupt-VIs das Sub-VI aufgerufen wurde und verwendet für jedes Vi getrennte Speicherbereiche (und sicher nicht seperate Kopien des gesamten VI wie in der oben genannten Alternative). Mein weiteres Interesse wie es intern gemacht wird, hält sich in Grenzen - Hauptsache ich weiß wie ich es richtig benutzen kann.
Super, danke.
Ich habe es jetzt so wie von dir vorgeschlagen implementiert und einfach eine Case-Struktur mit 20 Cases (und 20 FIR-Filtern) angelegt. Ab dem 21. Kanal wird eben nicht mehr gefilter
Es läuft (wie erwartet) spitze, also wieder was geschafft...