Werte im array verschieben

fiftyone_88

Level-1
Beiträge
23
Reaktionspunkte
0
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo miteinander, ich habe einen array mit 10 Plätzen und möchte, das der aktuelle wert immer auf dem ersten Platz ist und die restlichen sich um einen verschieben.

Beispiel:

Programmstart, erster Wert ist 1
2ter Durchlauf, aktueller Wert ist 2
.
.
10ter Durchlauf, aktueller Wert ist 10

Also beim Programmstart: 1,0,0,0,0,0,0,0,0,0,0

2ter Durchlauf: 2,1,0,0,0,0,0,0,0,0,0

10ter Durchlauf: 10,9,8,7,6,5,4,3,2,1

Beim 11ten nehmen wir mal an, der aktuelle Wert sei 5 dann sollte es so aussehen: 5,10,9,8,7,6,5,4,3,2

Ich habe es so geschrieben geht das?

FOR i:=1 TO 9 BY 1 DO vMerker[i+1]:=vMerker; END_FOR; (*verschiebt den ersten wert auf den zweiten usw*)
vMerker[1]:=v; (*aktueller wert wird auf den ersten geschrieben*)

Geht das so? Oder würde beim ersten Durchlauf der Schleife der 1te Wert auf den 2ten geschrieben werden und beim zweiten Durchlauf der 2te Wert auf den 3ten? Das würde ja bedeuten, das er alle plätze mit dem 1ten wert füllt oder?


Dann möchte ich den Mittelwert des array Werte bilden.

FOR i:=1 TO 10 BY 1 DO sumMerker:=sumMerker+vMerker; END_FOR; (*zählt alle zsm*)
vMittelwert:=sumMerker*0.1;(*summe wird durch 10 geteilt*)

Ich bedanke mich schonmal für eure Hilfe.
 
Ich habe es so geschrieben geht das?

FOR i:=1 TO 9 BY 1 DO vMerker[i+1]:=vMerker; END_FOR; (*verschiebt den ersten wert auf den zweiten usw*)
vMerker[1]:=v; (*aktueller wert wird auf den ersten geschrieben*)

Geht das so? Oder würde beim ersten Durchlauf der Schleife der 1te Wert auf den 2ten geschrieben werden und beim zweiten Durchlauf der 2te Wert auf den 3ten? Das würde ja bedeuten, das er alle plätze mit dem 1ten wert füllt oder?
Letzteres.

