FIFO for Structure Data type

SIMATIC S7-200/300/400, Step7, PCS7, CFC, SFC, PDM, PLCSIM,
SCL, Graph, SPS-VISU S5/S7, IBHsoftec, LOGO ...
Post Reply
yogi_g2982
Posts: 15
Joined: Fri May 18, 2012 8:54 am

FIFO for Structure Data type

Post by yogi_g2982 » Wed Sep 19, 2018 6:03 am

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

Alex_Zhang
Posts: 1
Joined: Wed Jun 21, 2017 12:20 am

Re: FIFO for Structure Data type

Post by Alex_Zhang » Thu Sep 20, 2018 2:59 pm

(suc)

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