# Array Schieberegister



## SPSOS (4 September 2011)

Hallo!

Möchte ein Array (8Spalten und 64 Zeilen) erzeugen. Datentypen:1xString,7Int
Immer 8 Zeilen gleichzeitig weiterschieben.
Eventuell in jede Zeile einen Wert bzw. Spalte vor dem Schieben aktualisieren.
Bin ein Neuling in der Codesyswelt.
Verwendetes PLC-System: Eaton X-Soft

Vielen Dank für die Hilfen


----------



## StructuredTrash (5 September 2011)

Ich würde da gar nichts schieben, sondern einen Ringpuffer bauen.
Für die Daten ein "Array[0..63] of irgendwas"
Dann eine INT-Variable "Index_Pos0", die Dir den aktuellen Array-Index für Position 0 des "Schieberegisters" liefert.
Um die Daten z. B. um eine Stelle "weiterzuschieben":
Index_Pos0:=(Index_Pos0+1) AND 63;
Um den aktuellen Array-Index für eine andere Position zu berechnen:
Index_PosX:=(Index_Pos0-PosX) AND 63;


----------



## PN/DP (5 September 2011)

StructuredTrash schrieb:


> Um die Daten z. B. um eine Stelle "weiterzuschieben":
> Index_Pos0:=(Index_Pos0+1) AND 63;


Genaugenommen müßte es so berechnet werden:
Index_Pos0:=(Index_Pos0+1) MOD 64;
Doch bei Array[0..63] funktioniert "AND 63" auch richtig. 

Harald


----------



## StructuredTrash (6 September 2011)

PN/DP schrieb:


> Genaugenommen müßte es so berechnet werden:
> Index_Pos0:=(Index_Pos0+1) MOD 64;
> Doch bei Array[0..63] funktioniert "AND 63" auch richtig.


Ja, das stimmt schon. Ich hätte vielleicht noch dazu schreiben sollen, dass das "AND" nur bei ganzen 2er-Potenzen funktioniert. Wenn man die allgemeingültige Version mit "MOD" wählt, müssen allerdings die Indexvariablen UINT sein, damit es keine negativen Werte gibt.


----------



## mathez (21 April 2015)

Hallo zusammen, 

ich schließe mich mal an diesen alten Threat an, da auch ich Probleme mit dem Ringpuffer habe. Ausgangspunkt ist meine Masterarbeit, in der ich eigentlich versuche eine Schnittstelle zwischen LabView und Beckhoff TwinCat zu erstellen. Da aufgrund der Menge der Daten ein Puffer nötig ist, wollen wir diesen schon in der SPS programmieren. Hierzu haben wir zunächst der Einfachheit halber und um die Daten besser auswerten zu können ein Array erstellt, welches Index für Index eine Zahl hochzählt. Wenn das Array voll geschrieben ist, wird am ersten Index weitergeschrieben. Da diese Variante jedoch zu Problemen in der anschließenden Auswertung mit LabView geführt hat, möchten wir nun, dass praktisch jeweils der neue Wert in den letzten Index geschrieben wird und oben herausgelöscht wird. 


Leider scheitere ich bisher kläglich in der Programmierung eines solchen Puffers in ST.


Vielleicht habt ihr ja ein paar Tipps für mich als Anfänger. Leider kann ich auch mit den Erklärungen hier drüber noch nicht so viel anfangen. 


Mfg, Mathes


----------



## StructuredTrash (21 April 2015)

TwinCat hat eine Funktion "MemMove", die auch für das Kopieren von überlappenden Speicherbereichen geeignet ist. Damit könntest Du die Daten des Arrays in einem Rutsch von Array[0] nach Array[1] schieben und dabei den Inhalt des obersten
Arrayfeldes unter den Tisch fallen lassen.


----------



## mathez (22 April 2015)

Hallo, 

zunächst vielen Dank für deine Antwort. Ich bin nicht sicher, ob der Baustein unseren Anforderungen entspricht. Wenn ja, dann weiß ich nicht genau wie ich es umsetzen muss. Im Prinzip habe ich es bisher "im kleinen" völlig simpel so gelöst:

Array [0] := Array[1]
Array[1]:= Array[2]
Array[2]:=Array[3]
Array[3]:=sin(x)

Hier wird ein Sinus von Index 3 des Arrays bis oben durchgereicht .. das eigentliche Problem ist, dass ich nun eine Möglichkeit suche, auf diese Weise bis zu 200 verschiedene Werte gleichzeitig von Stelle 100 bis Stelle 0 zu verschieben, was natürlich einen ungeheuren Programmieraufwand bedeuten würde. So sollen beispielsweise Index 91-100 an Stelle 81-90 durchgereicht werden und dabei dann mit neuen Werten beschrieben werden usw. Sollte die von Dir beschriebene Funktion das können, bitte ich um Nachsicht und würde mich über ein kurzes Beispiel freuen.

Ansonsten bin ich für jeden Tipp dankbar!

Viele Grüße,  

Mathes

Edit: habe es jetzt mit einer Schleife gelöst und es funktioniert soweit. Es gibt aber sicherlich sauberer Lösungen?!


----------



## singleton (22 April 2015)

mathez schrieb:


> Es gibt aber sicherlich sauberer Lösungen?!



Die saubere Lösung ist der bereits erwähnte Ringpuffer


----------



## mathez (22 April 2015)

Besteht denn die Möglichkeit einen Ansatz zu bekommen oder eine Seite auf der ich es nachschlagen kann? Ich verstehe im oben genannten Beispiel leider nicht ganz auf welche Weise dort der Wert verschoben wird. Was erreiche ich mit "MOD"? Wenn ich es programmiere zählt das Programm ganz normal einen entsprechenden Index hoch .. ich habe sicherlich nur einen blöden Dreher drin bzw. ein Verständnisproblem.

Danke und Gruß

Mathes


----------



## shrimps (22 April 2015)

Hi mathez,
ich hatte mich auch mal an dem Memcopy versucht mit Arrays etc.
http://www.sps-forum.de/programmier...gen-aendernd-von-arrayindexen.html#post524925

Ist allerdings in ST...
Viel Erfolg
Shrimps


----------



## StructuredTrash (22 April 2015)

mathez schrieb:


> Array [0] := Array[1]
> Array[1]:= Array[2]
> Array[2]:=Array[3]
> Array[3]:=sin(x)


würde mit MemMove so aussehen:

```
MemMove(
   destAddr:=ADR(Array[0]),   (* Zieladresse *)
   srcAddr:=ADR(Array[1]),     (* Quelladresse *)
   n:=SizeOf(Array)-Grösse eines Arrayfeldes);   (* Anzahl der zu verschiebenden Bytes *)
Array[3]:=sin(x);
```


----------



## computershooter (22 April 2015)

seht doch bitte die antworte aus 2011 an.
wenn labview fragt dan biete eine andere array an, dan brauchst du nur eine neue berechnung zu machen einmal wen die array vol ist.
stat jedes mahl wenn eine wert andert


----------