Du musst demzufolge mit dem Verschieben im Array hinten anfangen:
Code:
[COLOR=#333333]FOR i:= 9 TO 1 BY -1 DO
[/COLOR]    [COLOR=#333333]vMerker[i+1]:= vMerker[i];
END_FOR;[/COLOR]
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Dann möchte ich den Mittelwert des array Werte bilden.

FOR i:=1 TO 10 BY 1 DO sumMerker:=sumMerker+vMerker; END_FOR; (*zählt alle zsm*)
vMittelwert:=sumMerker*0.1;(*summe wird durch 10 geteilt*)
Hier solltest Du vor der FOR-Schleife die Variable sumMerker noch sicherheitshalber auf 0 setzen, sonst könnte im 2. Programmdurchlauf noch die Summe des 1. Durchlaufs drin stehen und mit zu den 10 aktuellen Werten addiert werden.
Hängt von der Deklarierung von sumMerker ab.
 
Hier solltest Du vor der FOR-Schleife die Variable sumMerker noch sicherheitshalber auf 0 setzen, sonst könnte im 2. Programmdurchlauf noch die Summe des 1. Durchlaufs drin stehen und mit zu den 10 aktuellen Werten addiert werden.
Hängt von der Deklarierung von sumMerker ab.

zu beiden antworten vielen dank, ja sumMerker setze ich nach dem der mittelwert berechnet wurde auf 0
 
Damit die Berechnung auch beim ersten Mal bzw. immer garantiert korrekt ist solltest Du sumMerker VOR der Berechnung auf 0 setzen.

Harald
 
Damit die Berechnung auch beim ersten Mal bzw. immer garantiert korrekt ist solltest Du sumMerker VOR der Berechnung auf 0 setzen.

Harald


eine frage noch, und zwar wenn ich ein 10 min mittelwert bilden möchte, kann ich das dann so machen:

zehnminTakt.PT:=T#600s;
zehnminTakt.IN:=NOT zehnminTakt.Q;
IF (zehnminTakt.Q=FALSE)
THEN zehnminSumme:=zehnminSumme+v; z:=z+1;
ELSE v10Mittelwert:=zehnminSumme/z; zehnminSumme:=0;
END_IF;
 
Um ganz sicher zu gehen initialisiert man Variablen trotzdem VOR der Verwendung. :cool:
Außerdem könntest Du die Variable durch eine temporäre Variable ersetzen und dann MUSST Du sie vor der Verwendung initialisieren.

Harald
 
Zuviel Werbung?
-> Hier kostenlos registrieren
eine frage noch, und zwar wenn ich ein 10 min mittelwert bilden möchte, kann ich das dann so machen:

zehnminTakt.PT:=T#600s;
zehnminTakt.IN:=NOT zehnminTakt.Q;
IF (zehnminTakt.Q=FALSE)
THEN zehnminSumme:=zehnminSumme+v; z:=z+1;
ELSE v10Mittelwert:=zehnminSumme/z; zehnminSumme:=0;
END_IF;

Ja so kannst du einen Mittelwert über die letzten 10 Minuten bilden. Du erhälst aber nur alle 10 Minuten einen neuen Wert, wenn dir das reicht....
Ansonsten befasse dich mal mit dem Thema "gleitender Mittelwert". Ich denke dazu findest du hier im Forum auch schon die ein oder andere Lösung.
 
Ja so kannst du einen Mittelwert über die letzten 10 Minuten bilden. Du erhälst aber nur alle 10 Minuten einen neuen Wert, wenn dir das reicht....
Ansonsten befasse dich mal mit dem Thema "gleitender Mittelwert". Ich denke dazu findest du hier im Forum auch schon die ein oder andere Lösung.

ok danke. ja den gleitenden mittelwert bilde ich mit den letzten 10 werten (ganz am anfang des threads) diesen 10 min mittelwert brauche ich für ein histogramm, das system soll theoretische jahrelang laufen, und alle 10 min mitteln.
 
(*..geht wieder über den Timer..*)

VAR
minTimer:ton;
end_var

minTimer(PT:=t#1m);
minTimer.IN:=not minTimer.Q;

IF minTimer.Q THEN
(*hier packst Du die FOR.. ..END_FOR Sachen rein*);
END_IF
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hi,
warum verwendest Du nicht einen Ringpuffer anstatt jedesmal das komplette Array zu kopieren?
Das mag bei 10 Werten keine große Sache sein, aber wenn das Array mal größer sein sollte...

Code:
Index := (Index MOD 10) + 1;
vMerker[Index] := v;
 
Hi,
warum verwendest Du nicht einen Ringpuffer anstatt jedesmal das komplette Array zu kopieren?
Das mag bei 10 Werten keine große Sache sein, aber wenn das Array mal größer sein sollte...

Code:
Index := (Index MOD 10) + 1;
vMerker[Index] := v;

das habe ich nicht genau verstanden. kannst du das bisschen erläutern bitte.
 
Ich verstehe irgendwie nicht was Du meinst :(

Harald

Er verschiebt die Werte irgendwie nicht. i wird auf 11 gesetzt und die werten nehmen den vom ersten arrayplatz an.

hier mein Quellcode. vielleicht mache ich bei der variablen deklaration falsch?

VAR
signal:BOOL;
sTakt:TON;

flanke:F_TRIG;
f,v,sumMerker,vGMittelwert:REAL:=0;
n:Real:=0;
vMerker:ARRAY[1..10] OF REAL;
i:BYTE;
END_VAR

signal:=PiFace.byIn.1;
sTakt(PT:=T#1S);
zehnminTakt(PT:=T#600S);
sTakt.IN:=NOT sTakt.Q;

flanke(CLK:=signal);
IF (flanke.Q) THEN n:=n+1; END_IF;
IF (sTakt.Q) THEN f:=n; n:=0; END_IF;

v:=0.048*f;

FOR i:=9 TO 1 BY 1 DO vMerker[i+1]:=vMerker; END_FOR;
FOR i:=1 TO 10 BY 1 DO sumMerker:=sumMerker+vMerker; END_FOR;
vGMittelwert:=sumMerker*0.1;
sumMerker:=0;
 
Code:
FOR i:=9 TO 1 BY [COLOR=#ff0000][U][B]1[/B][/U][/COLOR] DO vMerker[i+1]:=vMerker[i]; END_FOR;
Wenn die Schleife rückwärts durchlaufen werden soll, muss die Schrittweite im Minusbereich sein. Hier also -1 und nicht 1.


Und benutz' für Deine Programmauszüge bitte die Code-Tags [Code] ... [/Code], die Du z.B. mit dem letzten Button # in der 2. Zeile erzeugen kannst. Dann wird der Code besser lesbar dargestellt.
 
Zuletzt bearbeitet:
Zurück
Oben