Hallo maverickxxll,
ich habe in meinem neuen Projekt so etwas ähnliches gemacht.
Schau dir mal die SCL Quelle an.
FUNCTION "ERGEB" : Void
TITLE = Ergebnisse registrieren
{ S7_Optimized_Access := 'FALSE' }
//registrieren und löschen von Ergebnissen
VAR_INPUT
START : Bool; // startet das Rotieren der Ergebnisse
RESET : Bool; // löscht den kompletten Speicher
"DB" : Block_DB; // Datenbaustein
LBYTE : Int; // Startbyte Ergebnisse links
RBYTE : Int; // Startbyte Ergebnisse rechts
SBYTE : Int; // Startbyte Status
ANZAHL : Int; // Anzahl der Bytes pro Spur
END_VAR
VAR_OUTPUT
BUSY : Bool; // Baustein ist beschäftigt
END_VAR
VAR_TEMP
X : Int; // Zählvariable
END_VAR
BEGIN
IF #START THEN
#BUSY := TRUE;
FOR #X := (#ANZAHL - 1) TO 0 BY -1 DO
#DB.DB(#LBYTE + #X) := SHR(IN:=#DB.DB(#LBYTE + #X), N:=1);
#DB.DB(#RBYTE + #X) := SHR(IN:=#DB.DB(#RBYTE + #X), N:=1);
#DB.DB(#SBYTE + #X) := SHR(IN:=#DB.DB(#SBYTE + #X), N:=1);
IF #X > 0 THEN
#DB.DX((#LBYTE + #X), 0) := #DB.DX(((#LBYTE + #X) - 1), 7);
#DB.DX((#RBYTE + #X), 0) := #DB.DX(((#RBYTE + #X) - 1), 7);
#DB.DX((#SBYTE + #X), 0) := #DB.DX(((#SBYTE + #X) - 1), 7);
END_IF;
END_FOR;
#BUSY := FALSE;
GOTO Ende;
END_IF;
IF #RESET THEN
#BUSY := TRUE;
FOR #X := (#ANZAHL - 1) TO 0 BY -1 DO
#DB.DB(#LBYTE + #X) := 0;
#DB.DB(#RBYTE + #X) := 0;
#DB.DB(#SBYTE + #X) := 0;
END_FOR;
#BUSY := FALSE;
END_IF;
Ende:
RETURN;
END_FUNCTION
Der Baustein rotiert mit steigender Flanke am "START" einmal alles durch. Am Ende musst du die genaue Stelle im DB wissen die du dann nur noch abfragen oder mit einem Ergebnis setzen musst.
"BUSY" wird TRUE wenn der Baustein läuft. "RESET" löscht alles. Da ich das für drei Spuren mache brauch ich "LBYTE", "RBYTE" und "SBYTE". Du brauchst ja nur eine Spur.
Der Baustein schiebt immer ganze Bytes und kopiert dann Bit7 vom vorhergehenden in Bit0 vom nachfolgenden Byte, so das die Kette einmal von vorn nach hinten verschoben wird.
MfG Peter.