Werte beruhigen

Draco Malfoy

Level-1
Beiträge
1.168
Reaktionspunkte
82
Zuviel Werbung?
-> Hier kostenlos registrieren
Moin zusammen.

Ich möchte sehr gerne einen halb-analogen Wert beruhigen, der mir noch zu sehr schwankt bzw. teilweise auch richtig heftige Ausschläge zeigt, die nicht ins Messergebnis passen.
Ich habe dabei entweden an einen gleitenden Mittelwertfilter gedacht, oder an einen Tiefpass (1.er Ordnung, 2.er Ordnung ?? N-ter Ordnung ?) Grundlage sind jeweils OSCAT-Bausteine.

Die Werte werden je 150mS abgefragt also etwa 6 mal pro Sekunde eingelesen. Wie müsste ich jetzt sinnvollerweise die Glättungszeit und die Glättungskonstanten (K1, K2..) wählen ?
Wie kommt man am schnellsten zu den optimalen Einstellungen ?


Thanx im Voraus!
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Wie wäre es mit einem FIFO und darauf aufgesetzen Median?
Habe ich auch schon überlegt. Würde denn aber ein Tiefpass tendenziell nicht genau solche einzelstehende Spitzen ausfiltern können ?
...P.S. Die Implementierung von FIFO im Verbund mit Median ist mir jetzt auch noch nicht so ganz geläufig
 
Mal eine Strategie kurz angedeutet:

Nimm jeweils die letzten n Werte, bilde den Mittelwert M1, werfe die Extrema (die x Werte, die am meisten vom Mittel M1 abweichen) fort, bilde über die verbleibenden Werte das Mittel M2. Das kannst Du auch rekursiv machen.

M2 ist Dein beruhigter Wert. Die Anzahl der weggelassenen x Extremwerte kannst Du nur durch Ausprobieren optimieren. Das Ganze ist dann ein modifizierter Tiefpass, der durch die Anzahl n bestimmt wird.

Natürlich ist diese Sache eine Beschönigung, man müsste zuerst einmal versuchen, zu ergründen, woher die Ausreisser stammen!

Wenn die Quelle schon nichts taugt, dann wird die Auswertung nicht unbedingt besser.
 
Wenn die Quelle schon nichts taugt, dann wird die Auswertung nicht unbedingt besser.
Die Quelle taugt nichts, aber seitens des AG kam die Aufforderung diese zu implementieren. Von daher...
Außerdem - naja was heißt heftige Ausreißer. Wir haben z.B. einen exacten Wert (nach der Linearisierung) der bei 380 liegt. Jetzt geht er teilweise runter auf 370 und hoch bis 390, aber nicht in einem Peak, sondern er "krabbelt" sich da so lustig hoch und runter und schwankt dabei immer um 2-3 Einheiten. Wenn man dieses feine Zittern wegnehmen würde, wäre ja möglicherweise schon etwas gewonnen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Gegen so einen Drift wird es schwer mit einem Filter anzugehen ohne die gewollte Signaländerungen zu sehr zu verzerren. Hochfrequente Schwankungen mit geringer Amplitude bekommst du aber idR schon über wenig Messwerte gut herausgemittelt. Manche Steuerungshersteller haben auch schon in den Analogeingangskarten Filter integriert, die man nach Bedarf aktivieren kann, vlt. gibt es das bei dir auch?
 
Hochfrequente Schwankungen mit geringer Amplitude bekommst du aber idR schon über wenig Messwerte gut herausgemittelt. Manche Steuerungshersteller haben auch schon in den Analogeingangskarten Filter integriert, die man nach Bedarf aktivieren kann, vlt. gibt es das bei dir auch?
Die Werte werden aber nicht über eine analoge Karte eingelesen sondern per RS-232 Interface. Die Sachlage ist da leider etwas komplexer. Steuerung is ne normale S7-416 mit abgesetzten I/O s sprich ET200S.
Welche Werte des Filtes (und welchen Filters ? FILTER_I, FT_PT1, Gleitender Mittelwert ?) würdest Du zu Beginn veranschlagen um das hochfrequente Zittern zu unterdrücken ?
 
