Mittelwertbildung Strukturierter Text

mayvve

Level-1
Beiträge
2
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen

Ich steuere einen Motor an, welcher über Leistung geregelt ist. Der Bediener kann aber auch die Regelung ausschalten.
in diesem Fall werden die Drehzahlen der letzten Zeit ("mwTP_tMittelwert ") gespeichert und daraus ein Mittelwert (mwMittelwertDreh) gebildet, mit dieser der Motor in fester Drehzahl dreht.
Ich habe mich bereits ein bisschen informiert und habe es folgendermassen versucht:

Code:
    DataBuffer     :ARRAY[0..9]OF INT;
    Summe          :INT;
    IndexArray     :INT;


    tIntervall    :INT;



(*Zeitabstand Mittelwertbildung Drehzahl*)
tIntervall := mwTP_tMittelwert / 10;


(*Mittelwertbildung Drehzahl*)
TON_1(IN :=  NOT TON_1.Q, PT := tIntervall);


IF mwTP_SzDosier = 400 THEN
FOR IndexArray := 0 TO 9 DO
DataBuffer [IndexArray] := aeStromUewFU;
END_FOR
END_IF


IF TON_1.Q THEN
Summe := 0;
FOR IndexArray := 9 TO 1 BY -1 DO
DataBuffer [IndexArray] := DataBuffer [IndexArray -1];
Summe := Summe + DataBuffer [IndexArray];
END_FOR


mwMittelwertDreh := (Summe / 10);
END_IF

Bin mir aber noch nicht ganz sicher ob das funktioniert. Es gibt zehn Erfassungen in einem Array, welche dann für den Mittelwert verwendet werden.

Danke für eure Hilfe.
Lieber Gruss
mayvve
 
Was du mit "mwTP_SzDosier = 400 " vorhast will mir nicht so recht einleuchten. Aber so wie du das programmierst hast wird dein Array immer mit den gleichen Werten gefüllt sein.

Dein Timer ist soweit in Ordnung. Wenn die Regelung aktiv ist und du die Werte wegspeichern willst, dann musst du mit jeder Flanke vom Timer den Wert anur an einem bestimmten Arrayindex speichern, den Index erhöhen und für den nächsten Zyklus speichern. Darum muss dieser Index statisch im VAR Bereich liegen, und du darfst ihn dann an anderer Stelle z.B. für deinen Schleifendurchlauf zur Mittelwertbildung nicht verwenden. Anbieten würde sich eine Bezeichnung wie SchreibIndex, weil er die Position im Array angibt an der im nächsten Intervall gespeichert werden soll. Du musst den Überlauf auf den letzten Index auch noch abfangen, damit der Wert nicht außerhalb deiner Array-Größe liegt.

Den Mittelwert berechnen müsstest du auch nur einmalig wenn die Regelung ausgeschaltet wird, denn wenn die Regelung ausgeschaltet wird, möchtest du vermutlich keine neuen Werte abspeichern, sondern erst wieder wenn die Regelung aktiviert wurde.

So ungefähr
Code:
IF RegelungAktiv THEN
  IF TON_1.Q THEN // Speichern
    DataBuffer[SchreibIndex] := AktuellerWert;
    SchreibIndex := SchreibIndex + 1;
    IF SchreibIndex > 9 THEN
      SchreibIndex := 0;
    END_IF;
  END_IF;
ELSE
  // Regelung nicht aktiv, Mittelwert bilden und ausgeben
  Summe := 0;
  FOR i := 0 TO 9 DO
  // usw.

Unter Umständen sind noch weitere Dinge zu bedenken, z.B. was passiert wenn das Aufzeichnungsintervall über einen langen Zeitraum eingestellt wurde, das Array noch nicht komplett gefüllt ist und jemand die Regelung deaktiviert, werden u.U. nicht passende Werte ausgegeben. Du könntest hier nach dem Umschalten einmalig das Array mit dem aktuellen Wert füllen, oder mit einer weiteren Variable mitführen wie viele Werte schon weggeschrieben wurden o.Ä. Hängt davon ab wie wichtig diese Funktion ist.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Danke für deine Antwort.

"mwTP_SzDosier = 400" ist wann die Regelung aktiv ist, ich habe die Abfrage jetzt aber mit einer boolschen Variable definiert.
Wegen den Arrays, sollte ich für die Speicherung der Werte einen anderen Index als für die Mittelwertbildung verwenden? Array Werte Speichern: "SchreibIndex", Array Mittelwert: z.B. "MWertIndex"
Ich habe dein Code so verstanden:
Wenn Regelung aktiv, schreibe all tIntervall aktuelle Drehzahl in DataBuffer[SchreibIndex], danach zähle +1, bis 9 erreicht, dann SchreibIndex wieder auf 0 setzen.

Demnach angepasst wäre es:

Code:
IF RegelungAktiv THEN

IF TON_1.Q THEN
DataBuffer[SchreibIndex] := AktuellerWert;
SchreibIndex := SchreibIndex + 1;

IF SchreibIndex > 9 THEN
      SchreibIndex := 0;
END_IF
END_IF

ELSE

FOR MWertIndex := 0 TO 9 DO
DataBuffer [MWertIndex] := DataBuffer [MWertIndex ] + 1;
Summe := Summe + DataBuffer [MWertIndex];
END_FOR

DataBuffer[0] := aeUewFU;
Summe := Summe + aeUewFU;
mwMittelwertDreh := (Summe / 10);

END_IF

Wenn lange nicht aufgezeichnet wurde, würde ich nach dem Umschalten die aktuellen Werte einfügen, wäre es in diesem Fall in das SchreibIndex Array?

LG mayvve
 
Denke daran das TON_1.Q immer nur als Flanke ausgewertet werden darf, sonst wird in jedem Zyklus solange wie TON_1.Q TRUE ist der aktuelle Wert eingetragen.

Vielleicht:
Code:
IF TON_1.Q AND NOT P_Trig_old AND RegelungAktiv THEN // positive Flanke sowie RegelungAktiv abfragen.
[...]
// Programmteil
[...]
END_IF
P_Trig_old := TON_1.Q;


Wenn Du es füllen willst, so könnte man innerhalb der Schleife eine Abfrage machen die Fuellen abfragt und dann mit dem aktuellen Wert alles vorbelegen.
Code:
IF Fuellen THEN
      DataBuffer[MWertIndex] := Fuellwert; // wenn Füllen den Füllwert auf alle schreiben
END_IF


Welches Schreibindex-Array meinst Du? Es gibt doch nur das eine Array "DataBuffer".

Prinzipiell könnte man das alles in einer Schleife erledigen, dann entfällt der Schreibindex und die Schleifenvariable würde den Index darstellen. Wäre aber nur wichtig wenn Speicherplatz eng werden könnte.
 
Zurück
Oben