BaseSystemLib hinzugefügt

This commit is contained in:
2026-06-29 16:28:48 +02:00
parent a51a0c6fd1
commit 14a1c5172d
168 changed files with 6797 additions and 0 deletions
@@ -0,0 +1,11 @@
LibraryType:
Guid: 909777d2-e8ca-420e-b3b9-f6ae53af035b
LibraryVersion:
VersionNumber: 2.0.0
Author: e.yueksel
IsDefault: true
Comment:
de-DE: |-
Funktioniert zusammen mit LGF_FIFO
Ein Element zu einem FIFO Buffer hinzufügen
Freigegeben für IBN (EY, 22.04.2025)
@@ -0,0 +1,9 @@
DocumentHash:
- FileName: FC_FIFO_Append.scl
Hash: T7Pj2Z8cyXap1q9uur4i3m1xqyz5pPRz/2hkOB/5RlQ=
LibraryMetaFileHash: NABXVWmEloQAw/4Sn10m6TubIWUxHKkGYjsFdv1x47I=
LibraryVersion:
Guid: b605d468-bdd6-47e4-b7f5-c931cf8b16ae
DependsOn:
- TypeName: LGF_FIFO
VersionNumber: 4.0.0
@@ -0,0 +1,38 @@
FUNCTION "FC_FIFO_Append" : Void
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
VAR_INPUT
DataIn : Variant; // Der Wert der eingereiht werden soll
InitialItem : Variant; // Initialwert für Elemente im FIFO
MaxNo : UInt; // Maximale Anzahl an Elementen im FIFO-Buffer
END_VAR
VAR_OUTPUT
Success : Bool; // Einreihen erfolgreich
END_VAR
VAR_IN_OUT
fifoBuffer : "LGF_FIFO";
buffer : Variant; // Der FIFO-Buffer
END_VAR
VAR_TEMP
DataOut : Bool; // Platzhalter
END_VAR
BEGIN
#fifoBuffer(enqueue:= TRUE,
dequeue := FALSE,
initialItem:= #InitialItem,
itemIn:= #DataIn,
maxElementCount := #MaxNo,
buffer:= #buffer,
itemOut:=#DataOut);
IF #fifoBuffer.enqueueDone THEN
#Success := TRUE;
END_IF;
END_FUNCTION
@@ -0,0 +1,8 @@
LibraryType:
Guid: b6f005ff-2e28-4973-a770-caf1f845319a
LibraryVersion:
VersionNumber: 2.0.2
Author: e.yueksel
IsDefault: true
Comment:
de-DE: "Funktioniert mit Baustein LGF_FIFO\r\nDas aktuelle Element aus einem FIFO Buffer herausholen\r\nFreigegeben für IBN (EY, 22.04.2025) "
@@ -0,0 +1,11 @@
DocumentHash:
- FileName: FC_FIFO_GetFirst.scl
Hash: mJ29Kj+4BQYei3JO8PAOd0BmtSJ4E3eBFI9vfBpNeys=
LibraryMetaFileHash: IvtmcsHWKWxUkbuSinagzaRgz2Pd4cWgwdCq1p4ZLVs=
LibraryVersion:
Guid: 5f307c66-66a2-4362-98ee-51660aada83e
DependsOn:
- TypeName: LGF_FIFO
VersionNumber: 4.0.0
- TypeName: UDT_TelegramData_Send
VersionNumber: 0.0.7
@@ -0,0 +1,38 @@
FUNCTION "FC_FIFO_GetFirst" : Void
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
VAR_INPUT
xInInitialItem : Variant; // Initialwert für Elemente im FIFO
nInMaxNo : UInt; // Maximale Anzahl an Elementen im FIFO-Buffer
END_VAR
VAR_OUTPUT
xOutSuccess : Bool; // Einreihen erfolgreich
xOutData : Variant;
END_VAR
VAR_IN_OUT
fifoBuffer : "LGF_FIFO";
buffer : Variant; // Der FIFO-Buffer
END_VAR
VAR_TEMP
xInData : "UDT_TelegramData_Send"; // Platzhalter
END_VAR
BEGIN
#fifoBuffer(enqueue:= FALSE,
dequeue := TRUE,
initialItem:= #xInInitialItem,
itemIn:= #xInData,
maxElementCount := #nInMaxNo,
buffer:= #buffer,
itemOut:=#xOutData);
IF #fifoBuffer.dequeueDone THEN
#xOutSuccess := TRUE;
END_IF;
END_FUNCTION
@@ -0,0 +1,6 @@
LibraryType:
Guid: 0f749c18-e0f3-4bcc-957e-a77803394a52
LibraryVersion:
VersionNumber: 0.0.2
Author: e.yueksel
IsDefault: true
@@ -0,0 +1,9 @@
DocumentHash:
- FileName: FC_FIFO_GetFirst_Test.scl
Hash: 6+VnqYpzQbXy+UJkXPRSzMiXh3gVIEuHAnvTtWoM/EE=
LibraryMetaFileHash: m20Dmlf+lR6z9vRxLkOCaBr5vzDmdclwD9awOuJumrs=
LibraryVersion:
Guid: 880f12fd-0740-47ac-a348-dc57dfcfb243
DependsOn:
- TypeName: LGF_FIFO
VersionNumber: 4.0.0
@@ -0,0 +1,38 @@
FUNCTION "FC_FIFO_GetFirst_Test" : Void
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
VAR_INPUT
xInInitialItem : Variant; // Initialwert für Elemente im FIFO
nInMaxNo : UInt; // Maximale Anzahl an Elementen im FIFO-Buffer
END_VAR
VAR_OUTPUT
xOutSuccess : Bool; // Einreihen erfolgreich
xOutData : Variant;
END_VAR
VAR_IN_OUT
fifoBuffer : "LGF_FIFO";
buffer : Variant; // Der FIFO-Buffer
END_VAR
VAR_TEMP
xInData : USInt; // Platzhalter
END_VAR
BEGIN
#fifoBuffer(enqueue:= FALSE,
dequeue := TRUE,
initialItem:= #xInInitialItem,
itemIn:= #xInData,
maxElementCount := #nInMaxNo,
buffer:= #buffer,
itemOut:=#xOutData);
IF #fifoBuffer.dequeueDone THEN
#xOutSuccess := TRUE;
END_IF;
END_FUNCTION
@@ -0,0 +1,8 @@
LibraryType:
Guid: 165134c6-89ff-4736-8f52-770c0346080b
LibraryVersion:
VersionNumber: 4.0.0
Author: e.yueksel
IsDefault: true
Comment:
de-DE: "Das ist eine modifizierte Version des LGF_FIFO aus der Siemens-Library. \r\nÄnderungen:\r\n- Schnittstelle: \r\n - InOut: itemIn und itemOut, statt item.\r\n - isFull hinzugefügt\r\n - maxElementCount hinzugefügt\r\n - enqueueDone und dequeueDone hinzugefügt\r\n\r\nCode angepasst\r\n\r\n3.0.3 + 3.0.5 \r\n- Flankenmerker für enqueue und dequeue wird manuell zurückgesetzt\r\n\r\n4.0.0: Freigabe IBN (EY, 22.04.2025) "
@@ -0,0 +1,6 @@
DocumentHash:
- FileName: LGF_FIFO.scl
Hash: BIfbhj29jufO1l1arCSCphOQSLppKO8CJWeKftAqSGc=
LibraryMetaFileHash: YbN2PYZ8AkYvSAAoX7IlQQcHgXBeUPYkgUs0xiYeHLY=
LibraryVersion:
Guid: bae66bce-23a3-475d-93bf-65bd96466183
@@ -0,0 +1,389 @@
FUNCTION_BLOCK "LGF_FIFO"
TITLE = LGF_FIFO
{ S7_Optimized_Access := 'TRUE' }
AUTHOR : Siemens_Industry_Support
FAMILY : LGF
NAME : LGF_FIFO
//FIFO (First-In First-Out / Queue / Ringspeicher)
//Diese Funktion speichert eingehende Daten und gibt die ältesten noch nicht abgearbeiteten Daten aus.
//
VAR_INPUT
enqueue : Bool := false; // Element einreihen in den Puffer (Enqueue)
dequeue : Bool := false; // Element aus dem Puffer löschen und an `item` zurückgeben (Dequeue)
reset : Bool; // Puffer initialisieren (Index und Zähler zurücksetzen)
clear : Bool; // Puffer leeren und mit Anfangswert `initialItem` initialisieren (Index und Zähler zurücksetzen).
initialItem : Variant; // Wert mit dem das Array des Puffer initialisiert wird (meistens: `0` / default wert)
maxElementCount : UInt; // Maximale Anzahl an Elementen im FIFO
END_VAR
VAR_OUTPUT
error { ExternalWritable := 'False'} : Bool; // FALSE: Kein Fehler TRUE: Während der Ausführung des FB ist ein Fehler aufgetreten
status { ExternalWritable := 'False'} : Word; // 16#0000-16#7FFF: Status des FB 16#8000-16#FFFF: Fehleridentifikation (siehe folgende Tabelle)
subFunctionStatus { ExternalWritable := 'False'} : Word; // Status oder Rückgabewert von aufgerufenen FB's / FC's und Systemfunktionen
END_VAR
VAR_OUTPUT RETAIN
elementCount { ExternalWritable := 'False'} : USInt := 0; // Anzahl der Elemente im Puffer
isEmpty { ExternalWritable := 'False'} : Bool := TRUE; // TRUE: Puffer ist leer
isFull : Bool;
END_VAR
VAR_OUTPUT
oldestElement : Int;
enqueueDone : Bool;
dequeueDone : Bool;
END_VAR
VAR_IN_OUT
itemIn : Variant; // Eintrag der aus dem Puffer zurückgegeben wird oder in den Puffer geschrieben werden soll
buffer : Variant; // Das ARRAY welches als Puffer genutzt wird. (Array of … )
itemOut : Variant;
END_VAR
VAR RETAIN
statEdgesMem { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Struct // Flanken speicher zum speichern des vorherigen Zustands und Flankendetektion
enqueue { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; // enqueue Flanke
dequeue { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; // dequeue Flanke
clear { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; // clearing Flanke
END_STRUCT;
statFirstItemIndex { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Int := -1; // Index des ältesten Eintrags im Puffer
statNextEmptyItemIndex { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Int := 0; // Index für den nächsten freien Platz im Puffer
statElementCount { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : DInt; // Anzahl der Elemente im Puffer
END_VAR
VAR_TEMP
tempEdges : Struct // Flanken speicher zum speichern der Flanken
enqueue : Bool; // enqueue Flanke
dequeue : Bool; // dequeue Flanke
clear : Bool; // clearing Flanke
END_STRUCT;
tempInternalError : Int; // Fehler Information für interne Funktionsaufrufe und Rückgabewerte
tempNewFirstItemIndex : Int; // Variable Index
tempNewNextEmptyItemIndex : Int; // Variable Index
tempBufferSize : UDInt; // Anzahl der Elemente im Puffer Array / Puffer Größe
tempCounter : Int; // Zählvariable für die Iteration durch den Puffer
END_VAR
VAR CONSTANT
BUFFER_IS_EMPTY : Int := -1; // Puffer ist leer
NO_INTERNAL_ERROR : Int := 0; // Kein interner Fehler
BUFFER_INITIALIZED : Int := -1; // Puffer initialisieren
EMPTY_INITIALIZED : Int := 0; // Leeres Element Index = 0
INDEX_BEGINNING : Int := 0; // Startwert für die Indizierung des Arrays
COUNT_ELEMENTS : UDInt := 1; // Anzahl der zu kopierenden Elemente = 1
INCREMENT : Int := 1; // Inkrement Wert EINS
BUFFER_SIZE_CORRECTION : UDInt := 1; // Puffer Größen Korrekturfaktor (0-basierte Zählung)
COUNTER_LOWER_LIMIT : Int := 0; // Zähler untere Grenze
ZERO_ELEMENTS : DInt := 0; // Keine Elemente vorhanden
STATUS_NO_ERROR : Word := 16#0000; // Status: Abarbeitung ohne Fehler beendet
STATUS_NO_CURRENT_JOBS : Word := 16#7000; // Status: Keine aktuellen Aufträge, Initial State
ERR_BUFFER_EMPTY : Word := 16#8001; // Fehler: Der Puffer ist leer
ERR_BUFFER_FULL : Word := 16#8002; // Fehler: Der Puffer ist voll
ERR_NO_ARRAY : Word := 16#8200; // Fehler: Am Eingang `buffer` liegt kein Array an.
ERR_WRONG_TYPE_ITEM : Word := 16#8201; // Fehler: Der Datentyp des InOut-Parameters `item` entspricht nicht dem Datentyp der Array-Elemente von dem Eingang `buffer`.
ERR_WRONG_TYPE_INITIAL_ITEM : Word := 16#8202; // Fehler: Der Datentyp des Eingangs `initialItem` entspricht nicht dem Datentyp des InOut-Parameters `item`.
ERR_INDEX_IN_ARRAY_LIMITS_1 : Word := 16#8601; // Fehler: Die Variable `statNextEmptyItemIndex` liegt ausserhalb der Array Grenzen
ERR_INDEX_IN_ARRAY_LIMITS_2 : Word := 16#8602; // Fehler: Die Variable `statFirstItemIndex` liegt ausserhalb der Array Grenzen
ERR_CLEAR_BUFFER : Word := 16#8610; // Fehler: Während des Ablöschen des Puffer in Funktion `MOVE_BLK_VARIANT` - weitere Infos in `subFunctionStatus`
ERR_RETURN_FIRST_ENTRY : Word := 16#8611; // Fehler: Während der Rückgabe des ersten Elements aus dem Puffer in Funktion `MOVE_BLK_VARIANT` - weitere Infos in `subFunctionStatus`
ERR_REPLACE_ITEM_BY_INIT_VALUE : Word := 16#8612; // Fehler: Während des Überschreibens des Elements mit dem Initialwort in Funktion `MOVE_BLK_VARIANT` - weitere Infos in `subFunctionStatus
ERR_WRITE_ENTRY : Word := 16#8613; // Fehler: Während des Schreibens eines Elements in den Puffer in Funktion `MOVE_BLK_VARIANT` - weitere Infos in `subFunctionStatus`
END_VAR
BEGIN
REGION Block info header
//===============================================================================
// SIEMENS AG / (c)Copyright 2019
//-------------------------------------------------------------------------------
// Title: LGF_FIFO
// Comment/Function: FIFO (First In First Out)
// Queue / ring buffer memory
// Library/Family: LGF (Library General Functions)
// Author: Siemens Digital Industry Support
// Tested with: CPU 1515F-2 PN FW:V2.6
// Engineering: TIA Portal V15.1 Update 2
// Restrictions: ENO disabled - error handling done with error and status
// Requirements: PLC (S7-1200 / S7-1500)
//-------------------------------------------------------------------------------
// Change log table:
// Version | Date | Expert in charge | Changes applied
//----------|------------|------------------------|------------------------------
// 01.00.00 19.08.2015 Siemens Industry Online Support
// First released version
// 01.00.01 16.11.2015 Siemens Industry Online Support
// Bug fix resetBuffer
// 01.00.02 02.01.2017 Siemens Industry Online Support
// Upgrade: TIA Portal V14 Update 1
// 01.00.03 17.08.2018 Siemens Industry Online Support
// Upgrade: TIA V15 Update 2
// 01.00.04 23.11.2018 Siemens Industry Online Support
// Upgrade: TIA V15.1
// 02.00.00 29.01.2019 Siemens Industry Online Support
// Output "done" removed (not necessary, because block works synchronous)
// 03.00.00 22.10.2019 Simatic Systems Support
// Code refactoring, comments added
// Interface change (enqueue, dequeue etc.)
// Set version to V3.0.0, harmonize the version of the whole library
// 03.00.01 15.02.2021 Simatic Systems Support
// Insert documentation
//=============================================================================
END_REGION Block info header
REGION DESCRIPTION
(/*
Hinweis
: In `subFunctionStatus` wird der Status von aufgerufenen Anweisungen ausgegeben. Der Ausgangswert in `status` gibt in diesem Fall an, welche Anweisung den Fehler verursacht hat. Holen Sie sich in diesem Fall die Informationen aus der TIA Portal Online Hilfe zu den jeweiligen Anweisungen.
---
Hinweis
: Die Warteschlange (Queue) in der Informatik beruht ebenfalls auf dem FIFO-Prinzip.
---
Mit dem Eingang `enqueue` wird ein neues Element vom InOut-Parameter `item` an der nächsten freien Stelle im Puffer gespeichert. Der Ausgang `elementCount` wird um eins inkrementiert.
Mit dem Eingang `dequeue` ausgegeben und dieses Feld im Puffer durch den Wert am Parameter `initialItem` ersetzt. Der Ausgang `elementCount` wird um eins dekrementiert.
Mit dem Eingang `reset` wird der Puffer initialisiert, Index und Zähler werden zurückgesetzt. Der Ausgang `elementCount` wird auf null und der Ausgang `isEmpty` wird auf TRUE gesetzt.
Mit dem Eingang `clear` wird der Puffer geleert und mit Anfangswert `initialItem` initialisiert. Index und Zähler werden zurückgesetzt. Der Ausgang `elementCount` wird auf null, der Ausgang `isEmpty` auf TRUE gesetzt.
*/)
END_REGION DESCRIPTION
REGION Block execution control
#enqueueDone := FALSE;
#dequeueDone := FALSE;
// collect edges
#tempEdges.dequeue := #dequeue AND NOT #statEdgesMem.dequeue;
#tempEdges.clear := #clear AND NOT #statEdgesMem.clear;
// store values for edge detection
IF NOT #dequeue THEN
#tempEdges.enqueue := #enqueue AND NOT #statEdgesMem.enqueue;
#statEdgesMem.enqueue := #enqueue;
END_IF;
#statEdgesMem.dequeue := #dequeue;
#statEdgesMem.clear := #clear;
// This program code section is only executed if no trigger input is active
IF NOT (#enqueue OR #dequeue OR #reset OR #clear) THEN
// If an error occurred during program execution,
// the status "No Current Job" is used 16#7000 afterwarts when the triggers are reseted
#error := false;
#status := #STATUS_NO_CURRENT_JOBS;
#subFunctionStatus := #STATUS_NO_ERROR;
// the program processing OF the FB is terminated
RETURN;
END_IF;
END_REGION
REGION Validation of inputs
// check whether the ring #buffer is an ARRAY.
// IF so, the number OF the ARRAY elements is read out.
// IF it is NOT an ARRAY, the program execution is terminated at this point
IF IS_ARRAY(#buffer) THEN
#tempBufferSize := CountOfElements(#buffer);
ELSE
#error := true;
#status := #ERR_NO_ARRAY;
#subFunctionStatus := #STATUS_NO_ERROR;
RETURN;
END_IF;
// check whether the data type OF the ARRAY elements matches
// the data type OF the entry (#item). IF the data types DO NOT match,
// the program execution is terminated at this point
IF (TypeOf(#itemIn) <> TypeOfElements(#buffer)) THEN
#error := true;
#status := #ERR_WRONG_TYPE_ITEM;
#subFunctionStatus := #STATUS_NO_ERROR;
RETURN;
END_IF;
// check whether the initial value OF the ring #buffer
// matches the entry (tag #item). IF the data types DO NOT match,
// the program execution is terminated at this point
IF (TypeOf(#itemIn) <> TypeOf(#initialItem)) THEN
#error := true;
#status := #ERR_WRONG_TYPE_INITIAL_ITEM;
#subFunctionStatus := #STATUS_NO_ERROR;
RETURN;
END_IF;
// check whether the variable indices are within the ARRAY limits.
// IF they are NOT, the program execution is terminated at this point
IF (#statNextEmptyItemIndex >= #tempBufferSize) THEN
#error := true;
#status := #ERR_INDEX_IN_ARRAY_LIMITS_1;
#subFunctionStatus := #STATUS_NO_ERROR;
RETURN;
ELSIF (#statFirstItemIndex >= #tempBufferSize) THEN
#error := true;
#status := #ERR_INDEX_IN_ARRAY_LIMITS_2;
#subFunctionStatus := #STATUS_NO_ERROR;
RETURN;
END_IF;
// If resetBuffer is "TRUE", the buffer counters are reset
IF #reset THEN
#statFirstItemIndex := #BUFFER_INITIALIZED;
#statNextEmptyItemIndex := #EMPTY_INITIALIZED;
#statElementCount := #EMPTY_INITIALIZED;
#elementCount := INT_TO_USINT(#EMPTY_INITIALIZED);
#isEmpty := true;
RETURN;
END_IF;
// If clearBuffer has rising edge, the buffer is initialized by initial values
IF #tempEdges.clear THEN
FOR #tempCounter := #COUNTER_LOWER_LIMIT TO UDINT_TO_INT(#tempBufferSize - #BUFFER_SIZE_CORRECTION) DO
#tempInternalError := MOVE_BLK_VARIANT(SRC := #initialItem,
COUNT := #COUNT_ELEMENTS,
SRC_INDEX := #INDEX_BEGINNING,
DEST_INDEX := #tempCounter,
DEST => #buffer);
END_FOR;
// checks whether a local error has occurred.
IF (#tempInternalError <> #NO_INTERNAL_ERROR) THEN
#error := true;
#status := #ERR_CLEAR_BUFFER;
#subFunctionStatus := INT_TO_WORD(#tempInternalError);
END_IF;
// reset counters
#statFirstItemIndex := #BUFFER_INITIALIZED;
#statNextEmptyItemIndex := #EMPTY_INITIALIZED;
#statElementCount := #EMPTY_INITIALIZED;
#elementCount := INT_TO_USINT(#EMPTY_INITIALIZED);
#isEmpty := true;
RETURN;
END_IF;
END_REGION
REGION FIFO algorithm
IF #tempEdges.dequeue THEN
REGION dequeue
// check whether the ring #buffer is empty
// IF this is the CASE, program execution is terminated at this point
IF (#statFirstItemIndex = #BUFFER_IS_EMPTY) THEN
#error := true;
#status := #ERR_BUFFER_EMPTY;
#subFunctionStatus := #STATUS_NO_ERROR;
RETURN;
END_IF;
// return the first entry of the ring buffer
#tempInternalError := MOVE_BLK_VARIANT(SRC := #buffer,
COUNT := #COUNT_ELEMENTS,
SRC_INDEX := #statFirstItemIndex,
DEST_INDEX := #INDEX_BEGINNING,
DEST => #itemOut);
// check whether a local error has occurred
IF (#tempInternalError <> #NO_INTERNAL_ERROR) THEN
#error := true;
#status := #ERR_RETURN_FIRST_ENTRY;
#subFunctionStatus := INT_TO_WORD(#tempInternalError);
RETURN;
END_IF;
// check whether the ring #buffer contains ARRAY elements
// IF it does, the first entry is passed further on and the index is incremented BY 1
#tempInternalError := MOVE_BLK_VARIANT(SRC := #initialItem,
COUNT := #COUNT_ELEMENTS,
SRC_INDEX := #INDEX_BEGINNING,
DEST_INDEX := #statFirstItemIndex,
DEST => #buffer);
// check whether a local error has occurred
IF (#tempInternalError <> #NO_INTERNAL_ERROR) THEN
#error := true;
#status := #ERR_REPLACE_ITEM_BY_INIT_VALUE;
#subFunctionStatus := INT_TO_WORD(#tempInternalError);
RETURN;
END_IF;
// calculate the new index of the first entry
#tempNewFirstItemIndex := #statFirstItemIndex + #INCREMENT;
#tempNewFirstItemIndex := #tempNewFirstItemIndex MOD UDINT_TO_INT(#tempBufferSize);
// check whether the ring buffer is empty
IF (#statNextEmptyItemIndex = #tempNewFirstItemIndex) THEN
// If the ring buffer is empty, the index is set to 0
#statFirstItemIndex := #BUFFER_INITIALIZED;
#statNextEmptyItemIndex := #EMPTY_INITIALIZED;
ELSE
// The index of the first entry is changed
#statFirstItemIndex := #tempNewFirstItemIndex;
END_IF;
// Evaluation of the number of elements in the stack
#statElementCount -= #INCREMENT;
#dequeueDone := TRUE; // !!!!!!!!!!!
#statEdgesMem.dequeue := FALSE;
END_REGION dequeue
ELSIF #tempEdges.enqueue THEN
REGION enqueue
// check whether the ring #buffer is full
// IF this is the CASE, program execution is terminated at this point
IF (#statNextEmptyItemIndex = #statFirstItemIndex) THEN
#error := true;
#status := #ERR_BUFFER_FULL;
#subFunctionStatus := #STATUS_NO_ERROR;
RETURN;
END_IF;
// write the entry to the ring buffer
#tempInternalError := MOVE_BLK_VARIANT(SRC := #itemIn,
COUNT := #COUNT_ELEMENTS,
SRC_INDEX := #INDEX_BEGINNING,
DEST_INDEX := #statNextEmptyItemIndex,
DEST => #buffer);
// check whether a local error has occurred
IF (#tempInternalError <> #NO_INTERNAL_ERROR) THEN
#error := true;
#status := #ERR_WRITE_ENTRY;
#subFunctionStatus := INT_TO_WORD(#tempInternalError);
RETURN;
END_IF;
// increment the index by 1 and calculates the new empty entry index
#tempNewNextEmptyItemIndex := (#statNextEmptyItemIndex + #INCREMENT) MOD UDINT_TO_INT(#tempBufferSize);
#statNextEmptyItemIndex := #tempNewNextEmptyItemIndex;
// check which index the "#firstItemIndex" tag has
// IF the number = -1, the ring buffer is initialized
// AND the entry is written TO the ring #buffer
// Therefore, "0" must be assigned TO the tag
IF (#statFirstItemIndex = #BUFFER_INITIALIZED) THEN
#statFirstItemIndex := #INDEX_BEGINNING;
END_IF;
// Evaluation of the number of elements in the stack
#statElementCount += #INCREMENT;
#enqueueDone := TRUE;
#statEdgesMem.enqueue := FALSE;
END_REGION enqueue
END_IF;
END_REGION
REGION Writing to outputs
#oldestElement := #statFirstItemIndex; // HINZUGEFÜGT!!!
#elementCount := DINT_TO_USINT(#statElementCount);
#isEmpty := #statElementCount <= #ZERO_ELEMENTS;
#isFull := #statElementCount >= #maxElementCount;
#error := false;
#status := #STATUS_NO_ERROR;
#subFunctionStatus := #STATUS_NO_ERROR;
// no error handling by ENO needed
ENO := TRUE;
END_REGION
END_FUNCTION_BLOCK