Hier ist ein schöner EA-Filter:

Code:
FUNCTION_BLOCK "Filter_AA"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
   VAR_INPUT 
      IN : Real;
      V_IN : Real;
   END_VAR

   VAR_OUTPUT 
      OUT : Real;
   END_VAR

   VAR 
      V : Real;
   END_VAR


BEGIN
    
    
    
    #V:=#V_IN;
      IF #IN = #OUT THEN
        #V:=0.0;
      ELSIF #IN<#OUT THEN
        #OUT:= LIMIT(MN:=0.0,IN:=#OUT-MIN(IN1:=#V,IN2:=#OUT-#IN),MX:=100.0);
      ELSIF #IN>#OUT THEN
        #OUT:= LIMIT(MN:=0.0,IN:=#OUT+MIN(IN1:=#V,IN2:=#IN-#OUT),MX:=100.0);
      END_IF;
      
    
    
END_FUNCTION_BLOCK
 
Habe ich auch schon überlegt. Würde denn aber ein Tiefpass tendenziell nicht genau solche einzelstehende Spitzen ausfiltern können ?
...P.S. Die Implementierung von FIFO im Verbund mit Median ist mir jetzt auch noch nicht so ganz geläufig

Mir ist dafür der Tiefpass hier nicht so geläufig ;)

Ich habe so eine ähnliche Problemstellung so gelöst.
Code:
FUNCTION_Block WM_gleit_MedianTITLE = '_MEDIAN'
(* Diese Funktion gibt den Median aus bis zu 200 aufgezeichneten Gleitpunktwerten aus 
   V1.0 Abgegebene Version
 *)


VERSION : '1.0'
AUTHOR  : VoR
NAME    : Med_R
FAMILY  : FunkB


VAR_INPUT
 MW : REAL; // Windmesswert.
 Takt : BOOL; // Trigger um Messwert einzlesen. Reagiert auf steigende Flanke
 Anz : INT; // Anzahl Messwerte aus denen der Median gebildet wird.


END_VAR
VAR
 rwert : ARRAY[1..200] OF REAL; // Array für FIFO
 rwert_sort : ARRAY[1..200] OF REAL; // Array für Sortierung
 rMedian : REAL; 
 getauscht : BOOL;
 zw: REAL;
 i: INT;
 anzahl_save : INT;
 TAKT_ZM : BOOL;
    Onimp : BOOL;
    Onimpmem : BOOL;
END_VAR
VAR_OUTPUT
  median: REAL;
END_VAR




BEGIN
IF Anz < 3 THEN // Sicherstellen das index für FOR Schleife mindestens eine drei enthält.
    anzahl_save := 3;
ELSE
    anzahl_save := Anz;
END_IF;


Onimp :=  Takt AND NOT Onimpmem;
    Onimpmem := Takt;




IF onimp THEN // nur beim Takt ausführen
    FOR i := anzahl_save TO 2 BY -1 DO
        rwert[i] := rwert[i - 1];
    END_FOR;
        rwert[1] := MW;
END_IF;


    rwert_sort := rwert; // kopieren zum sortieren


(* Bubblesort Algoritmus sortiert aufsteigend das Array rwert (geschwindigkeit)
   und kopiert die irtg (windrichtung) die dazugehören gleich mit *) 
REPEAT
  getauscht := false; // tauschmerker
      FOR i := anzahl_save TO 2 BY -1 DO
          IF rwert_sort[i-1] > rwert_sort[i] THEN // tauschen
            zw := rwert_sort[i];
            rwert_sort[i] := rwert_sort[i-1];
            rwert_sort[i-1] := zw;
            getauscht := true;
          END_IF;
      END_FOR;
  UNTIL NOT getauscht
END_REPEAT;




   
// median auswählen    
median := rwert_sort[anzahl_save/2]; // den wert aus der Mitte der Anzahl werte nehmen. Wurden sortiert


END_FUNCTION_BLOCK

Das ist der Ursprungsbaustein. Das sortierte Array muss also nicht im Stat bereich stehen. ausserdem werden noch nicht gefüllte Zellen nicht ausgefiltert. Aber die Grundsätzliche Funktion ist gegeben. Vielleicht hilft dir das schon weiter.

