Zuviel Werbung? - > Hier kostenlos beim SPS-Forum registrieren

Ergebnis 1 bis 7 von 7

Thema: Mittelwert Bildung - CoDeSys 2

  1. #1
    Registriert seit
    08.12.2014
    Beiträge
    14
    Danke
    5
    Erhielt 0 Danke für 0 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Hallo da draußen,
    ich haben einen Messwert, der sehr schwank.
    Nun möchte ich, diesen Wert eine Stunde lang, mit einem Intervall von 2 Sekunden, mitteln.
    Wie bekomme ich das mit CoDeSys 2 am besten hin ???

    Danke für die Hilfe
    Zitieren Zitieren Mittelwert Bildung - CoDeSys 2  

  2. #2
    Registriert seit
    26.11.2012
    Ort
    Gummersbach
    Beiträge
    502
    Danke
    18
    Erhielt 71 Danke für 69 Beiträge

    Standard

    guten Morgen,

    ich verstehe die Aufgabenstellung so, das Du eine Anzeige von Messwerten realisieren möchtest, die 1h Historie bereithält. Abtastrate der gemittelten Messwerte soll 2s sein?

    Also für die Messwerterfassung einen Task anlegen, der mit einem definierten Intervall den Eingang erfasst (z.B. 500ms)
    Mit einer Schleife die Werte in Variablen "wegschreiben"
    Wenn Schleife einmal "rum" ist (in meinem Fall nach 4 gespeicherten Werten) die Mittelwertbildung triggern (Summe der Messwerte/Anzahl der Messwerte)
    Den so erhaltenen Wert in ein Array wegschreiben und Array-Pointer auf nächste Adresse setzen.
    Wenn das Array nun 60 Einträge umfasst hast du 1h Historie.

    Ich hoffe das hilft schonmal als Denkanstoß

    Gruß


    Christian
    Ganz kurz ganz hell
    ganz lange ganz dunkel....

  3. #3
    Registriert seit
    10.08.2012
    Beiträge
    245
    Danke
    0
    Erhielt 70 Danke für 66 Beiträge

    Standard

    Stichwort fliessender Gleitpunkt!

    Die Mathematik sagt für einen fliessenden Gleitpunkt (Arrays, das kostet bei vielen Stützpunkten viel Rechenleistung).
    x: aktueller Messpunkt
    x_fl: Fliessender Gleitpunkt
    x_fl_old: Fliessender Gleitpunkt beim letzten (zeitlich äquidistanter) Aufruf
    n: Anzahl der Stützstellen und somit zeitliche Fenster


    x_fl := (x + (n-1)*xfl_old)/n ;

  4. #4
    Registriert seit
    26.11.2012
    Ort
    Gummersbach
    Beiträge
    502
    Danke
    18
    Erhielt 71 Danke für 69 Beiträge

    Standard

    Ja, guter Einwand - diese Lösung gibt aber (erstmal) nur den aktuellen fließenden Gleitpunkt zurück - eine History müsste man dann immer noch "dazubasteln"

    Auch die Rechenleistung ist ein berechtigter Einwand, da uns aber keine Informationen vorliegen über die verwendete Hardware bzw. die weiteren Aufgaben der SPS hielt ich es als denkanstoß für legitim.


    Warten wir mal ab, was der Themenstarter dazu sagt bzw. ob wir seine Aufgabenstellung getroffen haben...

    gesendet von meinem Moto G mit Tapatalk
    Ganz kurz ganz hell
    ganz lange ganz dunkel....

  5. #5
    Registriert seit
    16.03.2014
    Beiträge
    358
    Danke
    74
    Erhielt 45 Danke für 38 Beiträge

    Standard

    Hi,
    da ich etwas ähnliches benötigte, habe ich mein Beispiel mal hier gepostet.
    Ist als mögliche Basis ggf. erweiterbar.
    Jedoch, wie die vorhergehenden Schreiber schon sagten, es ist ggf. sehr Resourcenintensiv:
    alle 2 s für eine h = 60/2 * 60 = 1800 Werte um eine h rollierend zu behalten...

    Vile Erfolg
    Shrimps
    Code:
    FUNCTION_BLOCK _fbAVG_INT16
    VAR_INPUT
        iSignal    : INT;    (* Eingangswert *)
        tZeit    : TIME := t#8s;    (* Abtastzeit gesamt *)
    END_VAR
    VAR_OUTPUT
        iAVG    : INT;    (* Der Mittelwert *)
    END_VAR
    VAR
        Timer     : TON;    (* Timer *)
        tTakt    : TIME;    (* 1/16 von tZeit *)
        iData     : ARRAY [0..15] OF INT;    (* Die Daten *)
        Summe    : DINT;    (* Summenzaehler *)
        Index    : INT;    (* Index für Array *)
        init    : BOOL := TRUE;    (* Start *)
    END_VAR
    (* FB ermittelt einen gleitenden Mittelwert aus *)
    (* 16 Integerwerten welche in einem vorgebbaren *)
    (* Zeitinterval als FIFO gespeichert werden *)
    IF init THEN
        FOR Index := 0 TO 15 DO
            iData[Index] := iSignal;
        END_FOR
        init := FALSE;
        iAVG := iSignal;
    END_IF
    
    tTakt := tZeit / 16;
    
    Timer(IN := NOT Timer.Q, PT := tTakt);
    
    IF Timer.Q THEN
        Summe := 0;
        FOR Index := 15 TO 1 BY -1  DO
            iData[Index] := iData[Index - 1];
            Summe := Summe + iData[Index];
        END_FOR
        iData[0] := iSignal;
        Summe := Summe + iSignal;
        iAVG := DINT_TO_INT(summe / 16);
    END_IF

  6. #6
    Registriert seit
    04.09.2012
    Beiträge
    54
    Danke
    4
    Erhielt 7 Danke für 7 Beiträge

    Standard

    Nach der obigen Formel würde das fertige Programm dann so aussehen:

    PROGRAM MAIN
    VAR
    x:REAL;(*aktueller Messpunkt*)
    x_fl:REAL;(*Fließender Gleitpunkt*)
    n:INT:=1;
    ton1: TON;
    rBuffer:ARRAY[0..1800]OF REAL;(*x_fl_old Fließender Gleitpunkt beim letzten Aufruf*)
    n1: INT;
    END_VAR

    ton1(pt:=t#2s, in:=NOT ton1.Q);
    IF ton1.Q THEN
    rBuffer[n]:=x_fl;
    IF n<>0 THEN (*div 0 verhindern*)x_fl:=(x+(n-1)*rBuffer[n])/n;END_IF
    n:=n+1;
    IF n>1800 THEN
    n:=1800;
    rBuffer[0]:=rBuffer[1800];
    FOR n1:=1800 TO 1 BY -1 DO
    rBuffer[n1]:=rBuffer[n1-1];
    END_FOR
    END_IF
    END_IF

  7. #7
    Registriert seit
    29.06.2015
    Beiträge
    33
    Danke
    2
    Erhielt 7 Danke für 6 Beiträge

    Standard


    Zuviel Werbung?
    -> Hier kostenlos registrieren
    Mit folgendem Baustein hab ich das in meinem Projekt gelöst. Da kann man einfach den aktuellen Messwert reinwerfen, den Mittelwert ausgeben sobald ausreichend Messwerte eingegangen sind. i Gibt die Anzahl der Durchläufe zurück. Bei mir wurde jeder Zyklus gemessen. Das müsste man dann noch anpassen.
    Code:
    FUNCTION_BLOCK
    VAR_INPUT	fActWert: REAL;
    	fAnzahlWerte: REAL;
    	xEnable: BOOL;
    END_VAR
    VAR_OUTPUT
    	fMEANOK: REAL;
    	bDone: BOOL;
    END_VAR
    VAR
    	fMEAN: REAL;
    	i: INT;
    	EnableTrig: R_TRIG;
    	fweight: REAL;
    END_VAR
    Code:
    bDone:=FALSE;
    fMEAN:=(1.0 - fweight) * fMEAN + fweight * fActWert;		//Gleitende Mittelwertbildung
    
    
    EnableTrig(CLK:=xEnable);
    
    
    IF EnableTrig.Q THEN
    	i:=0;
    	fMEAN:=0;
    	fweight:= 1.0 / fAnzahlWerte;
    END_IF
    
    
    i:=i+1;
    
    
    IF xEnable AND i> fAnzahlWerte THEN
    	bDone:=TRUE;
    	fMEANOK:=fMEAN;
    END_IF

Ähnliche Themen

  1. Sonstiges Erklärung AVERAGE ( Mittelwert ) Baustein
    Von chipchap im Forum Simatic
    Antworten: 9
    Letzter Beitrag: 31.10.2014, 10:35
  2. Bildung eines Zählers aus Analogsignal
    Von shrek23 im Forum CODESYS und IEC61131
    Antworten: 1
    Letzter Beitrag: 12.10.2014, 13:21
  3. Wieder Multiinstanz... Mittelwert Bildung
    Von c.wehn im Forum Simatic
    Antworten: 5
    Letzter Beitrag: 25.10.2012, 10:43
  4. mittelwert berechnung
    Von candemirkorkmaz im Forum Sonstige Steuerungen
    Antworten: 1
    Letzter Beitrag: 27.07.2011, 13:11
  5. Ringpuffer mit Mittelwert
    Von taucherd im Forum Simatic
    Antworten: 28
    Letzter Beitrag: 19.05.2011, 23:30

Stichworte

Lesezeichen

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •