FOR z := 1 TO AbtastWerte BY 1 DO

tkopf

Level-1
Beiträge
2
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Das Porg. Speichert alle x sec. ein Wert ab. Das Array ist auf 0..10 gesetzt
Wenn die Abtastzeit abgelaufen ist dann Summiere auf und teile durch die AbtastWerte.

Das funktioniert mit dem Prog. (*A*) wunderbar.

Nehme ich stattdessen eine FOR Schleife, also ich nutze Prog. (*B*) dann wird mehr aufsummiert und der Mittelwert läuft langsam hoch.

Kann mir jemand sagen was das Problem ist.?


Hier noch das ganze Programm:


(*
Gleitende- Mittelwertbildung über x Zeiteinheiten zb. ms und über x (max 10) Werte.
Hinweise:
AbtastWerte min 1 - max 10 weil von Hand auf Array Werte[ 10 ]
Abtastzeit time#5s
*)


TON_1( i, Abtastzeit );


If TON_1.Q = TRUE THEN; (*wenn Zeit abgelaufen dann schreibe Wert auf die Zelle X*)
Werte[Zaehler] := IstWerte;
Zaehler := Zaehler + 1; (*erhöhe Laufindex*)
i := FALSE; (**)
END_IF;


If TON_1.Q = FALSE THEN; (*wenn Zeit abgelaufen dann i=1*)
i := TRUE;
END_IF;


IF AbtastWerte = Zaehler THEN (*wenn Inhalt von AbtastWerte = Zaehler neustart*)
Zaehler := 0;
END_IF;


(*A*)
(*Mittelwertbildung über die AbtastWerte 0...X *)
IF i = TRUE THEN (*wenn Abtastzeit abgelaufen dann rechne *)

AbtastWerteREAL := ANY_TO_REAL (AbtastWerte); (* konvertiere nach REAL*)

Summe := Werte[0]+Werte[1]+Werte[2]+Werte[3]+Werte[4]+Werte[5]+Werte[6]+Werte[7]+Werte[8]+Werte[9] ;

Mittelwert := Summe / AbtastWerteREAL;
END_IF;


(*B*)
(*-----------------------------------------------------------------------------------------------------*)
IF i = TRUE THEN (*wenn i dann rechne *)

FOR z := 0 TO AbtastWerte BY 1 DO

Summe := Summe + Werte[ z ];
END_FOR;
AbtastWerteREAL := ANY_TO_REAL (AbtastWerte); (* konvertiere nach REAL*)

Mittelwert := Summe / AbtastWerteREAL ;

END_IF;
 
Moin tkopf,

eigentlich ganz einfach:

summe := summe + Werte[z]; // hast Du summe mit 0 initialisiert? Also vor der FOR-Schleife auf 0 gesetzt?

ist summe eine temporäre oder globale Variable?
Ich denke mal es handelt sich um eine globale Variable?

globale Variable ohne Initialisierung auf 0: der letzte Wert der globalen Variablen ist der neue Startwert...
temporäre Variable ohne Initialisierung auf 0: bei Start der FOR-Schleife kann in der temporären Variablen irgend ein Quatsch drin stehen.

Da Du sagst, dass der Wert immer weiter ansteigt, gehe ich von eine globalen Variablen aus.

ALSO:
Code:
[COLOR=#333333]IF i = TRUE THEN (*wenn i dann rechne *)[/COLOR]

[B]Summe := 0; // Initialisieren[/B]

[COLOR=#333333]FOR z := 0 TO AbtastWerte BY 1 DO[/COLOR]

[COLOR=#333333]Summe := Summe + Werte[ z ];[/COLOR]
[COLOR=#333333]END_FOR;[/COLOR]
[COLOR=#333333]AbtastWerteREAL := ANY_TO_REAL (AbtastWerte); (* konvertiere nach REAL*)[/COLOR]

[COLOR=#333333]Mittelwert := Summe / AbtastWerteREAL ;[/COLOR]

[COLOR=#333333]END_IF;[/COLOR]

VG

MFreiberger
 
Zuviel Werbung?
-> Hier kostenlos registrieren
...(*B*)
IF i = TRUE THEN (*wenn Abtastzeit abgelaufen dann rechne *)
-->Summe:=0;
FOR z := 0 TO AbtastWerte BY 1 DO
Summe := Summe + Werte[ z ];

da nicht sichergestellt ist, dass Variable Summe = 0 ist, muss Summe auf null gesetzt werden.....
 
Danke für die schnelle Reaktion:
ok ihr habt recht, Inhalt der Variabel „Summe“ :=0 setzen, dann läufts mit FOR schleife.


Die SPS ist
https://ab.rockwellautomation.com/de/Programmable-Controllers/Micro810


Der Baustein ist ein UDFB und wird mehrfach an anderen Stellen aufgerufen.
Die Variabel „Summe“ ist dann eine local Variable
Wieso funktioniert das dem Prog. (*A*), dort wird doch vorher auch nicht „Summe“ :=0
und dennoch kommt der richtige Mittelwert.
 
Moin tkopf,

weil Du bei (*A*) als erstes 'Summe' einen Wert zuweist:

Code:
[COLOR=#333333]Summe := Werte[0]+Werte[1]+Werte[2]+Werte[3]+Werte[4]+Werte[5]+Werte[6]+Werte[7]+Werte[8]+Werte[9] ;[/COLOR]

in (*B*) fragst Du den Wert von 'Summe' als erstes ab:

Code:
[COLOR=#333333]Summe := [B]Summe [/B]+ Werte[ z ];[/COLOR]

Also bei (*A*) rechnest Du mit dem, was Du in DIESEM Zyklus an Werten hast, in (*B*) beginnst Du mit dem zu rechnen, was Du im LETZTEN Zyklus an Werten hast.


VG

MFreiberger
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Wieso funktioniert das dem Prog. (*A*), dort wird doch vorher auch nicht „Summe“ :=0
und dennoch kommt der richtige Mittelwert.
Weil der Wert von Summe da in die Berechnung nicht mit eingeht, Summe ist rein das Ergebnis:
Summe := Werte[0]+Werte[1]+Werte[2]+Werte[3]+Werte[4]+Werte[5]+Werte[6]+Werte[7]+Werte[8]+Werte[9] ;

In der Schleife wird aber im ersten Durchlauf der vor der Schleife in Summe vorhandene Wert addiert.
Anstatt Summe := 0; könnte man auch schreiben:
Code:
Summe := Werte[0];
FOR z := 1 TO 9 DO
  Summe := Summe + Werte[z];
END_FOR;

Harald
 
Code:
(*A*)
[COLOR=#0000ff]Summe[/COLOR] := Werte[0]+Werte[1]+Werte[2]+Werte[3]+Werte[4]+Werte[5]+Werte[6]+Werte[7]+Werte[8]+Werte[9] ;

(*B*)
[COLOR=#ff0000]Summe[/COLOR] := [COLOR=#ff0000]0[/COLOR];
FOR z := 0 TO AbtastWerte DO
[COLOR=#ff0000]   Summe[/COLOR] := [COLOR=#ff0000]Summe[/COLOR] + Werte[ z ];
END_FOR;

*A* wird immer vollständig neu berechnet
*B* verwendet immer die Summe vom vorigen Zyklus

PS: die kürzeste Erklärung hatte am längsten gebraucht... :rolleyes:
 
Zuletzt bearbeitet:
Nur der Vollständigkeit halber: statt ...
Summe := Werte[0]+Werte[1]+Werte[2]+Werte[3]+Werte[4]+Werte[5]+Werte[6]+Werte[7]+Werte[8]+Werte[9] ;
... könnte man auch überflüssigerweise schreiben ...
Summe := 0 ;
Summe := Summe+Werte[0]+Werte[1]+Werte[2]+Werte[3]+Werte[4]+Werte[5]+Werte[6]+Werte[7]+Werte[8]+Werte[9] ;
... nur, damit's vergleichbarer wird mit der SchleifenVariante.
Bzw. in Analogie zu Haralds SchleifenVariante:
Summe := Werte[0] ;
Summe := Summe+Werte[1]+Werte[2]+Werte[3]+Werte[4]+Werte[5]+Werte[6]+Werte[7]+Werte[8]+Werte[9] ;
 
Zurück
Oben