Hi All,
I want to create FIFO block for 50 parameters. These parameters is in under Structure Data type. I have almost 90 sets of these parameter. Every 5 min. all data will be store in DB. is there any block so can move Structure Data type to next position. I tried with SFC 20 BLKMOV and I am getting result also but CPU work memory is increasing too much.
Please guide how to handle these? Without increasing work memory too much
Regards,
Yogendra
FIFO for Structure Data type
-
- Posts: 1
- Joined: Wed Jun 21, 2017 12:20 am
Re: FIFO for Structure Data type
FB_FIFO
Show
Code: Select all
(*****************************************************************************************
** **
** Copyright ?2011 SIEMENS AG I IA&DT, D-90475 Nuernberg **
** All Rights Reserved VOLKSWAGEN AG, 38436 Wolfsburg **
** AUDI AG, D-85045 Ingolstadt **
** **
******************************************************************************************
** **
** Aenderungsjournal : **
******************************************************************************************
** Datum Version Autor Beschreibung **
------------------------------------------------------------------------------------------
12.04.16 3.0.01 Schulz FIFO "leer" bilden nach Eintragen von Daten in FIFO
05.03.12 3.0.00 Jablonski Uebernahme in VASS_Standard aus V1.6
******************************************************************************************)
FUNCTION_BLOCK FB_FIFO // FB550
TITLE = 'Version 3.0.01'
VERSION : '3.0'
AUTHOR : VASS_V05
NAME : FIFO
FAMILY : FIFO
VAR_INPUT
In : BOOL;(*arDaten eintagen*)
Out : BOOL;(*arDaten austragen*)
Daten_In : DWORD;(*Einzutragender Datensatz*)
Laenge : INT;(*Laenge des FIFOs, Wert [1 bis 50]*)
Frg_Korr : BOOL;(*Freigabe Korrektur fuer Visualisierung*)
END_VAR
VAR_OUTPUT
Leer : BOOL;(*FIFO ist Leer*)
Voll : BOOL;(*FIFO ist Voll*)
Anzahl : INT;(*Anzahl arDaten In LIFO*)
Daten_Out : DWORD;(*Ausgetragener Datensatz*)
END_VAR
VAR_IN_OUT
In_Done : BOOL;(*Einspeichern fertig, muss von extern abgeloescht werden*)
Out_Done : BOOL;(*Ausspeichern fertig, muss von extern abgeloescht werden*)
Typ_Daten : ARRAY[0..50] OF DWORD;(*Typdaten Register*)
END_VAR
VAR
_dwVisuWerte1 : DWORD; (* B0: Sichtbarkeit der Bearbeitungs Buttons
B1: Anzahl eingefuegte Elemente
B2: Laenge des FI/LIFO
B3: Fr.Korrektur *)
_dwVisuWerte2 : DWORD; (* Schreibanforderung von Visu quittieren *)
dwVisuTasten1 : DWORD; (* geaenderter Datensatz von Visualisierung *)
_dwVisuTasten2 : DWORD; (* B0:
B1:
B2: Position (1..50)
B3: Befehl (1: Einfuegen 2: Aendern 3: Loeschen*)
arVisuWerte : ARRAY[0..50] OF DWORD; (* FIFO_DATEN *)
(**SIEMENS********************Anfang Variablendeklaration*************************************)
(***********fuer bit-, byte-, wordgranulare Sicht von Variablen mit dem AT-Befehl**************)
dwVisuTasten2 AT _dwVisuTasten2: STRUCT
B0 : BYTE ; // B0:
B1 : BYTE ; // B1:
B2 : BYTE ; // B2: Position (1..50)
B3 : BYTE ; (* B3: Befehl (1: Einfuegen 2: Aendern 3: Loeschen *)
END_STRUCT;
dwVisuWerte1 AT _dwVisuWerte1: STRUCT
B0 : BYTE ; //B0: Sichtbarkeit der Bearbeitungs Buttons
B1 : BYTE ; //B1: Anzahl eingefuegte Elemente
B2 : BYTE ; //B2: Laenge des FI/LIFO
B3 : BYTE ; //B3: Fr.Korrektur
END_STRUCT;
(**SIEMENS**********************Ende Variablendeklaration*************************************)
(***********fuer bit-, byte-, wordgranulare Sicht von Variablen mit dem AT-Befehl**************)
bBefehl : BYTE; (*Visubefehl*)
iVisuZeiger : INT; (*Bearbeitungsstelle aus Visu*)
iHM_Zaehler1 : INT; (*Laufvariable*)
iHM_Zaehler2 : INT; (*Laufvariable*)
iZeiger : INT; (*iZeiger auf letzten Datensatz*)
dwLeerdaten : DWORD := DWORD#0;(*Leerdatensatz fuer FIFO*)
R_TRIG_Out : R_Trig; (*Positive Flanke Austragen*)
R_TRIG_In : R_Trig; (*Positive Flanke Einspeichern*)
TON_EingabeTimeout : TON;
END_VAR
(*FIFO fuer die Zwischenspeicherung von Pufferdaten*)
(*Ruecksetzen der Befehle durch externe Quittierung*)
(*Umladen der Nutzdaten*)
arVisuWerte := Typ_Daten;
iZeiger := BYTE_TO_INT (DWORD_TO_BYTE(SHR(IN:=arVisuWerte[0],N:=16)));
(*Laengenpruefung*)
IF Laenge < 1 OR Laenge > 50 THEN
Laenge := 50;
END_IF;
(*Grenzen des FIFOs ueberpruefen*)
Voll:= (iZeiger >= Laenge);
(*Einspeichern eines neuen Datensatzes*)
R_TRIG_In(CLK:=In AND NOT Voll);
IF R_TRIG_In.Q AND NOT In_Done THEN
iZeiger := iZeiger + 1;
arVisuWerte[iZeiger] := Daten_In;
In_Done:=True;
END_IF;
Leer:= (iZeiger < 1 );
(*Austragen eines Datensatzes*)
R_TRIG_Out(CLK:=Out AND (In_Done OR NOT In ) AND NOT Leer );
IF R_TRIG_Out.Q AND NOT Out_Done THEN
Daten_Out := arVisuWerte[1];
(*Alle Datensaetze um ein Feld verschieben*)
FOR iHM_Zaehler1 := 2 TO iZeiger DO
iHM_Zaehler2 := iHM_Zaehler1 - 1;
arVisuWerte[iHM_Zaehler2] := arVisuWerte[iHM_Zaehler1];
END_FOR;
(* Freigewordenes Datenfeld abloeschen und iZeiger anpassen*)
arVisuWerte[iZeiger]:= dwLeerdaten;
iZeiger:= iZeiger - 1;
Out_Done := True;
END_IF;
(*Anzahl arVisuWerte In Puffer*)
Anzahl:= iZeiger;
//- Sichtbarkeit der Buttons zuruecksetzen
dwVisuWerte1.B0 := 0;
//- Setzen der Buttons-Sichtbarkeit
IF Frg_Korr THEN
// Wenn Freigabe, dann
IF (iZeiger <= 0)THEN
// Wenn kein Element
arVisuWerte[0] := arVisuWerte[0] OR SHL(IN:=BOOL_TO_DWORD(True),N:=25); // Aendern
arVisuWerte[0] := arVisuWerte[0] OR SHL(IN:=BOOL_TO_DWORD(True),N:=26); // Loeschen
dwVisuWerte1.B0 := dwVisuWerte1.B0 OR SHL(IN:=BOOL_TO_BYTE(True),N:=1); // Aendern
dwVisuWerte1.B0 := dwVisuWerte1.B0 OR SHL(IN:=BOOL_TO_BYTE(True),N:=2); // Loeschen
END_IF;
IF (iZeiger >= Laenge)THEN
// Wenn Voll
arVisuWerte[0] := arVisuWerte[0] OR SHL(IN:=BOOL_TO_DWORD(True),N:=24); // Einfuegen
dwVisuWerte1.B0 := dwVisuWerte1.B0 OR SHL(IN:=BOOL_TO_BYTE(True),N:=0); // Einfuegen
END_IF;
ELSE
//Wenn Kein Freigabe:
arVisuWerte[0] := arVisuWerte[0] AND DWORD#16#FFFFFF00;
dwVisuWerte1.B0 := Byte#16#0F; // Alle Unsichtbar
END_IF;
IF NOT Frg_Korr THEN
_dwVisuWerte2 := DWORD#0;
dwVisuTasten2.B2 := Byte#0;
dwVisuTasten2.B3 := Byte#0;
END_IF;
(*Typkennung fuer Fifo*)
arVisuWerte[0] := arVisuWerte[0] OR SHL(IN:=BOOL_TO_DWORD(True),N:=1);
bBefehl := dwVisuTasten2.B3;
iVisuZeiger := BYTE_TO_INT(dwVisuTasten2.B2);
(*Schreibbefehle von der Visualisierung ueberwachen*)
IF "PC_AKTIV" = DWORD#16#00000000 OR NOT Frg_Korr THEN
bBefehl := Byte#0;
iVisuZeiger := INT#0;
END_IF;
(*Pruefung auf gueltige Werte*)
IF iVisuZeiger > 0 AND iVisuZeiger <= 50 THEN
(*Einfuegen eines neuen Datensatzes aus der Visu*)
IF bBefehl = Byte#1 AND NOT Voll THEN
IF iVisuZeiger <= iZeiger THEN
iZeiger:=iZeiger + 1;
iHM_Zaehler1:=iZeiger;
REPEAT
iHM_Zaehler2:=iHM_Zaehler1 - 1;
arVisuWerte[iHM_Zaehler1]:= arVisuWerte[iHM_Zaehler2];
iHM_Zaehler1:=iHM_Zaehler1 - 1;
UNTIL iHM_Zaehler2 = iVisuZeiger
END_REPEAT;
arVisuWerte[iVisuZeiger]:= dwVisuTasten1;
ELSE
iZeiger:=iZeiger + 1;
arVisuWerte[iZeiger]:= dwVisuTasten1;
END_IF;
dwVisuTasten2.B3 := Byte#0;
dwVisuTasten2.B2 := Byte#0;
END_IF;
(*Ueberschreiben eines Datensatzes aus der Visualisierung*)
IF bBefehl = Byte#2 AND iVisuZeiger <= iZeiger THEN
arVisuWerte[iVisuZeiger] := dwVisuTasten1;
dwVisuTasten2.B3 := Byte#0;
dwVisuTasten2.B2 := Byte#0;
END_IF;
(*Loeschen eines Datensatzes aus der Visualisierung*)
IF bBefehl = Byte#3 AND iVisuZeiger <= iZeiger THEN
iZeiger:=iZeiger - 1;
iHM_Zaehler2:= iVisuZeiger; (*Initialisierung, fuer iVisuZeiger > iZeiger*)
FOR iHM_Zaehler1:= iVisuZeiger TO iZeiger DO
iHM_Zaehler2:=iHM_Zaehler1 + 1;
arVisuWerte[iHM_Zaehler1]:= arVisuWerte[iHM_Zaehler2];
END_FOR;
arVisuWerte[iHM_Zaehler2]:=dwLeerdaten;
dwVisuTasten2.B3 := Byte#0;
dwVisuTasten2.B2 := Byte#0;
END_IF;
(* Aenderung des Ausgangs Daten_Out*)
ELSIF iVisuZeiger = 55 AND bBefehl = Byte#2 THEN
Daten_Out := dwVisuTasten1;
dwVisuTasten2.B3 := Byte#0;
dwVisuTasten2.B2 := Byte#0;
END_IF;
(*arVisuWerte fuer Visu aufbereiten-------------------------------------------------*)
// VisuWerte fuer die Visu aufbereiten -------------------------------------------------
arVisuWerte[0] := (arVisuWerte[0] AND DWORD#16#FFFFFFFE) OR SHL(IN:=BOOL_TO_DWORD(Frg_Korr),N:=0);
dwVisuWerte1.B3 := Frg_Korr;
//- (Laenge);
arVisuWerte[0] := (arVisuWerte[0] AND DWORD#16#FFFF00FF) OR SHL(IN:=INT_TO_DWORD(Laenge),N:=8);
dwVisuWerte1.B2 := INT_TO_BYTE(Laenge);
//- (iZeiger);
arVisuWerte[0] := (arVisuWerte[0] AND DWORD#16#FF00FFFF) OR SHL(IN:=INT_TO_DWORD(iZeiger),N:=16);
dwVisuWerte1.B1 := INT_TO_BYTE(iZeiger);
(* Wenn Eingabe nicht beendet wird, dann nach 40 Sekunden Eingabe abbrechen*)
//TON_EingabeTimeout(In:=(dwVisuWerte3 <> Dword#0), PT:=T#40s);
//####################################
//TON_EingabeTimeout(In:=(dwVisuWerte1.B0 <> Dword#0), PT:=T#40s);
(*
IF TON_EingabeTimeout.Q THEN
dwVisuWerte1.B0 := Byte#0;
//dwVisuWerte3 := DWORD#0;
dwVisuTasten2.B3 := Byte#0;
dwVisuTasten2.B2 := Byte#0;
//wVisuSteuerwort1 := Word#0;
END_IF;
*)
(* Umladen der Nutzdaten*)
Typ_Daten:= arVisuWerte;
(*Baustein-Ende*)
END_FUNCTION_BLOCK