mfG René
 
Zuletzt bearbeitet:
In diesem Fall ist mein Messwerbeich von 0 bis 100 %, du kannst dein Messbereich natürlich anpassen.
Ich hab's mit analogen Eingangssignalen getestet, funktioniert wunderbar. Der Nachteil hierbei ist, dass der Filter in einem Weckalarm ob wie z. B. 100ms OB aufgerufen werden sollte.
V_IN ist das die "Geschwindigkeit deines Filters. In dem Fall wenn für du für V_IN eine 2 einstellst, hast du 20 digits in einer Sekunde. Bei einem Sprung von 0 auf 100 wäre der Ausgangswert in 5 Sekunden ausgeglichen.
Den Paramter V_IN kannst du dann wärend einer Inbetriebnahme schnell anpassen.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
In diesem Fall ist mein Messwerbeich von 0 bis 100 %, du kannst dein Messbereich natürlich anpassen.
Ich hab's mit analogen Eingangssignalen getestet, funktioniert wunderbar. Der Nachteil hierbei ist, dass der Filter in einem Weckalarm ob wie z. B. 100ms OB aufgerufen werden sollte.
V_IN ist das die "Geschwindigkeit deines Filters. In dem Fall wenn für du für V_IN eine 2 einstellst, hast du 20 digits in einer Sekunde. Bei einem Sprung von 0 auf 100 wäre der Ausgangswert in 5 Sekunden ausgeglichen.
Den Paramter V_IN kannst du dann wärend einer Inbetriebnahme schnell anpassen.
Interessant. Is an sich so auch kein schlechtes Konzept. Ich werde mal morgen beide Varianten ausprobieren (und FT_P1 noch dazu) und gebe dann eine Rückmeldung ab.
... Noch so n Gedanke der mir gerade kommt: Analogwerte zur Linearisierung und Ausfilterung sollten generell in REAL oder DINT angeboten werden. Sehe immer wieder als Schnittstellenbeschreibung der Sensorik WORD, INT, STRING (!) wodrin dann CHARs stehen, die mir hexadezimale Zeichen abbilden. Wer programmiert bitte sowas ??
 
Ich benute immer die Siemensfunktion SCALE (bei 1500er CPU's). Als Eingang habe ich dann einen INT und Ausgang natürlich einen REAL. Was anderes würde ich nicht nehmen.
 
Beispiel:

Code:
#fehlercode_fuellstand:=SCALE(IN:=#LIS,HI_LIM:=100.0,LO_LIM:=0.0,BIPOLAR:=false,OUT=>#Fuellstand);

LIS ist eine temproräre Integer Variable die einem analogeingang gleichgesetzt wird:
LIS:=%EW256;
Fuelstand ist von Typ REAL
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Ja ich meine, wenn die Sensorik an sich schon irgendwas sehr seltsames ausgibt, muss man das 5 mal wandeln, bevor man die Werte überhaupt verarbeiten kann. Egal, ist ein anderes Thema.
 
Hi!

Was hast du denn für ein Automatisierungssystem?
Beim großen S kann man in der Hardwarekonfiguration den Filter entsprechend einstellen.

Gruß,

Ottmar
 
Hallo
du verwendest ja die Oscat-Lib, ich verwende die Bausteine SH_1 und FT_AVG, das funktioniert bei meiner Wago sehr gut.
 
Das Teil von Sanjo filtert erstmal überhaupt nicht, sondern ist nur eine Begrenzung der Anstiegsgeschwindigkeit. Sowas lässt sich benutzen um z.B. eine Sollwertänderung stetig und nicht schlagartig auf einen Regler zu geben. Um einen Wert zu filtern in der Art wie man es von einem Tiefpass erwarten würde ist es nicht brauchbar.

Der Code von Aventinus ist ein PT1-Filter, d.h. ein Tiefpass erster Ordnung. Bei den Oscat-PT1 Filtern hängt die Grenzfrequenz vom Aufrufzyklus ab, siehe hier:
http://www.sps-forum.de/simatic/70496-pt1-glied-2.html#post489053
 
Zurück
Oben