Compare commits

...

11 Commits

442 changed files with 98389 additions and 29 deletions
@@ -0,0 +1,12 @@
LibraryType:
Guid: f8c50fdf-18cb-49d8-bf63-620c65163568
Comment:
de-DE: Dieser Baustein generiert einen Blinktakt mit variabler Zeit.
LibraryVersion:
VersionNumber: 2.0.0
Author: e.yueksel
IsDefault: true
Comment:
de-DE: |-
Dieser Baustein generiert einen Blinktakt mit variabler Zeit.
Freigegeben für Inbetriebnahme (EY, 22.04.2025)
@@ -0,0 +1,6 @@
DocumentHash:
- FileName: FB_Blinker.scl
Hash: 7BD6hj5VYn+rKNDdupCZ7URQVKvXdDd/Ugg8DHpghIY=
LibraryMetaFileHash: E7qOimsmciFEInzFA+XMEIrhTgTKp9xNTj8qMkDXBz0=
LibraryVersion:
Guid: fa6b40b5-8048-40b8-9a10-460377c0a038
+80
View File
@@ -0,0 +1,80 @@
FUNCTION_BLOCK "FB_Blinker"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
VAR_INPUT
tInPeriodicTime : Time := T#500ms; // Eingestellte Zeit, entspricht 1/2*Clock
xInActivate : Bool; // true = Dauerblinken, false = Zeit pausieren
END_VAR
VAR_OUTPUT
xOutput : Bool; // eingestellte Zeit true, eingestellte Zeit false usw.
xOutFlag : Bool; // Flanke von xOutput
END_VAR
VAR
rTrigSignal {InstructionName := 'R_TRIG'; LibVersion := '1.0'} : R_TRIG;
xSync : Bool;
timerTON {InstructionName := 'TON_TIME'; LibVersion := '1.0'} : TON_TIME;
END_VAR
VAR RETAIN
timerTONR {InstructionName := 'TONR_TIME'; LibVersion := '1.0'} : TONR_TIME;
END_VAR
VAR
tTONTime : Time; // Verarbeitete Zeit
END_VAR
VAR RETAIN
xTONStart : Bool; // IN-Signal für Timer
xSignal : Bool; // Merker für Ausgangszustand
END_VAR
VAR_TEMP
xReset : Bool; // Bit um im Takt den Timer zu reseten
END_VAR
BEGIN
#xSignal := #xOutput;
REGION Cycle
IF #tInPeriodicTime = T#0s THEN
#tTONTime := T#500ms;//Defaultwert
ELSE
#tTONTime := #tInPeriodicTime;//Zeit durch Eingabe
END_IF;
IF #timerTONR.Q THEN //wenn Timer abgelaufen.....
IF #xSignal THEN //aktueller Zustand wird gewechselt
#xSignal := 0;
ELSE //aktueller Zustand wird gewechselt
#xSignal := 1;
END_IF;
#xTONStart := 0; //...dann nimm Eingangssignal weg...
#xReset := TRUE; //...und rücksetze Timer
ELSE
#xTONStart := 1;
END_IF;
IF #xSync (*OR (#TimerTONTime <> #TimerTON.PT) *) THEN
#xSync := 0;
#xTONStart := 0;
#xSignal := 0;
END_IF;
END_REGION
#rTrigSignal(CLK:=#xSignal);
REGION Outputs
#xOutput := #xSignal;
#xOutFlag := #rTrigSignal.Q;
END_REGION
REGION Timer
// #TimerTON(IN := #xTimerTONStart,
// PT := #TimerTONTime);
#timerTONR(IN:=NOT #xReset AND #xTONStart AND #xInActivate,
R:=#xReset,
PT:=#tTONTime);
END_REGION
END_FUNCTION_BLOCK
@@ -0,0 +1,12 @@
LibraryType:
Guid: 13212dbb-fcc6-4125-b5ed-06ae06c3e32a
Comment:
de-DE: Letzte Zykluszeit ermitteln ("First Scan" muss aktiviert sein)
LibraryVersion:
VersionNumber: 2.0.0
Author: e.yueksel
IsDefault: true
Comment:
de-DE: |-
Letzte Zykluszeit ermitteln ("First Scan" muss aktiviert sein)
Freigegeben für IBN (EY, 22.04.2025)
@@ -0,0 +1,6 @@
DocumentHash:
- FileName: FB_CycleTime.scl
Hash: 2Z6NJMSKGY05RyA+gla5h62TX6LIB5u3QhWELu+SPK4=
LibraryMetaFileHash: SFLc5/VUD4IaggRRMBqedlgDMtDuKtPjaRskpHX46E8=
LibraryVersion:
Guid: 25d2e38e-f4fc-4204-8d07-336d2fe1fa8c
@@ -0,0 +1,34 @@
FUNCTION_BLOCK "FB_CycleTime"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
VAR_OUTPUT
CycleTime : DInt;
END_VAR
VAR
TimeOld : DInt;
TimeNew : DInt;
END_VAR
BEGIN
//letzte Zykluszeit ermitteln
IF "FirstScan" THEN
//first Cycle
//no Cycletime
#TimeNew := TIME_TCK();
#CycleTime := 0;
#TimeOld := TIME_TCK();
ELSE
#TimeNew := TIME_TCK();
IF #TimeNew < #TimeOld THEN
//Systemzeit übergelaufen
#CycleTime := 2147483647 - #TimeOld + #TimeNew;
ELSE
#CycleTime := #TimeNew - #TimeOld;
END_IF;
#TimeOld := #TimeNew;
END_IF;
END_FUNCTION_BLOCK
@@ -0,0 +1,14 @@
LibraryType:
Guid: bc5be256-7a5d-4ae4-aac8-c04ee556905a
Comment:
de-DE: |-
Liest lokale Systemzeit und gibt als String aus
Format: '21-05-12'
LibraryVersion:
VersionNumber: 2.0.0
Author: e.yueksel
IsDefault: true
Comment:
de-DE: |-
Liest lokale Systemzeit und gibt als String aus
Format: '21-05-12'
@@ -0,0 +1,6 @@
DocumentHash:
- FileName: FC_DateAsString.scl
Hash: sxW9MGlJNzQwHlUucUIrXWLqFFj9XVJTFDBvIpZg2Qs=
LibraryMetaFileHash: 6Yo0WP5KqjVpHhTLfUTFC+re32KTNH1ye9pj7xdoYqc=
LibraryVersion:
Guid: 34059056-04c6-4b56-b5a2-abd5a842540e
@@ -0,0 +1,38 @@
FUNCTION "FC_DateAsString" : String
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
VAR_TEMP
tInt : Int;
tDTL {InstructionName := 'DTL'; LibVersion := '1.0'} : DTL;
sTmp : String[5];
END_VAR
BEGIN
// Format: '21-05-12'
#tInt := RD_LOC_T(#tDTL);
#sTmp := UINT_TO_STRING(#tDTL.YEAR);
#FC_DateAsString[1] := #sTmp[4];
#FC_DateAsString[2] := #sTmp[5];
#FC_DateAsString[3] := '-';
#sTmp := USINT_TO_STRING(#tDTL.MONTH);
IF #tDTL.MONTH <= 9 THEN
#FC_DateAsString[4] := '0';
#FC_DateAsString[5] := #sTmp[2];
ELSE
#FC_DateAsString[4] := #sTmp[2];
#FC_DateAsString[5] := #sTmp[3];
END_IF;
#FC_DateAsString[6] := '-';
#sTmp := USINT_TO_STRING(#tDTL.DAY);
IF #tDTL.DAY <= 9 THEN
#FC_DateAsString[7] := '0';
#FC_DateAsString[8] := #sTmp[2];
ELSE
#FC_DateAsString[7] := #sTmp[2];
#FC_DateAsString[8] := #sTmp[3];
END_IF;
END_FUNCTION
@@ -0,0 +1,6 @@
LibraryType:
Guid: 75fdb852-33f8-4860-bfe0-74c853d48987
LibraryVersion:
VersionNumber: 2.0.0
Author: e.yueksel
IsDefault: true
@@ -0,0 +1,6 @@
DocumentHash:
- FileName: FC_RemoveStringPart.scl
Hash: M/GpwHJPz23hLSM9fCEJmNAQWH5VNKnkCvRvibwFVuI=
LibraryMetaFileHash: YxePwWkwi+6JBpfN1P+bJ2t85wqoDQfUarH23N+mI1o=
LibraryVersion:
Guid: c0a01750-6a1f-47ba-b034-8732c973f038
@@ -0,0 +1,27 @@
FUNCTION "FC_RemoveStringPart" : String
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
VAR_INPUT
sSource : String;
sRemove : String;
END_VAR
VAR_TEMP
nLen : Int;
nPos : Int;
END_VAR
BEGIN
#nLen := LEN(#sRemove);
#nPos := FIND(IN1:=#sSource, IN2:=#sRemove);
IF #nPos > 0 THEN
#FC_RemoveStringPart := DELETE(IN := #sSource,
L := #nLen,
P := #nPos);
ELSE
#FC_RemoveStringPart := #sSource;
END_IF;
END_FUNCTION
@@ -0,0 +1,10 @@
LibraryType:
Guid: 934482b5-e58d-48b7-95c0-95843c18790d
Comment:
de-DE: Liest Systemzeit und gibt Uhrzeit als String aus
LibraryVersion:
VersionNumber: 2.0.0
Author: e.yueksel
IsDefault: true
Comment:
de-DE: Liest Systemzeit und gibt Uhrzeit als String aus
@@ -0,0 +1,6 @@
DocumentHash:
- FileName: FC_TimeAsString.scl
Hash: 3WJUl9RFht2vorDlH8QAIOs7AhSUh8JVzkcdrRKQwZo=
LibraryMetaFileHash: rKdgHvTDa65A90nGw/BUqSQ1XoRp0ZITlOxvdtrZTnQ=
LibraryVersion:
Guid: 4a99e138-618d-44bb-915f-75873870e021
@@ -0,0 +1,83 @@
FUNCTION "FC_TimeAsString" : String
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
VAR_TEMP
tInt : DInt;
tDTL {InstructionName := 'DTL'; LibVersion := '1.0'} : DTL;
sTmp : String[10];
END_VAR
BEGIN
#tInt := RD_LOC_T(#tDTL);
#sTmp := UINT_TO_STRING(#tDTL.HOUR);
IF #tDTL.HOUR < 10 THEN
#FC_TimeAsString[1] := '0';
#FC_TimeAsString[2] := #sTmp[2];
ELSE
#FC_TimeAsString[1] := #sTmp[2];
#FC_TimeAsString[2] := #sTmp[3];
END_IF;
#FC_TimeAsString[3] := ':';
#sTmp := USINT_TO_STRING(#tDTL.MINUTE);
IF #tDTL.MINUTE < 10 THEN
#FC_TimeAsString[4] := '0';
#FC_TimeAsString[5] := #sTmp[2];
ELSE
#FC_TimeAsString[4] := #sTmp[2];
#FC_TimeAsString[5] := #sTmp[3];
END_IF;
#FC_TimeAsString[6] := ':';
#sTmp := USINT_TO_STRING(#tDTL.SECOND);
IF #tDTL.SECOND < 10 THEN
#FC_TimeAsString[7] := '0';
#FC_TimeAsString[8] := #sTmp[2];
ELSE
#FC_TimeAsString[7] := #sTmp[2];
#FC_TimeAsString[8] := #sTmp[3];
END_IF;
#FC_TimeAsString[9] := ',';
#sTmp := UDINT_TO_STRING(#tDTL.NANOSECOND);
IF #tDTL.NANOSECOND < 1000000 THEN
#FC_TimeAsString[10] := '0';
#FC_TimeAsString[11] := '0';
#FC_TimeAsString[12] := '0';
ELSIF #tDTL.NANOSECOND < 10000000 THEN
#FC_TimeAsString[10] := '0';
#FC_TimeAsString[11] := '0';
#FC_TimeAsString[12] := #sTmp[2];
ELSIF #tDTL.NANOSECOND < 100000000 THEN
#FC_TimeAsString[10] := '0';
#FC_TimeAsString[11] := #sTmp[2];
#FC_TimeAsString[12] := #sTmp[3];
ELSE
#FC_TimeAsString[10] := #sTmp[2];
#FC_TimeAsString[11] := #sTmp[3];
#FC_TimeAsString[12] := #sTmp[4];
END_IF;
END_FUNCTION
@@ -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
@@ -0,0 +1,10 @@
LibraryType:
Guid: 6c4bda0f-d233-468b-bd07-c2cb4b4a20ba
Comment:
de-DE: Betriebsstundenzähler
LibraryVersion:
VersionNumber: 2.0.0
Author: e.yueksel
IsDefault: true
Comment:
de-DE: Runtime monitoring
@@ -0,0 +1,9 @@
DocumentHash:
- FileName: FB_RTM.scl
Hash: ymZJIjIGGyLS2y0mLBHHE3+IcE1xLGWueL/FYcOvYDQ=
LibraryMetaFileHash: 31HNXsPryxvRfGOs/6Ktg3CxEscSNN46DFHpoT9qcWw=
LibraryVersion:
Guid: 752adfe9-6576-4cf0-831e-d62dd93f5f27
DependsOn:
- TypeName: UDT_RTM
VersionNumber: 2.0.0
@@ -0,0 +1,105 @@
FUNCTION_BLOCK "FB_RTM"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
VAR_INPUT
xEnable : Bool;
xClock : Bool;
END_VAR
VAR_IN_OUT
stRTM : "UDT_RTM";
END_VAR
BEGIN
REGION Betriebsstundenzähler / RTM
IF #xEnable THEN
REGION Total-Counter
#stRTM.stTotalCounter.nSecond := #stRTM.stTotalCounter.nSecond + BOOL_TO_INT(#xClock);
#stRTM.stTotalCounter.nMinute := #stRTM.stTotalCounter.nMinute + BOOL_TO_INT(#stRTM.stTotalCounter.nSecond >= 60);
#stRTM.stTotalCounter.nHour := #stRTM.stTotalCounter.nHour + BOOL_TO_DINT(#stRTM.stTotalCounter.nMinute >= 60);
#stRTM.stTotalCounter.nSecond := #stRTM.stTotalCounter.nSecond MOD 60;
#stRTM.stTotalCounter.nMinute := #stRTM.stTotalCounter.nMinute MOD 60;
END_REGION
REGION Charge-Counter
#stRTM.stChargeCounter.nSecond := #stRTM.stChargeCounter.nSecond + BOOL_TO_INT(#xClock);
#stRTM.stChargeCounter.nMinute := #stRTM.stChargeCounter.nMinute + BOOL_TO_INT(#stRTM.stChargeCounter.nSecond >= 60);
#stRTM.stChargeCounter.nHour := #stRTM.stChargeCounter.nHour + BOOL_TO_DINT(#stRTM.stChargeCounter.nMinute >= 60);
#stRTM.stChargeCounter.nSecond := #stRTM.stChargeCounter.nSecond MOD 60;
#stRTM.stChargeCounter.nMinute := #stRTM.stChargeCounter.nMinute MOD 60;
END_REGION
REGION Maintenance-Counter
#stRTM.stMaintenance.nSecond := #stRTM.stMaintenance.nSecond + BOOL_TO_INT(#xClock);
#stRTM.stMaintenance.nMinute := #stRTM.stMaintenance.nMinute + BOOL_TO_INT(#stRTM.stMaintenance.nSecond >= 60);
#stRTM.stMaintenance.nHour := #stRTM.stMaintenance.nHour - BOOL_TO_INT(#stRTM.stMaintenance.nMinute >= 60);
#stRTM.stMaintenance.nSecond := #stRTM.stMaintenance.nSecond MOD 60;
#stRTM.stMaintenance.nMinute := #stRTM.stMaintenance.nMinute MOD 60;
END_REGION
REGION Zero
IF #stRTM.stMaintenance.nHour < 0 THEN
#stRTM.stMaintenance.nHour := 0;
#stRTM.stMaintenance.nMinute := 0;
#stRTM.stMaintenance.nSecond := 0;
END_IF;
END_REGION
END_IF;
END_REGION
REGION Reset
REGION Reset Charge Counter
IF #stRTM.stFlags.xResetCharge THEN
#stRTM.stChargeCounter.nHour := 0;
#stRTM.stChargeCounter.nMinute := 0;
#stRTM.stChargeCounter.nSecond := 0;
#stRTM.stFlags.xResetCharge := FALSE;
END_IF;
END_REGION
REGION Reset Maintenance Counter
IF #stRTM.stFlags.xResetMaintenance THEN
#stRTM.stMaintenance.nHour := #stRTM.stMaintenance.nIntervall;
#stRTM.stMaintenance.nMinute := 0;
#stRTM.stMaintenance.nSecond := 0;
#stRTM.stFlags.xResetMaintenance := FALSE;
END_IF;
END_REGION
END_REGION
REGION Limit values
#stRTM.stMaintenance.nWarning := MIN(IN1:= #stRTM.stMaintenance.nWarning, IN2:= #stRTM.stMaintenance.nIntervall);
IF #stRTM.stMaintenance.nHour > #stRTM.stMaintenance.nIntervall THEN
#stRTM.stMaintenance.nHour := #stRTM.stMaintenance.nIntervall;
#stRTM.stMaintenance.nMinute := 0;
#stRTM.stMaintenance.nSecond := 0;
END_IF;
END_REGION
REGION Status
#stRTM.stFlags.xMaintenance := #stRTM.stMaintenance.nHour <= 0 AND #stRTM.stMaintenance.nIntervall > 0;
#stRTM.stFlags.xWarning := #stRTM.stMaintenance.nHour <= #stRTM.stMaintenance.nWarning AND #stRTM.stMaintenance.nWarning > 0;
#stRTM.stFlags.xWarning := #stRTM.stFlags.xWarning AND NOT #stRTM.stFlags.xMaintenance;
#stRTM.stFlags.nState := SEL(G := #stRTM.stFlags.xWarning, IN0 := 0, IN1 := 1);
#stRTM.stFlags.nState := SEL(G := #stRTM.stFlags.xMaintenance, IN0 := #stRTM.stFlags.nState, IN1 := 2);
END_REGION
END_FUNCTION_BLOCK
@@ -0,0 +1,8 @@
LibraryType:
Guid: 5b22b7a0-2178-4944-a91a-0554edd65f42
LibraryVersion:
VersionNumber: 2.0.0
Author: e.yueksel
IsDefault: true
Comment:
de-DE: Run time monitoring
@@ -0,0 +1,13 @@
DocumentHash:
- FileName: UDT_RTM.xml
Hash: Jz8w0u3bv3kyg1JteRl6e66LDncsx//c2I0x6quNxDk=
LibraryMetaFileHash: 3tJC4RrE/dALu5EIsH0uLUvJsp2VhfR3OeMesRTRsJI=
LibraryVersion:
Guid: 3af2b460-c36e-47b7-a1f9-870396d05bd7
DependsOn:
- TypeName: UDT_RTM_Time
VersionNumber: 2.0.0
- TypeName: UDT_RTM_Maintenance
VersionNumber: 2.0.0
- TypeName: UDT_RTM_Flags
VersionNumber: 2.0.0
@@ -0,0 +1,56 @@
<?xml version="1.0" encoding="utf-8"?>
<Document>
<Engineering version="V20" />
<SW.Types.PlcStruct ID="0">
<AttributeList>
<Interface><Sections xmlns="http://www.siemens.com/automation/Openness/SW/Interface/v5">
<Section Name="None">
<Member Name="stTotalCounter" Datatype="&quot;UDT_RTM_Time&quot;">
<AttributeList>
<BooleanAttribute Name="SetPoint" SystemDefined="true">true</BooleanAttribute>
</AttributeList>
</Member>
<Member Name="stChargeCounter" Datatype="&quot;UDT_RTM_Time&quot;">
<AttributeList>
<BooleanAttribute Name="SetPoint" SystemDefined="true">true</BooleanAttribute>
</AttributeList>
</Member>
<Member Name="stMaintenance" Datatype="&quot;UDT_RTM_Maintenance&quot;">
<AttributeList>
<BooleanAttribute Name="SetPoint" SystemDefined="true">true</BooleanAttribute>
</AttributeList>
</Member>
<Member Name="stFlags" Datatype="&quot;UDT_RTM_Flags&quot;">
<AttributeList>
<BooleanAttribute Name="SetPoint" SystemDefined="true">true</BooleanAttribute>
</AttributeList>
</Member>
</Section>
</Sections></Interface>
<Name>UDT_RTM</Name>
<Namespace />
</AttributeList>
<ObjectList>
<MultilingualText ID="1" CompositionName="Comment">
<ObjectList>
<MultilingualTextItem ID="2" CompositionName="Items">
<AttributeList>
<Culture>de-DE</Culture>
<Text />
</AttributeList>
</MultilingualTextItem>
</ObjectList>
</MultilingualText>
<MultilingualText ID="3" CompositionName="Title">
<ObjectList>
<MultilingualTextItem ID="4" CompositionName="Items">
<AttributeList>
<Culture>de-DE</Culture>
<Text />
</AttributeList>
</MultilingualTextItem>
</ObjectList>
</MultilingualText>
</ObjectList>
</SW.Types.PlcStruct>
</Document>
@@ -0,0 +1,8 @@
LibraryType:
Guid: 57d3de27-8412-4acc-a5a8-e11b5f7b8b97
LibraryVersion:
VersionNumber: 2.0.0
Author: e.yueksel
IsDefault: true
Comment:
de-DE: Run time monitoring
@@ -0,0 +1,6 @@
DocumentHash:
- FileName: UDT_RTM_Flags.xml
Hash: piMwP5JQiY++cWDND3c02GQsWnhEi9BMUlUbOiOmB3Q=
LibraryMetaFileHash: DL67+az3ZAISL96WmoV/d2neoW+fAIBmMGAmXK1Adlk=
LibraryVersion:
Guid: 06ef58da-e439-4df1-8ef3-6e8edf74d554
@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<Document>
<Engineering version="V20" />
<SW.Types.PlcStruct ID="0">
<AttributeList>
<Interface><Sections xmlns="http://www.siemens.com/automation/Openness/SW/Interface/v5">
<Section Name="None">
<Member Name="xResetCharge" Datatype="Bool" />
<Member Name="xResetMaintenance" Datatype="Bool" />
<Member Name="xWarning" Datatype="Bool" />
<Member Name="xMaintenance" Datatype="Bool" />
<Member Name="nState" Datatype="Int" />
</Section>
</Sections></Interface>
<Name>UDT_RTM_Flags</Name>
<Namespace />
</AttributeList>
<ObjectList>
<MultilingualText ID="1" CompositionName="Comment">
<ObjectList>
<MultilingualTextItem ID="2" CompositionName="Items">
<AttributeList>
<Culture>de-DE</Culture>
<Text />
</AttributeList>
</MultilingualTextItem>
</ObjectList>
</MultilingualText>
<MultilingualText ID="3" CompositionName="Title">
<ObjectList>
<MultilingualTextItem ID="4" CompositionName="Items">
<AttributeList>
<Culture>de-DE</Culture>
<Text />
</AttributeList>
</MultilingualTextItem>
</ObjectList>
</MultilingualText>
</ObjectList>
</SW.Types.PlcStruct>
</Document>
@@ -0,0 +1,8 @@
LibraryType:
Guid: 7ae2232d-8d12-4e5a-8096-4e1154c44e75
LibraryVersion:
VersionNumber: 2.0.0
Author: e.yueksel
IsDefault: true
Comment:
de-DE: Run time monitoring
@@ -0,0 +1,6 @@
DocumentHash:
- FileName: UDT_RTM_Maintenance.xml
Hash: KXV53rFL0ONooLjl08qJ73DjMpOsI9S8luaWGgluJG4=
LibraryMetaFileHash: 0l0zZpMtg/sKV4XRWqLlL+bHKf6Gr4YBebFrG2+GZSQ=
LibraryVersion:
Guid: 3f388807-4b41-4a6d-8f8a-c60ab16ba84f
@@ -0,0 +1,41 @@
<?xml version="1.0" encoding="utf-8"?>
<Document>
<Engineering version="V20" />
<SW.Types.PlcStruct ID="0">
<AttributeList>
<Interface><Sections xmlns="http://www.siemens.com/automation/Openness/SW/Interface/v5">
<Section Name="None">
<Member Name="nHour" Datatype="Int" />
<Member Name="nMinute" Datatype="Int" />
<Member Name="nSecond" Datatype="Int" />
<Member Name="nIntervall" Datatype="Int" />
<Member Name="nWarning" Datatype="Int" />
</Section>
</Sections></Interface>
<Name>UDT_RTM_Maintenance</Name>
<Namespace />
</AttributeList>
<ObjectList>
<MultilingualText ID="1" CompositionName="Comment">
<ObjectList>
<MultilingualTextItem ID="2" CompositionName="Items">
<AttributeList>
<Culture>de-DE</Culture>
<Text />
</AttributeList>
</MultilingualTextItem>
</ObjectList>
</MultilingualText>
<MultilingualText ID="3" CompositionName="Title">
<ObjectList>
<MultilingualTextItem ID="4" CompositionName="Items">
<AttributeList>
<Culture>de-DE</Culture>
<Text />
</AttributeList>
</MultilingualTextItem>
</ObjectList>
</MultilingualText>
</ObjectList>
</SW.Types.PlcStruct>
</Document>
@@ -0,0 +1,8 @@
LibraryType:
Guid: ee61d29b-02c2-4515-9554-eb11b12ed45f
LibraryVersion:
VersionNumber: 2.0.0
Author: e.yueksel
IsDefault: true
Comment:
de-DE: Run time monitoring
@@ -0,0 +1,6 @@
DocumentHash:
- FileName: UDT_RTM_Time.xml
Hash: xrTn+38zmregXA1kyMDhBDG+Cv8N4H+pzpG58WuOv4A=
LibraryMetaFileHash: baZKaT+d3x+N8QxCkx2ofQMcTRH4wa5UFiPci6wPnYo=
LibraryVersion:
Guid: 0b2dcfae-8c5e-4ffb-aa55-beecd9f70432
@@ -0,0 +1,39 @@
<?xml version="1.0" encoding="utf-8"?>
<Document>
<Engineering version="V20" />
<SW.Types.PlcStruct ID="0">
<AttributeList>
<Interface><Sections xmlns="http://www.siemens.com/automation/Openness/SW/Interface/v5">
<Section Name="None">
<Member Name="nHour" Datatype="DInt" />
<Member Name="nMinute" Datatype="Int" />
<Member Name="nSecond" Datatype="Int" />
</Section>
</Sections></Interface>
<Name>UDT_RTM_Time</Name>
<Namespace />
</AttributeList>
<ObjectList>
<MultilingualText ID="1" CompositionName="Comment">
<ObjectList>
<MultilingualTextItem ID="2" CompositionName="Items">
<AttributeList>
<Culture>de-DE</Culture>
<Text />
</AttributeList>
</MultilingualTextItem>
</ObjectList>
</MultilingualText>
<MultilingualText ID="3" CompositionName="Title">
<ObjectList>
<MultilingualTextItem ID="4" CompositionName="Items">
<AttributeList>
<Culture>de-DE</Culture>
<Text />
</AttributeList>
</MultilingualTextItem>
</ObjectList>
</MultilingualText>
</ObjectList>
</SW.Types.PlcStruct>
</Document>
@@ -0,0 +1,10 @@
LibraryType:
Guid: f40dd329-3f8e-45dd-898b-24da6076f332
Comment:
de-DE: 'Hauptzustandmaschine '
LibraryVersion:
VersionNumber: 2.0.0
Author: e.yueksel
IsDefault: true
Comment:
de-DE: stInOutControlUnitCabinet.xRestart wird jetzt benutzt
@@ -0,0 +1,11 @@
DocumentHash:
- FileName: FB_StateMain.scl
Hash: Nmmlczx8daiTq972/VPJUQ66oPeA5dceWjGNpRZf/6s=
LibraryMetaFileHash: 26KqGD4lRmtnuQv7YFrKjngcYTZuuY6+furs2L/j9lI=
LibraryVersion:
Guid: 78bc094a-ba36-410e-bb5c-9dc8345824b9
DependsOn:
- TypeName: UDT_MainState
VersionNumber: 2.0.0
- TypeName: UDT_HMI_StateMachine
VersionNumber: 2.0.0
@@ -0,0 +1,237 @@
FUNCTION_BLOCK "FB_StateMain"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
VAR_INPUT
xInBtnMachineOn : Bool; // Anlage Ein
xInBtnMachineNotOff : Bool; // Anlage Aus
xInBtnLightTest : Bool; // Lampentest
xInBtnTrigMot : Bool; // Trig Mot
xInBtnQuitError : Bool; // Start nach Störung
xInAllReadyToStart : Bool; // Alles bereit
xInAllInExecute : Bool; // Alle Antriebe in Run
xInAllStarted : Bool; // Starten erfolgreich beendet
xInSafetyActive : Bool; // Safety aktiv
xInAllInSafeState : Bool; // Alles im sicheren Status
stSettings : Struct // Einstellungen
tCancelStarting : Time := t#10s;
xEnableStartUpWarning : Bool;
xPressMachineOnAllTime : Bool;
tStartUpTime : Time := T#3s;
END_STRUCT;
END_VAR
VAR_IN_OUT
stInOutControlUnitCabinet : "UDT_MainState"; // Schnittstelle MainState
stInOutHMI : "UDT_HMI_StateMachine"; // NUR FÜR HMI
END_VAR
VAR
nState : Int := -10; // Schritt
sStateText : String; // Schritttext
tOnStartUpTimer {InstructionName := 'TON_TIME'; LibVersion := '1.0'} : TON_TIME; // Anlaufverzögerung
nConveyorStartUpCounter : Int; // Counter Förderer
xQuitErrorFlag : Bool; // Start nach Störung Flag
stControl : Struct // Start,Stop,Quit
xStart : Bool;
xStop : Bool;
xQuitt : Bool;
END_STRUCT;
END_VAR
VAR_TEMP
nCounter : Int;
nNoStartingAct : Int;
END_VAR
BEGIN
REGION MainStateMachine
CASE #nState OF
"E_DeviceState.eUndefined":
REGION Undefined
#sStateText := 'StartUp';
#nState := "E_DeviceState.eStopped";
END_REGION ;
"E_DeviceState.eStopped":
REGION Stopped
#sStateText := 'Stopped';
IF #xInAllReadyToStart AND NOT #stInOutControlUnitCabinet.xStopMachine THEN
#nState := "E_DeviceState.eIdle";
END_IF;
#stInOutControlUnitCabinet.xStopMachine := FALSE;
END_REGION ;
"E_DeviceState.eIdle":
REGION IDLE
#sStateText := 'Idle';
IF NOT #xInAllReadyToStart OR #stInOutControlUnitCabinet.xStopMachine THEN
#nState := "E_DeviceState.eStopped";
ELSIF (#xInBtnMachineOn OR #stInOutHMI.xStart OR #stControl.xStart)AND (((#xInBtnMachineNotOff AND NOT #stControl.xStop AND NOT #stInOutHMI.xStop) AND NOT #stControl.xStop AND NOT #stInOutHMI.xStop) AND NOT #stControl.xStop AND NOT #stInOutHMI.xStop) THEN
#nState := "E_DeviceState.eStarting";
#stControl.xStart := FALSE;
END_IF;
END_REGION ;
"E_DeviceState.eStarting":
REGION Starting
#sStateText := 'Start UP Warning Time';
IF NOT #xInAllReadyToStart OR #stInOutControlUnitCabinet.xStopMachine THEN
#nState := "E_DeviceState.eStopped";
ELSIF #xInAllStarted AND
(NOT #stSettings.xEnableStartUpWarning OR
(#stSettings.xEnableStartUpWarning AND #tOnStartUpTimer.Q)) THEN
#nState := 120;
ELSIF (NOT #xInBtnMachineOn AND #stSettings.xPressMachineOnAllTime)
OR NOT #xInBtnMachineNotOff OR
#tOnStartUpTimer.ET > #stSettings.tCancelStarting
THEN
#nState := "E_DeviceState.eStopping";
END_IF;
END_REGION ;
120:
REGION Waiting for All in Excecute
#sStateText := 'Waiting for All in Execute';
IF #xInAllInExecute THEN
#nState := "E_DeviceState.eExecute";
#nConveyorStartUpCounter := 0;
ELSIF NOT ((#xInBtnMachineNotOff AND NOT #stControl.xStop AND NOT #stInOutHMI.xStop) AND NOT #stControl.xStop AND NOT #stInOutHMI.xStop) OR #stInOutControlUnitCabinet.xStopMachine THEN
#nState := "E_DeviceState.eStopping";
END_IF;
END_REGION
"E_DeviceState.eExecute":
REGION Execute
#sStateText := 'Execute';
IF NOT #xInSafetyActive THEN
#nState := "E_DeviceState.eHolding";
#nConveyorStartUpCounter := 0;
ELSIF NOT (#xInBtnMachineNotOff AND NOT #stControl.xStop AND NOT #stInOutHMI.xStop) OR #stInOutControlUnitCabinet.xStopMachine THEN
#nState := "E_DeviceState.eStopping";
ELSIF FALSE THEN
#nState := "E_DeviceState.eSuspending";
END_IF;
IF #nConveyorStartUpCounter < 6000 THEN
#nConveyorStartUpCounter := #nConveyorStartUpCounter + 1;
ELSIF #xInBtnTrigMot THEN
#nConveyorStartUpCounter := 0;
END_IF;
END_REGION ;
"E_DeviceState.eHolding":
#sStateText := 'HOLDING: When the machine is in the EXECUTE state the Hold command can be used to start HOLDING logic which brings the machine to a controlled stop or to a state which represents HELD for the particular machine mode. ';
#nState := "E_DeviceState.eHeld";
"E_DeviceState.eHeld":
REGION Held
#sStateText := 'HELD: The HELD state would typically be used by the operator to hold the temporarily hold the machines operation whilst material blockages are cleared, or to stop throughput whilst a downstream problem is resolved.';
IF (NOT (#xInBtnMachineNotOff AND NOT #stInOutHMI.xStop)) OR #stInOutControlUnitCabinet.xStopMachine THEN
#nState := "E_DeviceState.eStopping";
ELSIF #xInSafetyActive THEN
#nState := "E_DeviceState.eUnholding";
END_IF;
END_REGION ;
"E_DeviceState.eUnholding":
REGION Unholding
#sStateText := 'Un-Holding: The UNHOLDING state is typically a response to an operator command to resume EXECUTE state. UNHOLDING prepares the machine to re-enter the EXECUTE state.';
IF NOT #stSettings.xEnableStartUpWarning OR
(#stSettings.xEnableStartUpWarning AND #tOnStartUpTimer.Q) THEN
#nState := "E_DeviceState.eExecute";
END_IF;
END_REGION
"E_DeviceState.eSuspending":
#sStateText := 'SUSPENDING: This state is a result of a command change from the EXECUTE state. This state is typically required prior to the SUSPENDED wait state, and prepares the machine (ie stops glue cycles, stops carton feeds, etc) prior to the SUSPEND state.';
#nState := "E_DeviceState.eSuspended";
"E_DeviceState.eSuspended":
REGION Suspended
#sStateText := 'SUSPENDED: The machine may be running at the relevant setpoint speed, there is no product being produced. This state can be reached as a result of a machine status, and differs from HELD in that HELD is typically a result of an operator request.';
IF NOT (#xInBtnMachineNotOff AND NOT #stControl.xStop AND NOT #stInOutHMI.xStop) OR #stInOutControlUnitCabinet.xStopMachine THEN
#nState := "E_DeviceState.eStopping";
ELSIF TRUE THEN
#nState := "E_DeviceState.eUnsuspending";
END_IF;
END_REGION ;
"E_DeviceState.eUnsuspending":
#sStateText := 'UN-SUSPENDING: This state is a result of a request from SUSPENDED state to go back to the EXECUTE state. This actions of this state may include: ramping up speeds, turning on vaccums, the re-engagement of clutches.';
(*IF NOT #xInSafetyOk THEN
#nState := "E_DeviceState.eHolding";
ELSE *)
#nState := "E_DeviceState.eExecute";
(* END_IF; *)
"E_DeviceState.eStopping":
REGION Stopping
#sStateText := 'Stopping';
#nState := 5010;
END_REGION
5010:
#sStateText := 'Waiting for Safe State';
IF #xInAllInSafeState THEN
#nState := "E_DeviceState.eStopped";
END_IF;
END_CASE;
END_REGION
//
REGION Global stop conditions
IF (#nState > "E_DeviceState.eIdle") AND
(#nState < "E_DeviceState.eStopping") AND
NOT #xInAllReadyToStart THEN
#nState := "E_DeviceState.eStopped";
END_IF;
END_REGION
REGION Timer
#tOnStartUpTimer(IN := (#nState = "E_DeviceState.eStarting" OR #nState = "E_DeviceState.eUnholding"),
PT := #stSettings.tStartUpTime);
END_REGION
REGION Outputs
#stInOutControlUnitCabinet.xStartUpWarning := (#nState = "E_DeviceState.eStarting" OR (#nState = "E_DeviceState.eUnholding" AND #stSettings.xEnableStartUpWarning)) AND #stSettings.xEnableStartUpWarning AND "Clock_1Hz";
#stInOutControlUnitCabinet.xStarting := (#nState = "E_DeviceState.eStarting") OR (#nState = "E_DeviceState.eUnholding");// AND #stSettings.xEnableStartUpWarning;
#stInOutControlUnitCabinet.xRunning := #nState > "E_DeviceState.eStarting" AND #nState <= "E_DeviceState.eUnholding";
#stInOutControlUnitCabinet.xMachineOnLed := (#nState > "E_DeviceState.eStarting" AND
#nState < "E_DeviceState.eUnholding")
OR
#nState = "E_DeviceState.eStarting" AND "Clock_2.5Hz"
OR
#nState = "E_DeviceState.eUnholding" AND "Clock_2.5Hz";
#stInOutControlUnitCabinet.xQuitError := (NOT #xQuitErrorFlag AND #xInBtnQuitError) OR #stControl.xQuitt OR #stInOutHMI.xQuit;
#stInOutControlUnitCabinet.xSafetyRequest := #nState >= "E_DeviceState.eStarting" AND #nState <= "E_DeviceState.eAborting";
#stInOutControlUnitCabinet.xSafetyActive := #xInSafetyActive;
IF (NOT #xQuitErrorFlag AND #xInBtnQuitError) THEN
#stInOutControlUnitCabinet.xError := 0;
END_IF;
#xQuitErrorFlag := #xInBtnQuitError;
#stInOutControlUnitCabinet.xRestart := #nConveyorStartUpCounter < 6000 AND #nState = "E_DeviceState.eExecute";
END_REGION
REGION Flags
#xQuitErrorFlag := #xInBtnQuitError OR #stInOutHMI.xQuit;
END_REGION
REGION HMI
#stInOutHMI.nStateStatus := #nState; // Für Anzeige
END_REGION
END_FUNCTION_BLOCK
@@ -0,0 +1,10 @@
LibraryType:
Guid: 748bae8a-b781-46d7-addf-30d61d2eba87
LibraryVersion:
VersionNumber: 2.0.0
Author: e.yueksel
IsDefault: true
Comment:
de-DE: |-
HMI Schnittstelle für MainStateMachine
Freigegeben für IBN (EY, 22.04.2025)
@@ -0,0 +1,6 @@
DocumentHash:
- FileName: UDT_HMI_StateMachine.xml
Hash: YqTb5Kyt7R2GxFrle2a0EDCZZaopcl49Qy34HgCTLgE=
LibraryMetaFileHash: DCa7PFui0vP0Ap3+CzccEnRwXeGVD/9IVuSPN1Z7DKQ=
LibraryVersion:
Guid: 56ad7890-8af6-435b-bc6e-eb1b1452b2de
@@ -0,0 +1,71 @@
<?xml version="1.0" encoding="utf-8"?>
<Document>
<Engineering version="V20" />
<SW.Types.PlcStruct ID="0">
<AttributeList>
<Interface><Sections xmlns="http://www.siemens.com/automation/Openness/SW/Interface/v5">
<Section Name="None">
<Member Name="nStateStatus" Datatype="Int">
<Comment>
<MultiLanguageText Lang="de-DE">State Status</MultiLanguageText>
</Comment>
</Member>
<Member Name="xStart" Datatype="Bool">
<Comment>
<MultiLanguageText Lang="de-DE">Ein</MultiLanguageText>
</Comment>
</Member>
<Member Name="xStop" Datatype="Bool">
<Comment>
<MultiLanguageText Lang="de-DE">Aus</MultiLanguageText>
</Comment>
</Member>
<Member Name="xQuit" Datatype="Bool">
<Comment>
<MultiLanguageText Lang="de-DE">Quittieren</MultiLanguageText>
</Comment>
</Member>
<Member Name="xEStop" Datatype="Bool">
<Comment>
<MultiLanguageText Lang="de-DE">Abort / Not-Aus</MultiLanguageText>
</Comment>
</Member>
<Member Name="xRestart" Datatype="Bool">
<Comment>
<MultiLanguageText Lang="de-DE">Restart</MultiLanguageText>
</Comment>
</Member>
<Member Name="xRevRequest" Datatype="Bool">
<Comment>
<MultiLanguageText Lang="de-DE">Rev Request</MultiLanguageText>
</Comment>
</Member>
</Section>
</Sections></Interface>
<Name>UDT_HMI_StateMachine</Name>
<Namespace />
</AttributeList>
<ObjectList>
<MultilingualText ID="1" CompositionName="Comment">
<ObjectList>
<MultilingualTextItem ID="2" CompositionName="Items">
<AttributeList>
<Culture>de-DE</Culture>
<Text />
</AttributeList>
</MultilingualTextItem>
</ObjectList>
</MultilingualText>
<MultilingualText ID="3" CompositionName="Title">
<ObjectList>
<MultilingualTextItem ID="4" CompositionName="Items">
<AttributeList>
<Culture>de-DE</Culture>
<Text />
</AttributeList>
</MultilingualTextItem>
</ObjectList>
</MultilingualText>
</ObjectList>
</SW.Types.PlcStruct>
</Document>
@@ -0,0 +1,12 @@
LibraryType:
Guid: 3d2d0bd3-d380-4083-96cb-8a59f491213f
Comment:
de-DE: Schnittstelle für FB_StateMain
LibraryVersion:
VersionNumber: 2.0.0
Author: e.yueksel
IsDefault: true
Comment:
de-DE: |-
Schnittstelle für FB_StateMain
Freigegeben für IBN (EY, 22.04.2025)
@@ -0,0 +1,6 @@
DocumentHash:
- FileName: UDT_MainState.xml
Hash: +MrFmzTr+4YI2f0qRODlk2+DIDgf/h5wtjQbdU+trFE=
LibraryMetaFileHash: akSVw7JbvF/2cLiH1d4UkN55a7NTHXG6blUM71UKumM=
LibraryVersion:
Guid: 10820fae-c055-4680-9e88-3660705a6587
@@ -0,0 +1,86 @@
<?xml version="1.0" encoding="utf-8"?>
<Document>
<Engineering version="V20" />
<SW.Types.PlcStruct ID="0">
<AttributeList>
<Interface><Sections xmlns="http://www.siemens.com/automation/Openness/SW/Interface/v5">
<Section Name="None">
<Member Name="xRunning" Datatype="Bool">
<Comment>
<MultiLanguageText Lang="de-DE">Anlage Automatikbetrieb</MultiLanguageText>
</Comment>
</Member>
<Member Name="xQuitError" Datatype="Bool">
<Comment>
<MultiLanguageText Lang="de-DE">Start nach Störung</MultiLanguageText>
</Comment>
</Member>
<Member Name="xError" Datatype="Bool">
<Comment>
<MultiLanguageText Lang="de-DE">Any Error active</MultiLanguageText>
</Comment>
</Member>
<Member Name="xStarting" Datatype="Bool">
<Comment>
<MultiLanguageText Lang="de-DE">Maschine startet</MultiLanguageText>
</Comment>
</Member>
<Member Name="xRestart" Datatype="Bool">
<Comment>
<MultiLanguageText Lang="de-DE">Neustart</MultiLanguageText>
</Comment>
</Member>
<Member Name="xMachineOnLed" Datatype="Bool">
<Comment>
<MultiLanguageText Lang="de-DE">LED Anlage Ein</MultiLanguageText>
</Comment>
</Member>
<Member Name="xStopMachine" Datatype="Bool">
<Comment>
<MultiLanguageText Lang="de-DE">Maschine wird durch dieses Bit angehalten</MultiLanguageText>
</Comment>
</Member>
<Member Name="xStartUpWarning" Datatype="Bool">
<Comment>
<MultiLanguageText Lang="de-DE">Anfahrwarnung</MultiLanguageText>
</Comment>
</Member>
<Member Name="xSafetyRequest" Datatype="Bool">
<Comment>
<MultiLanguageText Lang="de-DE">Anfrage, dass die Safety aktiviert wird</MultiLanguageText>
</Comment>
</Member>
<Member Name="xSafetyActive" Datatype="Bool">
<Comment>
<MultiLanguageText Lang="de-DE">Safety ist aktiviert</MultiLanguageText>
</Comment>
</Member>
</Section>
</Sections></Interface>
<Name>UDT_MainState</Name>
<Namespace />
</AttributeList>
<ObjectList>
<MultilingualText ID="1" CompositionName="Comment">
<ObjectList>
<MultilingualTextItem ID="2" CompositionName="Items">
<AttributeList>
<Culture>de-DE</Culture>
<Text />
</AttributeList>
</MultilingualTextItem>
</ObjectList>
</MultilingualText>
<MultilingualText ID="3" CompositionName="Title">
<ObjectList>
<MultilingualTextItem ID="4" CompositionName="Items">
<AttributeList>
<Culture>de-DE</Culture>
<Text />
</AttributeList>
</MultilingualTextItem>
</ObjectList>
</MultilingualText>
</ObjectList>
</SW.Types.PlcStruct>
</Document>
@@ -0,0 +1,20 @@
LibraryType:
Guid: fc79a2eb-31dd-4847-9624-eb660ce10f25
Comment:
de-DE: |-
Manager für Schrittketten
- Schrittketten ein-ausschalten
- Schritttimer integriert (Dauer eines aktiven Schritts)
- Schritthistorie
LibraryVersion:
VersionNumber: 2.0.0
Author: e.yueksel
IsDefault: true
Comment:
de-DE: |-
Manager für Schrittketten
- Schrittketten ein-ausschalten
- Schritttimer integriert (Dauer eines aktiven Schritts)
- Schritthistorie
Freigegeben für IBN (22.04.2025)
@@ -0,0 +1,6 @@
DocumentHash:
- FileName: FB_StateManager.scl
Hash: bcEUtDKqV8LMMdpaYVhVCfjBuKlBilNyJprtURyTJZc=
LibraryMetaFileHash: 2PYH+EJhUOAQSvx/5tKDPTmfq3RYznpIYVnZ2XbSK1M=
LibraryVersion:
Guid: cb3fd588-4989-4a4a-a2a6-5529192cbc90
@@ -0,0 +1,164 @@
FUNCTION_BLOCK "FB_StateManager"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
VAR_INPUT
stInSettings : Struct
nStartState : Int := 100; // State auf den als erstes gesprungen wird wenn xFunctoinEnable = TRUE
nStartStateTestMode : Int;
xRestartAtStartState : Bool; // TRUE: Wird der Baustein wieder aktiviert wird der State der unter "Settings.nStartState" angegeben ist angesprungen. False: Alter State wird wieder angesprungen
xActUnivTOn : Bool;
END_STRUCT;
xInFunctionEnabled : Bool; // nState springt auf 0 wenn FALSE, und zurück zum Ursprung bei TRUE
xInReset : Bool;
xInRunUnivTOn : Bool;
xInTimerReset : Bool;
xInTestMode : Bool;
END_VAR
VAR_OUTPUT
nOutStateLast : Int;
xOutStepchange : Bool; // einen Zyklus True bei Schrittwechel. Kommt nicht beim Wechel in State = 0 aus State = 0
tOutTimeInStep : Time; // Zeit wie lange schon im Schritt, wird bei Stepchange zurückgesetzt
tOutUnivTonR : Time; // Gibt eine hochzählende Zeit aus die z.B. in Schrittketten verwendet werden kann
END_VAR
VAR_IN_OUT
nInOutState : Int;
END_VAR
VAR RETAIN
nStateBeforeError : Int := 100;
nStateLast : Int := 100;
arHistory : Array[0..50] of Int;
END_VAR
VAR
arHistoryAdv : Array[0..#cSizeHistoryAdv] of Struct
nStepNum : Int;
tTimeStamp {InstructionName := 'DTL'; LibVersion := '1.0'} : DTL;
END_STRUCT;
END_VAR
VAR RETAIN
nPosHistory : USInt;
tOnrTimeInStep {InstructionName := 'TONR_TIME'; LibVersion := '1.0'} : TONR_TIME;
tOnrUnivTimer {InstructionName := 'TONR_TIME'; LibVersion := '1.0'} : TONR_TIME;
tOnUnivTimer {InstructionName := 'TON_TIME'; LibVersion := '1.0'} : TON_TIME;
xStepchange : Bool;
END_VAR
VAR
R_TRIG_TestMode {InstructionName := 'R_TRIG'; LibVersion := '1.0'} : R_TRIG;
F_TRIG_TestMode {InstructionName := 'F_TRIG'; LibVersion := '1.0'} : F_TRIG;
R_TRIG_FunctionEn {InstructionName := 'R_TRIG'; LibVersion := '1.0'} : R_TRIG;
END_VAR
VAR_TEMP
t_Status : Int;
END_VAR
VAR CONSTANT
cSizeHistory : USInt := 50;
cSizeHistoryAdv : UInt := 200;
END_VAR
BEGIN
// #R_TRIG_TestMode(CLK := #xInTestMode);
// #F_TRIG_TestMode(CLK:=#xInTestMode);
//#R_TRIG_FunctionEn(CLK := #xInFunctionEnabled);
REGION Reset
IF #xInReset (* OR "FirstScan" *) (* OR #R_TRIG_TestMode.Q OR #F_TRIG_TestMode.Q *) THEN //XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
#nInOutState := 0;
#nStateLast := #stInSettings.nStartState;
#nStateBeforeError := #stInSettings.nStartState;
END_IF;
END_REGION
REGION Stephistory schreiben
IF #nInOutState <> #nStateLast AND
#nInOutState <> 0000 THEN
#arHistory[#nPosHistory] := #nInOutState;
IF #nPosHistory >= #cSizeHistory THEN
#arHistory[0] := 9999;
#nPosHistory := 0;
ELSE
#arHistory[#nPosHistory + 1] := 9999;
#nPosHistory += 1;
END_IF;
END_IF;
END_REGION
REGION Stephistory mit Zeitstempel
// IF
// #nInOutState <> #nStateLast
// THEN
// #t_Status := MOVE_BLK_VARIANT(SRC := #"arHistoryAdv",
// COUNT := #cSizeHistoryAdv,
// SRC_INDEX := 0,
// DEST_INDEX := 1,
// DEST => #"arHistoryAdv");
// #t_Status := RD_LOC_T(#"arHistoryAdv"[0].tTimeStamp); //Zeitstempel
// #"arHistoryAdv"[0].nStepNum := #nInOutState;
// #nStateLast := #nInOutState;
// END_IF;
END_REGION
REGION Ein- und Ausschalten
//Bei Ein - Auschalten in Schritt 0 und zurück wechseln
IF NOT #xInFunctionEnabled
AND #nInOutState <> 0000 THEN
#nStateBeforeError := #nInOutState;
#nInOutState := 0000;
ELSIF #xInFunctionEnabled AND
#nInOutState = 0000 THEN
IF #stInSettings.xRestartAtStartState THEN
#nInOutState := #stInSettings.nStartState;
ELSE
#nInOutState := #nStateBeforeError;
END_IF;
END_IF;
END_REGION
REGION Stepchange
IF #nInOutState <> #nStateLast THEN
IF #nInOutState <> 0000 THEN
#nStateLast := #nInOutState;
IF #nStateLast <> 0000 THEN
#xStepchange := TRUE;
END_IF;
END_IF;
ELSE
#xStepchange := FALSE;
END_IF;
END_REGION
REGION Timer
#tOnrTimeInStep(IN := #nInOutState <> 0000,
PT := T#+24d_20h_31m_23s, //Max Zeit für "Time"
R := #xStepchange OR #xInReset);
IF #stInSettings.xActUnivTOn THEN
#tOnrUnivTimer(IN := #xInRunUnivTOn,
PT := T#+24d_20h_31m_23s); //Max Zeit für "Time"
IF #xInReset OR #xInTimerReset THEN
RESET_TIMER(#tOnrUnivTimer);
END_IF;
END_IF;
END_REGION
REGION Ausgänge schreiben
#xOutStepchange := #xStepchange;
#tOutTimeInStep := #tOnrTimeInStep.ET;
#nOutStateLast := #nStateLast;
IF #stInSettings.xActUnivTOn THEN
#tOutUnivTonR := #tOnrUnivTimer.ET;
ELSE
#tOutUnivTonR := T#0S;
END_IF;
END_REGION
END_FUNCTION_BLOCK
@@ -0,0 +1,10 @@
LibraryType:
Guid: 3342ee0b-33ee-4d32-9746-e58e39123b17
Comment:
de-DE: Cognex DM Barcode Reader
LibraryVersion:
VersionNumber: 2.0.4
Author: e.yueksel
IsDefault: true
Comment:
de-DE: Änderung im unterlagerten Baustein
@@ -0,0 +1,19 @@
DocumentHash:
- FileName: FB_BarcodeReaderCognex.scl
Hash: 4rFEFeAdq0tC32QHEP8AN5yefbKhwxAEdFcdHSCNsGc=
LibraryMetaFileHash: 6AEzsSMKgxcEeln7MzkJ58F/SOePAjBWRRDdTjBpDe4=
LibraryVersion:
Guid: 52e3e154-927c-43ca-a9f1-9b6026af3f8a
DependsOn:
- TypeName: stHMI_BRCognexDM
VersionNumber: 2.0.0
- TypeName: stCognexInterface
VersionNumber: 2.0.0
- TypeName: FB_Monitoring
VersionNumber: 2.0.5
- TypeName: UDT_MainState
VersionNumber: 2.0.0
- TypeName: UDT_BarcodeReader
VersionNumber: 2.0.1
- TypeName: UDT_SettingsBarcodeReader
VersionNumber: 2.0.0
@@ -0,0 +1,554 @@
FUNCTION_BLOCK "FB_BarcodeReaderCognex"
TITLE = FB_BarcodeReader
{ S7_Optimized_Access := 'TRUE' }
AUTHOR : 'e.yueksel'
FAMILY : BarcodeReader
VERSION : 0.1
//Zusammensetzung aus FB_CameraCognex_Continuous und FB_StationScanner_WithCont
//Optimierte Variante (z.B. Schrittkette zusammengefasst)
//
//Dieser Baustein funktioniert nur mit Cognex Readern (z.B. DM260, DM280) und dem Cognex Profinet Interface und Triggermodus: Kontinuierlich (Continuous)!
VAR_INPUT
stInSettings : "UDT_SettingsBarcodeReader";
xInBorner : Bool; // NIU
xInStartReading : Bool; // Starte Lesevorgang
xInHandshakeDone : Bool; // Lesevorgang beendet Handshake rein
xInErrQuit : Bool; // Fehler rücksetzen
xInReset : Bool; // Baustein zurücksetzen
xInHWError : Bool; // Baugruppen Fehler
END_VAR
VAR_OUTPUT
xOutReadingDone : Bool; // Lesevorgang abgeschlossen / Handshake raus
xOutReadyForNewScan : Bool; // Reader ist bereit für Leseanforderung
nOutBarcode : LInt; // Letzter gelesener Barcode
sOutBarcode : String[20]; // Letzter gelesener Barcode (als Zeichenkette)
wOutErrorWord : Word; // Fehlercode
xOutCodeGood : Bool; // NIU
xOutCodeBad : Bool; // NIU
END_VAR
VAR_IN_OUT
stInOutInterface : "stCognexInterface";
stInOutControlUnitCabinet : "UDT_MainState";
stInOutHMI : "UDT_BarcodeReader";
END_VAR
VAR
xStartReading : Bool;
xTrigger : Bool;
xToggleBitFlg : Bool;
nBarcode : LInt;
sBarcodeString : String[20] := 'none';
GETIO_PART {InstructionName := 'GETIO_PART'; LibVersion := '1.2'; ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : GETIO_PART;
SETIO_PART {InstructionName := 'SETIO_PART'; LibVersion := '1.2'; ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : SETIO_PART;
stCtrlBitsIn : Struct
D0_DeviceReady : Bool;
D1_SystemReady : Bool;
D2_GoodRead : Bool;
D3_NoRead : Bool;
D4_ExtOut1 : Bool;
D5_ExtOut2 : Bool;
D6_Result1 : Bool;
D7_Result2 : Bool;
D8_ExtIn1 : Bool;
D9_ExtIn2 : Bool;
D10_Sensor1 : Bool;
D11_Sensor2 : Bool;
D12_Res : Bool;
D13_Res : Bool;
D14_Res : Bool;
D15_Toggle : Bool;
END_STRUCT;
nState : Int;
nLastStep { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Int;
arStepHistory : Array[0..10] of Struct
StepNum : Int;
TimeStamp {InstructionName := 'DTL'; LibVersion := '1.0'} : DTL;
END_STRUCT;
nResultID : Int;
nResultCode : Int;
nResultExtended : Int;
"64Byte_IN_Data" { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Array[0..63] of Byte;
tOnMonitoring {InstructionName := 'TON_TIME'; LibVersion := '1.0'} : TON_TIME;
stHMI : "stHMI_BRCognexDM";
fbMonitoringCamRuntimeFail : "FB_Monitoring";
fbMonitoringCamGeneralFault : "FB_Monitoring";
stStatistics : Struct
nReads : UDInt;
nGoodRead : UDInt;
nBadRead : UDInt;
nGoodReadBarcodeChanged : UDInt;
nBadReadBarcodeChanged : UDInt;
tLastBarcodeRecv {InstructionName := 'DTL'; LibVersion := '1.0'; ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : DTL;
tLastNoReadRecv {InstructionName := 'DTL'; LibVersion := '1.0'; ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : DTL;
tLastReset {InstructionName := 'DTL'; LibVersion := '1.0'; ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : DTL;
END_STRUCT;
END_VAR
VAR RETAIN
xReInit : Bool;
END_VAR
VAR
tPLCTime {InstructionName := 'DTL'; LibVersion := '1.0'} : DTL;
xCodeGood : Bool;
xCodeBad : Bool;
nBarcodeTarget : DInt;
sBarcodeTarget : String;
stTest : Struct
nGoodRead : Int;
nBadRead : Int;
nGoodReadBarcodeChanged : Int;
nBadReadBarcodeChanged : Int;
END_STRUCT;
END_VAR
VAR_TEMP
tReadIO_Status : DWord;
tReadIO_Error : Bool;
tWriteIO_Status_01 : DWord;
tWriteIO_Error_01 : Bool;
t_BC_iO : Bool;
t_BC_niO : Bool;
t_Format : Word;
t_Status : Int;
t_Time : Int;
xTemp : Bool;
nTempRetVal : Int;
tTempLocalTime {InstructionName := 'DTL'; LibVersion := '1.0'} : DTL;
END_VAR
VAR CONSTANT
"E_DeviceState.eInit1" : Int := 0;
"E_DeviceState.eInit2" : Int := 100;
"E_DeviceState.eNoJob" : Int := 200;
"E_DeviceState.eWaitReaderReady" : Int := 300;
"E_DeviceState.eWaitTriggerAck" : Int := 400;
"E_DeviceState.eGetResult" : Int := 500;
"E_DeviceState.eClearResult" : Int := 600;
"E_DeviceState.eOutput" : Int := 700;
"E_DeviceState.eHandshake" : Int := 800;
END_VAR
BEGIN
REGION Block Header
//=================================================================================
// Schönenberger Systeme GmbH / (c)Copyright 2025
//---------------------------------------------------------------------------------
// Title: FB_BarcodeReaderCognex
// Comment/Function: Cognex Barcode Reader
// Library/Family: BaseSystemLib/PROFINET/Devices
// Author: E.Yüksel
// Tested with: CPU 1515F-2 PN FW:V3.0
// Engineering: TIA Portal V20
// Restrictions: This function block ONLY works with Cognex Dataman Readers and PROFINET protocol
// Currently ONLY designed for Cognex trigger mode: Continuous
// Requirements: PLC (S7-1500)
//---------------------------------------------------------------------------------
// Change log table:
// Version | Date | Expert in charge | Changes applied
//----------|------------|------------------------|--------------------------------
// 01.00.00 | 25.04.2024 | Yüksel, Molina | First released version
// 02.00.00 | 20.11.2024 | Yüksel | Prepare for library integration
// 03.00.00 | 31.01.2025 | Yüksel | Refactoring, no functionality changes
//=================================================================================
END_REGION
REGION Info
(*
Errors:
00 Internal Error / Stepfailure
01 Results available before trigger
02 Runtime failure
03 Barcode ASCI failure
04 Res 4
05 ReadIO_Error
06 Res 6
07 Res 7
08 Res 8
09 Res 9
10 Res 10
11 Res 11
12 Res 12
13 Res 13
14 Camera not ready / General Fault
15 Modul reset
*)
END_REGION
REGION Read local plc time
// Lokale CPU Zeit auslesen
#nTempRetVal := RD_LOC_T(#tTempLocalTime);
END_REGION
REGION INIT
REGION First Scan
IF "FirstScan" THEN
#nState := #"E_DeviceState.eInit1";
END_IF;
END_REGION
REGION Reset statistics
IF NOT #xReInit AND NOT "FirstScan" AND #tTempLocalTime.YEAR > 1970 THEN
#stStatistics.nReads := 0;
#stStatistics.nGoodRead := 0;
#stStatistics.nBadRead := 0;
#stStatistics.nGoodReadBarcodeChanged := 0;
#stStatistics.nBadReadBarcodeChanged := 0;
#stStatistics.tLastBarcodeRecv := DTL#1970-01-01-00:00:00;
#stStatistics.tLastNoReadRecv := DTL#1970-01-01-00:00:00;
#stStatistics.tLastReset := DTL#1970-01-01-00:00:00;
#xReInit := TRUE;
#stStatistics.tLastReset := #tTempLocalTime;
END_IF;
IF #stInOutHMI.xResetStatistics THEN
#stStatistics.nReads := 0;
#stStatistics.nGoodRead := 0;
#stStatistics.nBadRead := 0;
#stStatistics.nGoodReadBarcodeChanged := 0;
#stStatistics.nBadReadBarcodeChanged := 0;
#stStatistics.tLastBarcodeRecv := DTL#1970-01-01-00:00:00;
#stStatistics.tLastNoReadRecv := DTL#1970-01-01-00:00:00;
#stStatistics.tLastReset := DTL#1970-01-01-00:00:00;
#stStatistics.tLastReset := #tTempLocalTime;
#stInOutHMI.xResetStatistics := FALSE;
END_IF;
END_REGION
END_REGION
REGION ErrorQuitt
IF #xInErrQuit THEN
#wOutErrorWord := 0;
END_IF;
END_REGION
REGION reset step sequence
IF #xInReset THEN
#nState := #"E_DeviceState.eInit1";
#wOutErrorWord := 0;
#wOutErrorWord.%X15 := TRUE;
END_IF;
END_REGION
REGION Err check camera ready
#wOutErrorWord.%X14 := #stInOutInterface.#xInCamGeneralFault;
END_REGION
REGION stepsequence
CASE #nState OF
#"E_DeviceState.eInit1":
REGION STEP 000 - INIT 1
#xOutReadyForNewScan := FALSE;
#xCodeBad := FALSE;
#xCodeGood := FALSE;
#xOutReadingDone := FALSE;
#stInOutInterface.xOutCamTriggerEnable := FALSE;
#stInOutInterface.xOutCamTrigger := FALSE;
#stInOutInterface.xOutCamResultsAck := FALSE;
#nOutBarcode := #nBarcode := 0;
#sOutBarcode := #sBarcodeString := '';
#wOutErrorWord := 0; // no Error
#nState := #"E_DeviceState.eInit2"; //Lade aktuelle Schrittnummer
END_REGION
#"E_DeviceState.eInit2":
REGION STEP 100 - INIT 2
#xOutReadyForNewScan := FALSE;
#xCodeBad := FALSE;
#xCodeGood := FALSE;
#xOutReadingDone := FALSE;
#stInOutInterface.xOutCamTriggerEnable := FALSE;
#stInOutInterface.xOutCamTrigger := FALSE;
#stInOutInterface.xOutCamResultsAck := TRUE; // Reader Ergebnisse quittieren
#nOutBarcode := #nBarcode := 0;
#sOutBarcode := #sBarcodeString := '';
//Transition
IF
NOT #stInOutInterface.xInCamResultsAvailable
THEN
#nState := #"E_DeviceState.eNoJob"; //Lade aktuelle Schrittnummer
END_IF;
END_REGION
#"E_DeviceState.eNoJob":
REGION STEP 200 - IDLE
#xCodeBad := FALSE;
#xCodeGood := FALSE;
IF #stInOutInterface.xInCamResultsAvailable OR #xInErrQuit THEN
#stInOutInterface.xOutCamResultsAck := TRUE;
ELSE
#stInOutInterface.xOutCamResultsAck := FALSE;
END_IF;
//#stInOutInterface.xOutCamResultsAck := #xInErrQuit;
#stInOutInterface.xOutCamTriggerEnable := FALSE;
#stInOutInterface.xOutCamTrigger := FALSE;
#xOutReadingDone := FALSE;
#nBarcode := #nOutBarcode := 0;
#xOutReadyForNewScan := TRUE;
//Transition
IF #xInStartReading THEN // Leseanforderung
#nState := #"E_DeviceState.eWaitReaderReady"; //Lade aktuelle Schrittnummer
END_IF;
END_REGION
#"E_DeviceState.eWaitReaderReady":
REGION STEP 300 - WAIT READER READY
#xOutReadyForNewScan := FALSE;
#stInOutInterface.xOutCamTriggerEnable := TRUE; // Freigabe an Barcode Reader
#stInOutInterface.xOutCamResultsAck := FALSE;
#wOutErrorWord.%X1 := #stInOutInterface.xInCamResultsAvailable; // Fehler wenn es schon Ergebnisse gibt
//Transition
IF #stInOutInterface.xInCamTriggerReady THEN // Barcode Reader meldet bereit
#stInOutInterface.xOutCamTrigger := TRUE; // Barcode Reader triggern
#nState := #"E_DeviceState.eWaitTriggerAck";
END_IF;
END_REGION
#"E_DeviceState.eWaitTriggerAck":
REGION STEP 400 - WAIT TRIGGER ACK
#xOutReadyForNewScan := FALSE;
#stInOutInterface.xOutCamTrigger := TRUE;
//Transition
IF #stInOutInterface.xInCamTriggerAck THEN
#nState := #"E_DeviceState.eGetResult";
END_IF;
END_REGION
#"E_DeviceState.eGetResult":
REGION STEP 500 - GET RESULT
// INFO:
// Beim Continous-Trigger (Modus der am Barcode Reader eingestellt wird) muss das Trigger-Signal im Gegensatz zum Single-Trigger immer high bleiben.
// Der Reader macht kontinuierlich Bilder und hört erst auf, wenn etwas gelesen wurde oder man den Trigger wegnimmt (z.B. nach Timeout)
// #stInOutInterface.xOutCamTrigger := #xInStartReading;
// Auf Ergebnis warten...
IF #stInOutInterface.xInCamResultsAvailable THEN // Ergebnis ist da
#stInOutInterface.xOutCamTrigger := FALSE; // Trigger wegnehmen
REGION Read data
#GETIO_PART(ID := #stInOutInterface.hwInCamInspectionResults, //Einlesen IN 64 Byte Daten
OFFSET := 0,
LEN := 64,
STATUS => #tReadIO_Status,
ERROR => #wOutErrorWord.%X5,
INPUTS := #"64Byte_IN_Data");
Chars_TO_Strg(Chars := #"64Byte_IN_Data",
pChars := 8, //Zeichen ab 8.Byte InData
Cnt := 14, //10 Zeichen
Strg => #sBarcodeString);
END_REGION
REGION Evaluation (+ optional check Ascii)
// ok - ASCI Zeichenprüfung 0 = 48 ... 9 = 57
IF NOT #stInSettings.xActivateCheckASCI OR // next Step wenn ASCI Prüfung nicht aktiv
(#"64Byte_IN_Data"[08] >= 48 AND //Prüfung 1. Zeichen auf Zahlen größer/gleich 0
#"64Byte_IN_Data"[08] <= 57 AND //Prüfung 1. Zeichen auf Zahlen kleiner/gleich 9
#"64Byte_IN_Data"[15] >= 48 AND //Prüfung 10. Zeichen auf Zahlen kleiner/gleich 0
#"64Byte_IN_Data"[15] <= 57) //Prüfung 10. Zeichen auf Zahlen kleiner/gleich 9
THEN
REGION SUCCESS
#stStatistics.tLastBarcodeRecv := #tTempLocalTime;
#stStatistics.nReads += 1;
#stStatistics.nGoodRead += 1;
#xCodeGood := TRUE;
#wOutErrorWord.%X3 := FALSE;
REGION Convert to Integer
STRG_VAL(IN := #sBarcodeString, //Barcode nach DWord
FORMAT := w#16#0,
P := 1, //Ab Zeichen 1 bis zu Ungültigem wert umwandeln //
OUT => #nBarcode);
END_REGION
END_REGION
ELSE
REGION FAIL / BAD
#stStatistics.nReads += 1;
#stStatistics.nBadRead += 1;
#stStatistics.tLastNoReadRecv := #tTempLocalTime;
#wOutErrorWord.%X3 := TRUE; // Fehler ASCI Prüfung! zb NoRead von Cam
#xCodeBad := TRUE;
#nBarcode := -1;
#sBarcodeString := 'NO READ'; // NEU
END_REGION
END_IF;
END_REGION
REGION Acknowledge & Transition
//Transition
#stInOutInterface.xOutCamResultsAck := TRUE;
#nState := #"E_DeviceState.eClearResult";
END_REGION
END_IF;
END_REGION
#"E_DeviceState.eClearResult":
REGION STEP 600 - CLEAR RESULT
#stInOutInterface.xOutCamResultsAck := TRUE; //Leseergebnis quittieren
//Transition
IF
NOT #stInOutInterface.xInCamResultsAvailable // Auf Handshake warten
THEN
#nState := #"E_DeviceState.eOutput"; // Nächster Schritt
END_IF;
END_REGION
#"E_DeviceState.eOutput":
REGION STEP 700 - WRITE OUTPUT
#xOutReadyForNewScan := FALSE;
#stInOutInterface.xOutCamTriggerEnable := FALSE; // Freigabe wegnehmen
#stInOutInterface.xOutCamTrigger := FALSE;
#nOutBarcode := #nBarcode;
#sOutBarcode := #sBarcodeString;
#xOutReadingDone := TRUE;
//Transition
#nState := #"E_DeviceState.eHandshake";
END_REGION
#"E_DeviceState.eHandshake":
REGION STEP 800 - HANDSHAKE
#xOutReadyForNewScan := FALSE;
#xOutReadingDone := TRUE;
#stInOutInterface.xOutCamTriggerEnable := FALSE; // Freigabe wegnehmen
#stInOutInterface.xOutCamTrigger := FALSE;
IF #xInHandshakeDone THEN // Handshake
#nState := #"E_DeviceState.eNoJob";
END_IF;
END_REGION
ELSE //keine gültige Schrittnummer vorhanden
#wOutErrorWord.%X0 := true;
END_CASE;
REGION Step history
IF
#nState <> #nLastStep
THEN
#t_Status := MOVE_BLK_VARIANT(SRC := #arStepHistory,
COUNT := 10,
SRC_INDEX := 0,
DEST_INDEX := 1,
DEST => #arStepHistory);
#t_Status := RD_LOC_T(#arStepHistory[0].TimeStamp); //Zeitstempel
#arStepHistory[0].StepNum := #nState;
#nLastStep := #nState;
END_IF;
END_REGION
END_REGION
REGION Output
#xOutCodeGood := #xCodeGood;
#xOutCodeBad := #xCodeBad;
END_REGION
REGION Runtime monitoring
IF #tOnMonitoring.Q THEN // TIMEOUT
#stStatistics.nReads += 1;
#stStatistics.nBadRead += 1;
#stStatistics.tLastNoReadRecv := #tTempLocalTime;
#xCodeBad := TRUE;
#wOutErrorWord.%X2 := TRUE; // Runtime failure
#nBarcode := -1;
#sBarcodeString := 'NO-READ';
#nState := #"E_DeviceState.eOutput";
END_IF;
END_REGION
REGION HMI / Visu
#stHMI.In16.%X0 := #stInOutInterface.xInCamTriggerReady;
#stHMI.In16.%X1 := #stInOutInterface.xInCamTriggerAck;
#stHMI.In16.%X2 := #stInOutInterface.xInCamResultsAvailable;
#stHMI.In16.%X3 := #stInOutInterface.xInCamGeneralFault;
#stHMI.BarcodeString := #sBarcodeString;
#stHMI.Barcode := #nBarcode;
#stHMI.ResultID := #nResultID;
#stHMI.ErrorWord := #wOutErrorWord;
IF #stInOutInterface.xInCamGeneralFault OR #xInHWError THEN // Kamera nicht bereit
#stInOutHMI.bStatus := 2; // ERROR
ELSE
CASE #nState OF
#"E_DeviceState.eInit1", #"E_DeviceState.eInit2":
#stInOutHMI.bStatus := 0; // NOT_AVAILABLE
#"E_DeviceState.eNoJob", #"E_DeviceState.eWaitReaderReady", #"E_DeviceState.eWaitTriggerAck",
#"E_DeviceState.eGetResult", #"E_DeviceState.eClearResult", #"E_DeviceState.eOutput",
#"E_DeviceState.eHandshake":
#stInOutHMI.bStatus := 1; // AVAILABLE
ELSE //Fallback
#stInOutHMI.bStatus := 0; // NOT AVAILABLE
END_CASE;
END_IF;
#stInOutHMI.nMode := 2; // Continuous
#stInOutHMI.stBRInterface := #stHMI;
#stInOutHMI.nNumberScans := #stStatistics.nReads;
#stInOutHMI.nNumberNoReads := #stStatistics.nBadRead;
#stInOutHMI.nNoReadPercentage := REAL_TO_USINT((UDINT_TO_REAL(#stStatistics.nBadRead) / UDINT_TO_REAL(#stStatistics.nReads)) * 100);
#stInOutHMI.tLastBarcodeRecv := #stStatistics.tLastBarcodeRecv;
#stInOutHMI.tLastNoReadRecv := #stStatistics.tLastNoReadRecv;
#stInOutHMI.tLastReset := #stStatistics.tLastReset;
END_REGION
REGION Timer
#tOnMonitoring(IN := #stInOutInterface.xOutCamTriggerEnable,
PT := #stInSettings.tTimeout);
END_REGION
REGION Monitoring
#fbMonitoringCamRuntimeFail.stSettings.nErrorType := 2;
#fbMonitoringCamRuntimeFail.stSettings.xErrLedIfMachineIsOff := TRUE;
#fbMonitoringCamRuntimeFail.stSettings.xSelfQuit := TRUE;
#fbMonitoringCamRuntimeFail(sInFctnName := CONCAT_STRING(IN1:='Barcode Reader: ', IN2:= #stInOutHMI.sLocation),
sInPrefix := #stInOutHMI.sUnit,
sInSuffix := #stInOutHMI.sIpAdress,
InOutMachineState := #stInOutControlUnitCabinet,
xInQuitError := #stInOutControlUnitCabinet.xQuitError,
xInSignal := NOT #tOnMonitoring.Q,
sInAlarmMessage := 'Laufzeitfehler',
wInTextListId_Function := 1,
wInTextListId_Message := 1);
#fbMonitoringCamGeneralFault.stSettings.nErrorType := 1;
#fbMonitoringCamGeneralFault.stSettings.xErrLedIfMachineIsOff := TRUE;
#fbMonitoringCamGeneralFault.stSettings.xSelfQuit := TRUE;
#fbMonitoringCamGeneralFault(sInFctnName := CONCAT_STRING(IN1:='Barcode Reader: ', IN2:= #stInOutHMI.sLocation),
sInPrefix := #stInOutHMI.sUnit,
sInSuffix := #stInOutHMI.sIpAdress,
InOutMachineState := #stInOutControlUnitCabinet,
xInQuitError := #stInOutControlUnitCabinet.xQuitError,
xInSignal := NOT #stInOutInterface.xInCamGeneralFault AND NOT #xInHWError,
sInAlarmMessage := 'Barcode Reader ist nicht bereit.',
wInTextListId_Function := 1,
wInTextListId_Message := 1);
END_REGION
REGION Event Log
// Pro Event wird ein Aufruf benötigt
//TODO
END_REGION
END_FUNCTION_BLOCK
@@ -0,0 +1,8 @@
LibraryType:
Guid: 05646a02-da52-45d6-8bda-9aae3887a902
Comment:
de-DE: HMI Barcode Reader Interface
LibraryVersion:
VersionNumber: 2.0.1
Author: e.yueksel
IsDefault: true
@@ -0,0 +1,9 @@
DocumentHash:
- FileName: UDT_BarcodeReader.xml
Hash: qvIBnqvITx1xwHE9SSsLnWLseRNEbya8p0X1zJHLLQ8=
LibraryMetaFileHash: +m3hhiCBCcwveV1S82lVQ8/koMYibJlthp0wtBAmKaE=
LibraryVersion:
Guid: 938eb73b-d543-45c9-93b1-e09754c1416f
DependsOn:
- TypeName: stHMI_BRCognexDM
VersionNumber: 2.0.0
@@ -0,0 +1,135 @@
<?xml version="1.0" encoding="utf-8"?>
<Document>
<Engineering version="V20" />
<SW.Types.PlcStruct ID="0">
<AttributeList>
<Interface><Sections xmlns="http://www.siemens.com/automation/Openness/SW/Interface/v5">
<Section Name="None">
<Member Name="bStatus" Datatype="Byte">
<Comment>
<MultiLanguageText Lang="de-DE">Standardized status</MultiLanguageText>
</Comment>
</Member>
<Member Name="nMode" Datatype="Int">
<Comment>
<MultiLanguageText Lang="de-DE">Kamera Triggermodus (Single, Continuous...)</MultiLanguageText>
</Comment>
</Member>
<Member Name="nInternalNumber" Datatype="USInt">
<Comment>
<MultiLanguageText Lang="de-DE">Interne Nummerierung</MultiLanguageText>
</Comment>
</Member>
<Member Name="sUnit" Datatype="String[20]">
<Comment>
<MultiLanguageText Lang="de-DE">Kamera Bezeichnung (z.B. DM262-9FC5D4)</MultiLanguageText>
</Comment>
</Member>
<Member Name="sLocation" Datatype="String[30]">
<Comment>
<MultiLanguageText Lang="de-DE">Standort</MultiLanguageText>
</Comment>
</Member>
<Member Name="sIpAdress" Datatype="String[20]">
<Comment>
<MultiLanguageText Lang="de-DE">IP-Adresse</MultiLanguageText>
</Comment>
</Member>
<Member Name="rThreshold" Datatype="Real">
<Comment>
<MultiLanguageText Lang="de-DE">Schwellwert um die Lesequalität zu bewerten (z.B. 99 [%])</MultiLanguageText>
</Comment>
</Member>
<Member Name="stBRInterface" Datatype="&quot;stHMI_BRCognexDM&quot;">
<Comment>
<MultiLanguageText Lang="de-DE">Schnittstelle Kamera Baustein</MultiLanguageText>
</Comment>
</Member>
<Member Name="nNumberScans" Datatype="UDInt">
<Comment>
<MultiLanguageText Lang="de-DE">Anzahl Scans</MultiLanguageText>
</Comment>
</Member>
<Member Name="nNumberNoReads" Datatype="UDInt">
<Comment>
<MultiLanguageText Lang="de-DE">Anzahl No-Read</MultiLanguageText>
</Comment>
</Member>
<Member Name="nNoReadPercentage" Datatype="USInt">
<Comment>
<MultiLanguageText Lang="de-DE">No-Read in Prozent</MultiLanguageText>
</Comment>
</Member>
<Member Name="tLastBarcodeRecv" Datatype="DTL" Version="1.0">
<Comment>
<MultiLanguageText Lang="de-DE">Letzter Barcode empfangen </MultiLanguageText>
</Comment>
</Member>
<Member Name="tLastNoReadRecv" Datatype="DTL" Version="1.0">
<Comment>
<MultiLanguageText Lang="de-DE">Letzter No-Read empfangen </MultiLanguageText>
</Comment>
</Member>
<Member Name="tLastReset" Datatype="DTL" Version="1.0">
<Comment>
<MultiLanguageText Lang="de-DE">Letzter Reset</MultiLanguageText>
</Comment>
</Member>
<Member Name="xResetStatistics" Datatype="Bool">
<Comment>
<MultiLanguageText Lang="de-DE">Alle Statistiken rücksetzen</MultiLanguageText>
</Comment>
</Member>
</Section>
</Sections></Interface>
<Name>UDT_BarcodeReader</Name>
<Namespace />
</AttributeList>
<ObjectList>
<MultilingualText ID="1" CompositionName="Comment">
<ObjectList>
<MultilingualTextItem ID="2" CompositionName="Items">
<AttributeList>
<Culture>de-DE</Culture>
<Text />
</AttributeList>
</MultilingualTextItem>
<MultilingualTextItem ID="3" CompositionName="Items">
<AttributeList>
<Culture>en-US</Culture>
<Text />
</AttributeList>
</MultilingualTextItem>
<MultilingualTextItem ID="4" CompositionName="Items">
<AttributeList>
<Culture>cs-CZ</Culture>
<Text />
</AttributeList>
</MultilingualTextItem>
</ObjectList>
</MultilingualText>
<MultilingualText ID="5" CompositionName="Title">
<ObjectList>
<MultilingualTextItem ID="6" CompositionName="Items">
<AttributeList>
<Culture>de-DE</Culture>
<Text />
</AttributeList>
</MultilingualTextItem>
<MultilingualTextItem ID="7" CompositionName="Items">
<AttributeList>
<Culture>en-US</Culture>
<Text />
</AttributeList>
</MultilingualTextItem>
<MultilingualTextItem ID="8" CompositionName="Items">
<AttributeList>
<Culture>cs-CZ</Culture>
<Text />
</AttributeList>
</MultilingualTextItem>
</ObjectList>
</MultilingualText>
</ObjectList>
</SW.Types.PlcStruct>
</Document>
@@ -0,0 +1,12 @@
LibraryType:
Guid: 9cd149c5-120a-4c6b-b374-72d0804fee13
Comment:
de-DE: Schrittkette optimiert, bisher fehlende Ausgänge werden jetzt beschrieben
LibraryVersion:
VersionNumber: 2.0.0
Author: e.yueksel
IsDefault: true
Comment:
de-DE: |-
Einstellungen für Barcode-Reader
Freigegeben für IBN (EY, 22.04.2025)
@@ -0,0 +1,6 @@
DocumentHash:
- FileName: UDT_SettingsBarcodeReader.xml
Hash: WIqXsAFeE/opnVa20/ZCVUkon6tOnniE9KMUlnjvY2Y=
LibraryMetaFileHash: OTpcVojAkzlEEy/DPvJe96WcLeEDZJvnkXLUgt3MvdA=
LibraryVersion:
Guid: 6be7977f-bd26-4a22-a946-663b8c2af2c1
@@ -0,0 +1,58 @@
<?xml version="1.0" encoding="utf-8"?>
<Document>
<Engineering version="V20" />
<SW.Types.PlcStruct ID="0">
<AttributeList>
<Interface><Sections xmlns="http://www.siemens.com/automation/Openness/SW/Interface/v5">
<Section Name="None">
<Member Name="nStation" Datatype="Int">
<Comment>
<MultiLanguageText Lang="de-DE">Nummer</MultiLanguageText>
</Comment>
</Member>
<Member Name="nScannerPurpose" Datatype="USInt">
<Comment>
<MultiLanguageText Lang="de-DE">Leser Aufgabe (Trolley Barcode, Teil Barcode...)</MultiLanguageText>
</Comment>
</Member>
<Member Name="xActivateCheckASCI" Datatype="Bool">
<Comment>
<MultiLanguageText Lang="de-DE">ASCI Prüfung aktiveren</MultiLanguageText>
</Comment>
<StartValue>true</StartValue>
</Member>
<Member Name="tTimeout" Datatype="Time">
<Comment>
<MultiLanguageText Lang="de-DE">Timeout Lesung</MultiLanguageText>
</Comment>
<StartValue>T#5s</StartValue>
</Member>
</Section>
</Sections></Interface>
<Name>UDT_SettingsBarcodeReader</Name>
<Namespace />
</AttributeList>
<ObjectList>
<MultilingualText ID="1" CompositionName="Comment">
<ObjectList>
<MultilingualTextItem ID="2" CompositionName="Items">
<AttributeList>
<Culture>de-DE</Culture>
<Text />
</AttributeList>
</MultilingualTextItem>
</ObjectList>
</MultilingualText>
<MultilingualText ID="3" CompositionName="Title">
<ObjectList>
<MultilingualTextItem ID="4" CompositionName="Items">
<AttributeList>
<Culture>de-DE</Culture>
<Text />
</AttributeList>
</MultilingualTextItem>
</ObjectList>
</MultilingualText>
</ObjectList>
</SW.Types.PlcStruct>
</Document>
@@ -0,0 +1,12 @@
LibraryType:
Guid: 522f83ce-0f0f-4b78-ad1b-5bd95073250a
Comment:
de-DE: Cognex PROFINET Interface
LibraryVersion:
VersionNumber: 2.0.0
Author: e.yueksel
IsDefault: true
Comment:
de-DE: |-
Cognex PROFINET Interface
Freigegeben für IBN (EY, 22.04.2025)
@@ -0,0 +1,6 @@
DocumentHash:
- FileName: stCognexInterface.xml
Hash: J+LAf7w1glPlo9Ow1PIqSnnM5HGz4UPc30sj3AR/oKU=
LibraryMetaFileHash: XheQv51sz6RtFuNhNKVf2R1rrw7mGvCKbif6zVxhlPM=
LibraryVersion:
Guid: fd4fcb5f-2541-42a7-b6e0-a0e94d47950e
@@ -0,0 +1,87 @@
<?xml version="1.0" encoding="utf-8"?>
<Document>
<Engineering version="V20" />
<SW.Types.PlcStruct ID="0">
<AttributeList>
<Interface><Sections xmlns="http://www.siemens.com/automation/Openness/SW/Interface/v5">
<Section Name="None">
<Member Name="xInCamTriggerReady" Datatype="Bool">
<Comment>
<MultiLanguageText Lang="de-DE">Cognex Acquisition Status Module</MultiLanguageText>
</Comment>
</Member>
<Member Name="xInCamTriggerAck" Datatype="Bool">
<Comment>
<MultiLanguageText Lang="de-DE">Cognex Acquisition Status Module</MultiLanguageText>
</Comment>
</Member>
<Member Name="xInCamResultsAvailable" Datatype="Bool">
<Comment>
<MultiLanguageText Lang="de-DE">Cognex Results Status Module</MultiLanguageText>
</Comment>
</Member>
<Member Name="xInCamGeneralFault" Datatype="Bool">
<Comment>
<MultiLanguageText Lang="de-DE">Cognex Results Status Module</MultiLanguageText>
</Comment>
</Member>
<Member Name="wInCamResultID" Datatype="Word">
<Comment>
<MultiLanguageText Lang="de-DE">Cognex Result Data Module</MultiLanguageText>
</Comment>
</Member>
<Member Name="wInCamResultCode" Datatype="Word">
<Comment>
<MultiLanguageText Lang="de-DE">Cognex Result Data Module</MultiLanguageText>
</Comment>
</Member>
<Member Name="wInCamResultExtended" Datatype="Word">
<Comment>
<MultiLanguageText Lang="de-DE">Cognex Result Data Module</MultiLanguageText>
</Comment>
</Member>
<Member Name="hwInCamInspectionResults" Datatype="HW_SUBMODULE" />
<Member Name="xOutCamTriggerEnable" Datatype="Bool">
<Comment>
<MultiLanguageText Lang="de-DE">Cognex Acquisition Control Module</MultiLanguageText>
</Comment>
</Member>
<Member Name="xOutCamTrigger" Datatype="Bool">
<Comment>
<MultiLanguageText Lang="de-DE">Cogenx Acquisition Control Module</MultiLanguageText>
</Comment>
</Member>
<Member Name="xOutCamResultsAck" Datatype="Bool">
<Comment>
<MultiLanguageText Lang="de-DE">Cognex Results Control Module</MultiLanguageText>
</Comment>
</Member>
</Section>
</Sections></Interface>
<Name>stCognexInterface</Name>
<Namespace />
</AttributeList>
<ObjectList>
<MultilingualText ID="1" CompositionName="Comment">
<ObjectList>
<MultilingualTextItem ID="2" CompositionName="Items">
<AttributeList>
<Culture>de-DE</Culture>
<Text />
</AttributeList>
</MultilingualTextItem>
</ObjectList>
</MultilingualText>
<MultilingualText ID="3" CompositionName="Title">
<ObjectList>
<MultilingualTextItem ID="4" CompositionName="Items">
<AttributeList>
<Culture>de-DE</Culture>
<Text />
</AttributeList>
</MultilingualTextItem>
</ObjectList>
</MultilingualText>
</ObjectList>
</SW.Types.PlcStruct>
</Document>
@@ -0,0 +1,12 @@
LibraryType:
Guid: ba76061d-44fd-44db-918c-8781346850fc
Comment:
de-DE: Cognex Barcode Reader HMI Interface
LibraryVersion:
VersionNumber: 2.0.0
Author: e.yueksel
IsDefault: true
Comment:
de-DE: |-
Cognex Barcode Reader HMI Interface
Freigegeben für IBN (22.04.2025)
@@ -0,0 +1,6 @@
DocumentHash:
- FileName: stHMI_BRCognexDM.xml
Hash: r2yXtsMPR1tYYayK89wCaBfoYnfvbcC8U08Pmqz3ghQ=
LibraryMetaFileHash: 2QmCAfK/VMBYGEhHb3XXb2Mlozb9v/F06igsbe8CqUI=
LibraryVersion:
Guid: 4292f22b-ef2b-4a96-8038-d15fd7be6b5a
@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<Document>
<Engineering version="V20" />
<SW.Types.PlcStruct ID="0">
<AttributeList>
<Interface><Sections xmlns="http://www.siemens.com/automation/Openness/SW/Interface/v5">
<Section Name="None">
<Member Name="In16" Datatype="Word" />
<Member Name="Out16" Datatype="Word" />
<Member Name="Barcode" Datatype="LInt" />
<Member Name="BarcodeString" Datatype="String" />
<Member Name="ResultID" Datatype="Int" />
<Member Name="ErrorWord" Datatype="Word" />
</Section>
</Sections></Interface>
<Name>stHMI_BRCognexDM</Name>
<Namespace />
</AttributeList>
<ObjectList>
<MultilingualText ID="1" CompositionName="Comment">
<ObjectList>
<MultilingualTextItem ID="2" CompositionName="Items">
<AttributeList>
<Culture>de-DE</Culture>
<Text />
</AttributeList>
</MultilingualTextItem>
</ObjectList>
</MultilingualText>
<MultilingualText ID="3" CompositionName="Title">
<ObjectList>
<MultilingualTextItem ID="4" CompositionName="Items">
<AttributeList>
<Culture>de-DE</Culture>
<Text />
</AttributeList>
</MultilingualTextItem>
</ObjectList>
</MultilingualText>
</ObjectList>
</SW.Types.PlcStruct>
</Document>
@@ -0,0 +1,14 @@
LibraryType:
Guid: ff362ef5-3706-4678-9b8f-9b5edec9d6cc
Comment:
de-DE: Encoder TR
LibraryVersion:
VersionNumber: 2.0.0
Author: e.yueksel
IsDefault: true
Comment:
de-DE: |-
CHANGED: Angleich an ILS Testversion (Stand: 03.02.2025)
CHANGED: Globale Konstante "cEncoderScaling" gegen lokale Konstante getauscht
Freigegeben für IBN (EY, 22.04.2025)
@@ -0,0 +1,9 @@
DocumentHash:
- FileName: FB_EncoderTR.scl
Hash: lAU38Ds+TsapS+ZQ4p5ClovY85o6+dj/r4TM8y2vS/4=
LibraryMetaFileHash: QwiMrqRTP+HgutRyzKwkQFevBlA6qZIO3E9CXAnzj0g=
LibraryVersion:
Guid: 46ef14f8-3462-4511-aec5-4139a799256f
DependsOn:
- TypeName: UDT_Sensor
VersionNumber: 2.0.0
@@ -0,0 +1,197 @@
FUNCTION_BLOCK "FB_EncoderTR"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
VAR_INPUT
nInPosAct : DInt;
xInPresetAdjQuit : Bool;
xInPresetAdjSet : Bool;
nInPresetAdjSetValue : DInt; // Abweichung in mm
nInPitch : DInt := 254;
nInEncoderMax : DInt;
nInHooksSorterMax : DInt;
stInSensorReference { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : "UDT_Sensor";
END_VAR
VAR_OUTPUT
xOutPresetAdjSet : Bool;
nOutPresetAdjSetValue : DInt;
nOutPosAct : DInt;
nOutPosActDif : DInt;
bOutReferenced : Bool;
nOutPosPitch : DInt;
nOutPosPitchDif : DInt;
nOutPosPitchPart : DInt; // Skaliert [0-100]%
END_VAR
VAR
arIncremente : Array[0..40] of DInt;
nPos : Int;
xSensorFlag : Bool;
nStateAdjustment : Int;
nPosActDif { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : DInt;
nPosPitchDif : DInt;
nPosAct : DInt;
nPosPitchAct : DInt;
nTest : Array[0..40] of DInt;
nPosPitchPart : DInt;
END_VAR
VAR CONSTANT
cReferenceValue : DInt;
cEncoderScaling : DInt := 100; // Scalierung des Encoders pro Teilung
END_VAR
BEGIN
REGION GeberParameter
(*
Einstellungen für Pinband ILS Testanlage
Anzahl Taschen: 54 Stück (länge des Bandes)
Durchmesser: 278mm
Kettenteilung (pro Tasche): 250mm
Eingabe im Geber:
Gesamtmesslänge = 13500 (Bandteilung * Anzahl Taschen)
Umdrehungen Zähler = 154575
Umdrehungen Nenner = 10000
-> PosAct = Position in mm
Einstellungen für Fingerband ILS Testanlage
Anzahl Taschen: 26 Stück (länge der Kette)
Kettenrad: 17 Zähne
Kettenteilung (pro Tasche): 254mm
Kettenglieder pro Tasche: 32 Stück
Eingabe im Geber:
Gesamtmesslänge = 6604 (Kettenteilung * Anzahl Taschen)
Umdrehungen Zähler = 244706 (Anzahl Taschen * Kettenglieder pro Tasche)
Umdrehungen Nenner = 10000 (Kettenrad)
-> PosAct = Position in mm
*)
END_REGION
REGION Adjustment
CASE #nStateAdjustment OF
0: // Undefined
#bOutReferenced := 0;
#nStateAdjustment := 10;
10: // Wait for Reference Sensor 1st Time
IF #stInSensorReference.xDirectEdgePos THEN
#nStateAdjustment := 15;
END_IF;
15: // Wait for Reference Sensor 2nd Time
IF #stInSensorReference.xDirectEdgePos THEN
#nStateAdjustment := 20;
#xOutPresetAdjSet := 1;
IF #xInPresetAdjSet THEN
#nOutPresetAdjSetValue := #nInPresetAdjSetValue;
ELSE
#nOutPresetAdjSetValue := #cReferenceValue;
END_IF;
END_IF;
20: // Wait for Quit
#xOutPresetAdjSet := 1;
IF #xInPresetAdjSet THEN
#nOutPresetAdjSetValue := #nInPresetAdjSetValue;
ELSE
#nOutPresetAdjSetValue := #cReferenceValue;
END_IF;
IF #xInPresetAdjQuit THEN
#xOutPresetAdjSet := 0;
#nStateAdjustment := 30;
END_IF;
30: // Wait for Reset the #xInPresetAdjSet Input
IF NOT #xInPresetAdjSet THEN
#nStateAdjustment := 100;
#nTest[1] := 0;
END_IF;
100: // First Refernce Set
#bOutReferenced := 1;
IF #xInPresetAdjSet THEN
#nStateAdjustment := 0;
END_IF;
END_CASE;
END_REGION
REGION Positionsänderung ermitteln
#nPosActDif := #nInPosAct - #nPosAct;
IF (#nInPosAct < #nPosAct) AND // Wenn die neue Position kleiner ist als der alte Wert
ABS(#nPosActDif) > (#nInEncoderMax / 2) THEN // Und die differenz Größer als die Hälfte des Encoderendwertes
#nPosActDif := #nInEncoderMax - #nPosAct;
#nPosActDif += #nInPosAct;
#nPosAct := #nInPosAct;
ELSIF #nPosActDif > 0 THEN
#nPosAct := #nInPosAct;
ELSE
#nPosActDif := 0;
#nPosAct := #nInPosAct;
END_IF;
(*
IF #nPosActDif > 0 THEN
#nPosAct := #nInPosAct;
ELSIF ABS(#nPosActDif) > ("cEncoderMax" / 2) THEN
#nPosActDif := "cEncoderMax" - #nPosAct;
#nPosActDif += #nInPosAct;
#nPosAct := #nInPosAct;
ELSE
#nPosActDif := 0;
#nPosAct := #nInPosAct;
END_IF;
*)
END_REGION
REGION Pitch
#nOutPosPitch := #nInPosAct / #nInPitch; // Taschennummer nach Encoder
//#nOutPosPitchPart := REAL_TO_DINT(((#nInPosAct MOD #nInPitch)));
//TEST MOLINA ANFANG
#nOutPosPitchPart := (#"cEncoderScaling" * (#nInPosAct MOD #nInPitch)) / #nInPitch; // Skalierter Restwert Taschenzwischenschritt
//TEST MOLINA ENDE
#nPosPitchDif := #nOutPosPitch - #nPosPitchAct;
IF ABS(#nPosPitchDif) > (#nInHooksSorterMax / 2) THEN
#nPosPitchDif := #nInHooksSorterMax - #nPosPitchAct;
#nPosPitchDif += #nOutPosPitch;
#nPosPitchAct := #nOutPosPitch;
ELSIF #nPosPitchDif > 0 THEN
#nPosPitchAct := #nOutPosPitch;
ELSE
#nPosPitchDif := 0;
#nPosPitchAct := #nOutPosPitch;
END_IF;
END_REGION
REGION Outputs
IF #nStateAdjustment = 100 THEN
#nOutPosAct := #nInPosAct;
END_IF;
#nOutPosActDif := #nPosActDif;
#nOutPosPitchDif := #nPosPitchDif;
#nTest[0] += #nPosPitchDif;
IF #stInSensorReference.xDirectEdgePos THEN
#nTest[1] += 1;
END_IF;
END_REGION
REGION Statistic
#arIncremente[#nPos] += #nPosActDif;
IF #stInSensorReference.xDirectEdgePos THEN
(*
#nPosActDif := #nInPosAct - #nPosAct;
IF #nPosActDif > 0 THEN
#nPosAct := #nInPosAct;
ELSIF ABS(#nPosActDif) > ("cEncoderMax" / 2) THEN
#nPosActDif := "cEncoderMax" - #nPosAct;
#nPosActDif += #nInPosAct;
#nPosAct := #nInPosAct;
ELSE
#nPosActDif := 0;
#nPosAct := #nInPosAct;
END_IF;
*)
#nPos += 1;
IF #nPos > 40 THEN
#nPos := 0;
END_IF;
END_IF;
END_REGION
END_FUNCTION_BLOCK
@@ -0,0 +1,10 @@
LibraryType:
Guid: a35365d7-dff1-4ac5-9689-8750d7467e8e
Comment:
de-DE: Sensor Interface (Flanken, Stau etc.)
LibraryVersion:
VersionNumber: 2.0.3
Author: e.yueksel
IsDefault: true
Comment:
de-DE: aktualisiert wegen unterlagerter Änderung
@@ -0,0 +1,15 @@
DocumentHash:
- FileName: FB_SensorInput.scl
Hash: AlAVLvJXtSwVO/JfArSvLoOOdNN4MVw9gFmg6QucV+M=
LibraryMetaFileHash: CyRGpaSqwJewa6ic6V5dGHgKYoRJ9vxuiRUgbTHGAhs=
LibraryVersion:
Guid: b1b8d1e1-2be4-46f5-8e3b-08cc20f9ff04
DependsOn:
- TypeName: FB_Monitoring
VersionNumber: 2.0.5
- TypeName: UDT_Sensor
VersionNumber: 2.0.0
- TypeName: UDT_HMI_Sensor
VersionNumber: 2.0.0
- TypeName: UDT_MainState
VersionNumber: 2.0.0
@@ -0,0 +1,183 @@
FUNCTION_BLOCK "FB_SensorInput"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
VAR_INPUT
sInFctName : String[10]; // Sensor Funktion (z.B. Stau)
sInName : String[10]; // Sensor BMK
xInSensor : Bool;
tInDelay : Time := T#150ms;
tInFlicker : Time := T#20ms;
tInJamR : Time := T#3000ms;
tInJamF : Time := T#2000ms;
tInSenFreeShort : Time := T#4000ms;
tInSenFreeLong : Time := T#7000ms;
xInMonitorJam : Bool;
END_VAR
VAR_OUTPUT
xOutFlickerError : Bool;
xOutJam : Bool;
xOutFreeShort : Bool;
xOutFreeLong : Bool;
nOutCntFlicker : Int;
END_VAR
VAR_IN_OUT
stInOutSensor : "UDT_Sensor";
stInOutHMI : "UDT_HMI_Sensor";
stInOutControlUnitCabinet : "UDT_MainState";
END_VAR
VAR
tOnNoSensorChange {InstructionName := 'TON_TIME'; LibVersion := '1.0'} : TON_TIME;
nCntFlickerPos : Int;
nCntFlickerNeg : Int;
xSensorFlag : Bool;
xSensorDbncdFlag : Bool;
xSensorDbncd { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool;
nActualDay : USInt;
xJam : Bool;
fbMonitoringJam : "FB_Monitoring";
END_VAR
VAR_TEMP
tSensor : Bool;
tDebug : Int;
END_VAR
BEGIN
// ------------------------------------------------
// GLOBAL INFORMATION - do before other FB calls
// ------------------------------------------------
REGION read inputs
#tSensor := (NOT #stInOutHMI.stSensorControl.xControlWithHMI AND #xInSensor) OR
(#stInOutHMI.stSensorControl.xControlWithHMI AND #stInOutHMI.stSensorControl.xSensor);
END_REGION
REGION logic
#stInOutSensor.xDirectSensor := #tSensor;
#stInOutSensor.xDirectEdgePos := #tSensor AND NOT #xSensorFlag AND NOT "FirstScan";
#stInOutSensor.xDirectEdgeNeg := NOT #tSensor AND #xSensorFlag AND NOT "FirstScan";
IF #tSensor AND
((#xSensorFlag = #tSensor AND #tOnNoSensorChange.ET >= #tInDelay) OR "FirstScan") THEN
#xSensorDbncd := TRUE;
ELSIF NOT #tSensor AND
((#xSensorFlag = #tSensor AND #tOnNoSensorChange.ET >= #tInDelay) OR "FirstScan") THEN
#xSensorDbncd := FALSE;
END_IF;
#stInOutSensor.xDbncdEdgePos := #xSensorDbncd AND NOT #xSensorDbncdFlag;
#stInOutSensor.xDbncdEdgeNeg := NOT #xSensorDbncd AND #xSensorDbncdFlag;
END_REGION
REGION detect flickering
#xOutFlickerError := FALSE;
IF #tSensor AND NOT #xSensorFlag AND //ging kurzzeitig auf 0
#tOnNoSensorChange.ET <= #tInFlicker AND
NOT #stInOutHMI.stSensorControl.xControlWithHMI THEN
#xOutFlickerError := TRUE;
#nCntFlickerNeg += 1;
ELSIF
NOT #tSensor AND #xSensorFlag AND // geht kurzzeitig auf 1
#tOnNoSensorChange.ET <= #tInFlicker AND
NOT #stInOutHMI.stSensorControl.xControlWithHMI THEN
#xOutFlickerError := TRUE;
#nCntFlickerPos += 1;
END_IF;
(* // Am Ende des Tages die Zähler zurücksetzten
IF "DB_MachineGlobal".DTL_TimePLC.DAY <> #nActualDay THEN
#nActualDay := "DB_MachineGlobal".DTL_TimePLC.DAY;
#nCntFlickerNeg := 0;
#nCntFlickerPos := 0;
END_IF; *)
END_REGION
REGION timer
#tOnNoSensorChange(IN := (#tSensor = #xSensorFlag),
PT := T#10000S);
END_REGION
REGION flags
#xSensorFlag := #tSensor;
#xSensorDbncdFlag := #xSensorDbncd;
END_REGION
REGION detect jam signal
IF #tSensor AND #tOnNoSensorChange.ET > #tInJamR THEN
#xJam := TRUE;
ELSIF NOT #tSensor AND #tOnNoSensorChange.ET > #tInJamF THEN
#xJam := FALSE;
END_IF;
END_REGION
REGION detect if sensor is false for period of time
IF NOT #tSensor AND #tOnNoSensorChange.ET > #tInSenFreeShort THEN
#xOutFreeShort := TRUE;
ELSE
#xOutFreeShort := FALSE;
END_IF;
IF NOT #tSensor AND #tOnNoSensorChange.ET > #tInSenFreeLong THEN
#xOutFreeLong := TRUE;
ELSE
#xOutFreeLong := FALSE;
END_IF;
END_REGION ;
REGION write outputs
#xOutJam := #xJam;
#stInOutSensor.xDbncdSensor := #xSensorDbncd;
#stInOutSensor.sName := #sInName;
#stInOutSensor.xJam := #xJam;
IF #tOnNoSensorChange.ET >= #tInDelay THEN //
#stInOutSensor.tDirectChangeLast := #tOnNoSensorChange.ET;
ELSE
#stInOutSensor.tDirectChangeLast := T#0s;
END_IF;
#nOutCntFlicker := #nCntFlickerNeg + #nCntFlickerPos;
END_REGION
REGION HMI interface
#stInOutHMI.stSensorStatus.sName := #sInName;
#stInOutHMI.stSensorStatus.xDirectSensor := #tSensor;
#stInOutHMI.stSensorStatus.xDirectEdgePos := #tSensor AND NOT #xSensorFlag AND NOT "FirstScan";
#stInOutHMI.stSensorStatus.xDirectEdgeNeg := NOT #tSensor AND #xSensorFlag AND NOT "FirstScan";
IF #tOnNoSensorChange.ET >= #tInDelay THEN
#stInOutHMI.stSensorStatus.tDirectChangeLast := #tOnNoSensorChange.ET;
ELSE
#stInOutHMI.stSensorStatus.tDirectChangeLast := T#0s;
END_IF;
#stInOutHMI.stSensorStatus.xDbncdSensor := #xSensorDbncd;
#stInOutHMI.stSensorStatus.xDbncdEdgePos := #xSensorDbncd AND NOT #xSensorDbncdFlag;
#stInOutHMI.stSensorStatus.xDbncdEdgeNeg := NOT #xSensorDbncd AND #xSensorDbncdFlag;
#stInOutHMI.stSensorStatus.xJam := #xJam;
END_REGION
REGION monitoring jam
#fbMonitoringJam.stSettings.nErrorType := 1;
#fbMonitoringJam.stSettings.xErrLedIfMachineIsOff := TRUE;
#fbMonitoringJam.stSettings.xSelfQuit := TRUE;
#fbMonitoringJam.stSettings.tDelay := T#1s;
#fbMonitoringJam(sInFctnName := 'Stauueberwachung',
sInPrefix := #sInFctName,
sInAlarmMessage := 'Sensor meldet Stau',
sInSuffix := #sInName,
wInTextListId_Message := 2,
InOutMachineState := #stInOutControlUnitCabinet,
xInSignal := (NOT #xJam) OR NOT #xInMonitorJam);
END_REGION
END_FUNCTION_BLOCK
@@ -0,0 +1,11 @@
LibraryType:
Guid: 7dd56464-1b63-4d64-b2d7-887bdb82e393
LibraryVersion:
VersionNumber: 2.0.0
Author: e.yueksel
IsDefault: true
Comment:
de-DE: |-
HMI Schnittstelle Sensor gesamt
Freigegeben für IBN (EY, 22.04.2025)
@@ -0,0 +1,13 @@
DocumentHash:
- FileName: UDT_HMI_Sensor.xml
Hash: pdpSaxLHHvmtFPis2kxAHCIGbaHxTFdN8tJtZWBViZ0=
LibraryMetaFileHash: pjTVRyZilhDWD1G0TlCpop0/Hr20FaE5CeWAuYTlLsQ=
LibraryVersion:
Guid: b57e71d3-bb28-42e3-98c8-056af10bfdcb
DependsOn:
- TypeName: UDT_Sensor
VersionNumber: 2.0.0
- TypeName: UDT_HMI_Sensor_Config
VersionNumber: 2.0.0
- TypeName: UDT_HMI_Sensor_Control
VersionNumber: 2.0.0
@@ -0,0 +1,51 @@
<?xml version="1.0" encoding="utf-8"?>
<Document>
<Engineering version="V20" />
<SW.Types.PlcStruct ID="0">
<AttributeList>
<Interface><Sections xmlns="http://www.siemens.com/automation/Openness/SW/Interface/v5">
<Section Name="None">
<Member Name="stSensorStatus" Datatype="&quot;UDT_Sensor&quot;">
<AttributeList>
<BooleanAttribute Name="SetPoint" SystemDefined="true">true</BooleanAttribute>
</AttributeList>
</Member>
<Member Name="stSensorConfig" Datatype="&quot;UDT_HMI_SensorConfig&quot;">
<AttributeList>
<BooleanAttribute Name="SetPoint" SystemDefined="true">true</BooleanAttribute>
</AttributeList>
</Member>
<Member Name="stSensorControl" Datatype="&quot;UDT_HMI_SensorCtrl&quot;">
<AttributeList>
<BooleanAttribute Name="SetPoint" SystemDefined="true">true</BooleanAttribute>
</AttributeList>
</Member>
</Section>
</Sections></Interface>
<Name>UDT_HMI_Sensor</Name>
<Namespace />
</AttributeList>
<ObjectList>
<MultilingualText ID="1" CompositionName="Comment">
<ObjectList>
<MultilingualTextItem ID="2" CompositionName="Items">
<AttributeList>
<Culture>de-DE</Culture>
<Text />
</AttributeList>
</MultilingualTextItem>
</ObjectList>
</MultilingualText>
<MultilingualText ID="3" CompositionName="Title">
<ObjectList>
<MultilingualTextItem ID="4" CompositionName="Items">
<AttributeList>
<Culture>de-DE</Culture>
<Text />
</AttributeList>
</MultilingualTextItem>
</ObjectList>
</MultilingualText>
</ObjectList>
</SW.Types.PlcStruct>
</Document>
@@ -0,0 +1,11 @@
LibraryType:
Guid: 50f6123e-5cf5-451c-991a-e3b8c4fc53e6
LibraryVersion:
VersionNumber: 2.0.0
Author: e.yueksel
IsDefault: true
Comment:
de-DE: |-
HMI: Sensor Konfiguration
Freigegeben für IBN (EY, 22.04.2025)
@@ -0,0 +1,6 @@
DocumentHash:
- FileName: UDT_HMI_Sensor_Config.xml
Hash: qVtFL7MkmbLJxHZ7EimCYQhPUE1d68oJJe/I6gMX/4A=
LibraryMetaFileHash: mDWR4ZOzDreembK/g+lNYKUCuVdT/bM6lH3CjStr054=
LibraryVersion:
Guid: e4319c82-04b6-4bf6-856a-f001cb82348c
@@ -0,0 +1,66 @@
<?xml version="1.0" encoding="utf-8"?>
<Document>
<Engineering version="V20" />
<SW.Types.PlcStruct ID="0">
<AttributeList>
<Interface><Sections xmlns="http://www.siemens.com/automation/Openness/SW/Interface/v5">
<Section Name="None">
<Member Name="tDelay" Datatype="Time">
<Comment>
<MultiLanguageText Lang="de-DE">Entprellzeit für Debounced</MultiLanguageText>
</Comment>
</Member>
<Member Name="tFlicker" Datatype="Time">
<Comment>
<MultiLanguageText Lang="de-DE">Zeit die als "Flackern" eingestuft wird</MultiLanguageText>
</Comment>
</Member>
<Member Name="tJamR" Datatype="Time">
<Comment>
<MultiLanguageText Lang="de-DE">Zeit bis Stau steigende Flanke</MultiLanguageText>
</Comment>
</Member>
<Member Name="tJamF" Datatype="Time">
<Comment>
<MultiLanguageText Lang="de-DE">Zeit bis Stau fallende Flanke</MultiLanguageText>
</Comment>
</Member>
<Member Name="tSenFreeShort" Datatype="Time">
<Comment>
<MultiLanguageText Lang="de-DE">Sensor seit Zeit x frei (Zeit 1, kurz)</MultiLanguageText>
</Comment>
</Member>
<Member Name="tSenFreeLong" Datatype="Time">
<Comment>
<MultiLanguageText Lang="de-DE">Sensor seit Ueit x frei (Zeit 2, lang)</MultiLanguageText>
</Comment>
</Member>
</Section>
</Sections></Interface>
<Name>UDT_HMI_Sensor_Config</Name>
<Namespace />
</AttributeList>
<ObjectList>
<MultilingualText ID="1" CompositionName="Comment">
<ObjectList>
<MultilingualTextItem ID="2" CompositionName="Items">
<AttributeList>
<Culture>de-DE</Culture>
<Text />
</AttributeList>
</MultilingualTextItem>
</ObjectList>
</MultilingualText>
<MultilingualText ID="3" CompositionName="Title">
<ObjectList>
<MultilingualTextItem ID="4" CompositionName="Items">
<AttributeList>
<Culture>de-DE</Culture>
<Text />
</AttributeList>
</MultilingualTextItem>
</ObjectList>
</MultilingualText>
</ObjectList>
</SW.Types.PlcStruct>
</Document>
@@ -0,0 +1,11 @@
LibraryType:
Guid: 09d91f68-6a2d-4805-86d6-9574c935a865
LibraryVersion:
VersionNumber: 2.0.0
Author: e.yueksel
IsDefault: true
Comment:
de-DE: |-
HMI: Sensor kontrollieren
Freigegeben für IBN (EY, 22.04.2025)
@@ -0,0 +1,6 @@
DocumentHash:
- FileName: UDT_HMI_Sensor_Control.xml
Hash: bWLPsGarsUcnfdbdiUbARe+Bjt4MWYui0farXKX091w=
LibraryMetaFileHash: 4h5gTdhZdANRu7ObG4Q0GM5Z+gROxsHK6PIhP8+U3KM=
LibraryVersion:
Guid: 0315a473-65a3-42eb-8abe-27c8b0341757
@@ -0,0 +1,46 @@
<?xml version="1.0" encoding="utf-8"?>
<Document>
<Engineering version="V20" />
<SW.Types.PlcStruct ID="0">
<AttributeList>
<Interface><Sections xmlns="http://www.siemens.com/automation/Openness/SW/Interface/v5">
<Section Name="None">
<Member Name="xControlWithHMI" Datatype="Bool">
<Comment>
<MultiLanguageText Lang="de-DE">Sensor per HMI steuern aktivieren</MultiLanguageText>
</Comment>
</Member>
<Member Name="xSensor" Datatype="Bool">
<Comment>
<MultiLanguageText Lang="de-DE">Sensor HMI</MultiLanguageText>
</Comment>
</Member>
</Section>
</Sections></Interface>
<Name>UDT_HMI_Sensor_Control</Name>
<Namespace />
</AttributeList>
<ObjectList>
<MultilingualText ID="1" CompositionName="Comment">
<ObjectList>
<MultilingualTextItem ID="2" CompositionName="Items">
<AttributeList>
<Culture>de-DE</Culture>
<Text />
</AttributeList>
</MultilingualTextItem>
</ObjectList>
</MultilingualText>
<MultilingualText ID="3" CompositionName="Title">
<ObjectList>
<MultilingualTextItem ID="4" CompositionName="Items">
<AttributeList>
<Culture>de-DE</Culture>
<Text />
</AttributeList>
</MultilingualTextItem>
</ObjectList>
</MultilingualText>
</ObjectList>
</SW.Types.PlcStruct>
</Document>
@@ -0,0 +1,13 @@
LibraryType:
Guid: daf03d56-a8bc-4c33-9e87-b6b4ed277fe3
Comment:
de-DE: 'Anwenderdatentyp für Separator '
LibraryVersion:
VersionNumber: 2.0.0
Author: e.yueksel
IsDefault: true
Comment:
de-DE: |-
Standard Sensor Interface
Freigegeben für IBN (EY, 22.04.2025)
@@ -0,0 +1,6 @@
DocumentHash:
- FileName: UDT_Sensor.xml
Hash: gZqmsqXcGDYJlbUue+QglmkruFD+MU4TdxwktDL+wSM=
LibraryMetaFileHash: fmiqCPUQjv/AmVJlc2IJ0GwWtyG6giYM7RrNeIVaX2Y=
LibraryVersion:
Guid: d053d64c-e366-43e2-bd21-474f5cd34c8f
@@ -0,0 +1,81 @@
<?xml version="1.0" encoding="utf-8"?>
<Document>
<Engineering version="V20" />
<SW.Types.PlcStruct ID="0">
<AttributeList>
<Interface><Sections xmlns="http://www.siemens.com/automation/Openness/SW/Interface/v5">
<Section Name="None">
<Member Name="sName" Datatype="String[10]">
<Comment>
<MultiLanguageText Lang="de-DE">Sensor BMK</MultiLanguageText>
</Comment>
</Member>
<Member Name="xDirectSensor" Datatype="Bool">
<Comment>
<MultiLanguageText Lang="de-DE">Direktes Signal ohne Verarbeitung</MultiLanguageText>
</Comment>
</Member>
<Member Name="xDirectEdgePos" Datatype="Bool">
<Comment>
<MultiLanguageText Lang="de-DE">Positive Flanke</MultiLanguageText>
</Comment>
</Member>
<Member Name="xDirectEdgeNeg" Datatype="Bool">
<Comment>
<MultiLanguageText Lang="de-DE">Negative Flanke</MultiLanguageText>
</Comment>
</Member>
<Member Name="tDirectChangeLast" Datatype="Time">
<Comment>
<MultiLanguageText Lang="de-DE">Zeit seit letzter Änderung Signalwechsel</MultiLanguageText>
</Comment>
</Member>
<Member Name="xDbncdSensor" Datatype="Bool">
<Comment>
<MultiLanguageText Lang="de-DE">Entprelltes Signal</MultiLanguageText>
</Comment>
</Member>
<Member Name="xDbncdEdgePos" Datatype="Bool">
<Comment>
<MultiLanguageText Lang="de-DE">Entprellte positive Flanke</MultiLanguageText>
</Comment>
</Member>
<Member Name="xDbncdEdgeNeg" Datatype="Bool">
<Comment>
<MultiLanguageText Lang="de-DE">Entprellte negative Flanke</MultiLanguageText>
</Comment>
</Member>
<Member Name="xJam" Datatype="Bool">
<Comment>
<MultiLanguageText Lang="de-DE">Stau Indikator</MultiLanguageText>
</Comment>
</Member>
</Section>
</Sections></Interface>
<Name>UDT_Sensor</Name>
<Namespace />
</AttributeList>
<ObjectList>
<MultilingualText ID="1" CompositionName="Comment">
<ObjectList>
<MultilingualTextItem ID="2" CompositionName="Items">
<AttributeList>
<Culture>de-DE</Culture>
<Text />
</AttributeList>
</MultilingualTextItem>
</ObjectList>
</MultilingualText>
<MultilingualText ID="3" CompositionName="Title">
<ObjectList>
<MultilingualTextItem ID="4" CompositionName="Items">
<AttributeList>
<Culture>de-DE</Culture>
<Text />
</AttributeList>
</MultilingualTextItem>
</ObjectList>
</MultilingualText>
</ObjectList>
</SW.Types.PlcStruct>
</Document>
@@ -0,0 +1,10 @@
LibraryType:
Guid: 8024a909-1e3e-4f70-8f13-ffe7958aad3e
Comment:
de-DE: Ein Signal überwachen.
LibraryVersion:
VersionNumber: 2.0.5
Author: e.yueksel
IsDefault: true
Comment:
de-DE: Änderung im unterlagerten Baustein
@@ -0,0 +1,15 @@
DocumentHash:
- FileName: FB_Monitoring.scl
Hash: 7zVFA7a6jJLu2JXdmpI/wOoD9NJ1ZKE124qCEzQAG80=
LibraryMetaFileHash: FyVT72eNe8+4aol3t4NG6coi+oUFlavaZw4zLGWezD0=
LibraryVersion:
Guid: 2e5c8d6b-fd81-4364-8c85-7c635e9e9be3
DependsOn:
- TypeName: UDT_MainState
VersionNumber: 2.0.0
- TypeName: FB_SetAlarmAndLog
VersionNumber: 2.0.1
- TypeName: FB_Blinker
VersionNumber: 2.0.0
- TypeName: UDT_HMI_Monitoring
VersionNumber: 2.0.0
@@ -0,0 +1,114 @@
FUNCTION_BLOCK "FB_Monitoring"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
VAR_INPUT
xInQuitError : Bool; // Quittierung des Alarms
stSettings : Struct
xErrLedIfMachineIsOff : Bool; // LED-Ausgang aktiv wenn Maschine nicht in "run"
xSelfQuit : Bool; // Selbstquittierung wenn Fehler weg
xStopMachine : Bool; // Maschine wird gestoppt falls dieser Fehler auftritt
nErrorType : Int := 1; // 0: IntError | 1: Error | 2: Warning | 3: Information | 4: Debug
tDelay : Time; // Zeitverzögerung bis Fehler geworfen wird
tBlinkerTime : Time := t#500ms;
END_STRUCT;
sInFctnName : String; // Name der Funktion
xInSignal : Bool; // Einfang des Fehlers. Fehler wird geworfen wenn xInSignal = FALSE
sInPrefix : String[30]; // Anfangstext der Fehlermeldung
sInAlarmMessage : String; // Haupttext der Fehlermeldung
sInSuffix : String[30]; // Endtext der Fehlermeldung
wInTextListId_Message : Word;
wInTextListId_Function : Word;
wInTextListId_Prefix : Word;
wInTextListId_Suffix : Word;
END_VAR
VAR_OUTPUT
xOutOk : Bool; // TRUE = Kein Fehler
xOutError : Bool; // TRUE = Error
xOutLedError : Bool; // FehlerLED leuchten lassen
xOutAckReq : Bool; // TRUE: Quittierung angefordert
stOutHMI : "UDT_HMI_Monitoring";
END_VAR
VAR_IN_OUT
InOutMachineState : "UDT_MainState"; // Mit "xStopMachine" des jeweiligen StateMachine verbinden
END_VAR
VAR
xOk : Bool := true;
tOffTimer {InstructionName := 'TOF_TIME'; LibVersion := '1.0'} : TOF_TIME;
fbSetAlarmAndLog : "FB_SetAlarmAndLog";
FB_Blinker : "FB_Blinker";
END_VAR
BEGIN
REGION Blinker
// #FB_Blinker(tInPeriodicTime := #stSettings.tBlinkerTime,
// xInActivate := 1);
END_REGION
REGION Aktivieren
IF NOT #xOk AND
#xInSignal AND
(#xInQuitError OR #InOutMachineState.xQuitError OR #stSettings.xSelfQuit) THEN
#xOk := TRUE;
END_IF;
END_REGION
REGION Timer
IF #stSettings.tDelay > T#0ms THEN
#tOffTimer(IN := #xInSignal,
PT := #stSettings.tDelay);
END_IF;
END_REGION
REGION Deaktivieren
IF #xOk AND
(#stSettings.tDelay = T#0ms AND // kein Delay
NOT #xInSignal) OR
(#stSettings.tDelay > T#0ms AND // mit Delay-timer
NOT #tOffTimer.Q) THEN
#xOk := FALSE;
END_IF;
END_REGION
REGION Monitoring
#fbSetAlarmAndLog.stSettings.nNoMaxErrors := 1;
#fbSetAlarmAndLog.stSettings.nType := #stSettings.nErrorType;
#fbSetAlarmAndLog.stSettings.sFctnName := #sInFctnName;
#fbSetAlarmAndLog(xInAlarm := NOT #xOk,
nInAlarmNumber := 0,
sInPrefix := #sInPrefix,
sInAlarmMessage := #sInAlarmMessage,
sInSuffix := #sInSuffix,
wInTextListId_Message:= #wInTextListId_Message,
wInTextListId_Function := #wInTextListId_Function,
wInTextListId_Prefix := #wInTextListId_Prefix,
wInTextListId_Suffix := #wInTextListId_Suffix,
stInOutControlUnitCabinet:= #InOutMachineState);
END_REGION
REGION Ausgang schreiben
#xOutLedError := ((NOT #xOk AND #xInSignal AND "Clock_1Hz" (* #FB_Blinker.xOutput *)) OR // Nicht quttiert
(NOT #xOk AND NOT #xInSignal)) // Quittiert
AND (#InOutMachineState.xRunning OR #stSettings.xErrLedIfMachineIsOff);
// #InOutMachineState.xError := NOT #xOk;
#xOutOk := #xOk;
#xOutError := NOT #xOk;
#xOutAckReq := NOT #xOk AND #xInSignal;
IF NOT #xOk AND
#stSettings.xStopMachine THEN
#InOutMachineState.xStopMachine := TRUE;
END_IF;
END_REGION
REGION HMI
#stOutHMI.xSigOk := #xOk;
#stOutHMI.xAckReq := #xOutAckReq;
END_REGION
END_FUNCTION_BLOCK
@@ -0,0 +1,14 @@
LibraryType:
Guid: 2d4f98e2-307a-4d8c-ad18-172d395d7189
Comment:
de-DE: |-
Zeile 45 Fehler beseitigt, Variable hatte sich selbst beschrieben
(InOutMachineState.xError := InOutMachineState.xError OR NOT xOk)
-> zusätzlich Zeile auskommentiert
LibraryVersion:
VersionNumber: 2.0.1
Author: e.yueksel
IsDefault: true
Comment:
de-DE: verbesserungen im Handling und Fehlerfälle
@@ -0,0 +1,15 @@
DocumentHash:
- FileName: FB_SetAlarmAndLog.scl
Hash: 8qG1qPBoUdaSG9VcMOvZ2L2HvGjSFHHK8sZBpMcbShg=
LibraryMetaFileHash: h/GHYK+TRn0hzsHGxrm4PS4stX7Tau4elDYd02T0GAY=
LibraryVersion:
Guid: da7f5558-c66c-49f0-982d-1c07a6997146
DependsOn:
- TypeName: DataLogBuffer
VersionNumber: 2.0.0
- TypeName: UDT_MainState
VersionNumber: 2.0.0
- TypeName: FC_TimeAsString
VersionNumber: 0.0.14
- TypeName: FC_GetAlarmNo
VersionNumber: 2.0.0
@@ -0,0 +1,227 @@
FUNCTION_BLOCK "FB_SetAlarmAndLog"
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
VAR_INPUT
stSettings : Struct // Grundsätzliche einstellungen des Bausteins
sFctnName : String[20]; // Name der Funktion die den Fehler wirft
nNoMaxErrors : UInt := 32; // Maximale Anzahl an Fehlern. Werden über "xPlcReOrg" zugewiesen.
nType : Int := 0; // 0: IntError | 1: Error | 2: Warning | 3: Information | 4: Debug
END_STRUCT;
xInAlarm : Bool; // An: Fehler liegt an. | Aus: Kein Fehler liegt an
nInAlarmPriority : USInt := 1; // Priorität des Fehlers: 1 = Höchste Prio. | 30 = Niedrigste Prio.
nInAlarmNumber : UInt; // Fehlernummer von 0 bis (stSettings.nNoMaxErrors - 1)
sInPrefix : String[20]; // Text vor der Fehlermeldung
sInAlarmMessage : String[20]; // Text der Fehlermeldung
sInSuffix : String[20]; // Text nach der Fehlermeldung
wInTextListId_Message : Word;
wInTextListId_Function : Word;
wInTextListId_Prefix : Word;
wInTextListId_Suffix : Word;
wInTextListId_Separator : Word;
END_VAR
VAR_OUTPUT
xOutRdy : Bool; // Zeigt an, ob ein neuer Fehler geschrieben werden darf
END_VAR
VAR_IN_OUT
stInOutControlUnitCabinet : "UDT_MainState";
END_VAR
VAR RETAIN
nAlarmNoOffset : UInt;
END_VAR
VAR
wStatus : Word;
xAlarmFlag : Bool;
sErrorString : String;
xSetProgramAlarm : Bool;
fbProgram_Alarm {InstructionName := 'Program_Alarm'; LibVersion := '1.0'} : Program_Alarm;
xRetryProgramAlarm : Bool;
END_VAR
VAR_TEMP
xTemp : Bool;
tStringParts : Struct
sType : String;
sNumber : String;
sFunctionName : String;
END_STRUCT;
tString : String;
tSetDataLog : Bool;
tRunProgramAlarm : Bool;
tRenewString : Bool;
tDataLogBuffer : "DataLogBuffer";
tRisingAlarm : Bool; // Kommende Meldung
tFallingAlarm : Bool; // Gehende Meldung
END_VAR
BEGIN
(*
Der Baustein gibt über den Befehl "Program_Alarm" fehler am HMI aus. Achtung, nur jeweils ein Fehler pro Monitoring-Baustein gleichzeitig.
Aufbau Fehlermeldung:
Fehler 123: Heber 2, Step 230 - Heber nicht am Sensor erkannt BG6061
"sTypeAndNumber: " "sFunctionName" "sInPrefix" "sInErrorMessage" "xInSuffix"
nType&(nErrorNumber+Offset)
*)
(* Fragen:
Todo:
- Priority-Level
*)
REGION Alarmnummer abfragen
(* IF "DB_AlarmGlobal".xAlarmReOrg THEN
#nAlarmNoOffset := "FC_GetAlarmNo_1"(#stSettings.nNoMaxErrors);
// #xPlcReOrg := FALSE; // wird wegen "Funktionsname holen" nicht benötigt
ELSIF
#nAlarmNoOffset = 0 THEN
"DB_AlarmGlobal".xAlarmReOrgNextStep := TRUE;
END_IF;
*)
#nAlarmNoOffset := "FC_GetAlarmNo"(#stSettings.nNoMaxErrors);
END_REGION
REGION Kommende und gehende Meldung erfassen
#tRisingAlarm := #xInAlarm AND NOT #xAlarmFlag;
#tFallingAlarm := NOT #xInAlarm AND #xAlarmFlag;
END_REGION
REGION Alarm und Datalog aktivieren
IF #nAlarmNoOffset > 0 THEN
// Error
CASE #stSettings.nType OF
0..1: // (0)Intern Error and (1)Error
IF #tRisingAlarm OR #xRetryProgramAlarm THEN
#tRunProgramAlarm := TRUE;
#xSetProgramAlarm := TRUE;
#tRenewString := TRUE;
#tSetDataLog := TRUE;
#xRetryProgramAlarm := FALSE;
ELSIF #tFallingAlarm OR #xRetryProgramAlarm THEN
#tRunProgramAlarm := TRUE;
#xSetProgramAlarm := FALSE;
#tRenewString := FALSE;
#tSetDataLog := FALSE;
#xRetryProgramAlarm := FALSE;
END_IF;
// #tRunProgramAlarm := (#xInAlarm <> #xAlarmFlag);//OR #stMachineState.xQuitError; //!!!!
// #tSetDataLog := #xInAlarm AND NOT #xAlarmFlag;
// #tRenewString := #xInAlarm <> #xAlarmFlag;
// #xSetProgramAlarm := #xInAlarm;
2..4: // Warning, Information, Debug
IF #xInAlarm AND NOT #xAlarmFlag THEN
#tRunProgramAlarm := TRUE;
#xSetProgramAlarm := TRUE;
#tRenewString := TRUE;
#tSetDataLog := TRUE;
ELSIF NOT #xInAlarm AND #xAlarmFlag THEN
#tRunProgramAlarm := TRUE;
#xSetProgramAlarm := FALSE;
#tRenewString := FALSE;
#tSetDataLog := FALSE;
ELSIF #stInOutControlUnitCabinet.xQuitError THEN
#tRunProgramAlarm := TRUE;
#xSetProgramAlarm := FALSE;
#tRenewString := FALSE;
#tSetDataLog := FALSE;
END_IF;
END_CASE;
END_IF;
END_REGION
REGION Fehler zu String zusammenfügen
IF #tRenewString THEN
REGION Type And Number
CASE #stSettings.nType OF
0:
#tStringParts.sType := 'Int.Fehler';
1:
#tStringParts.sType := 'Fehler';
2:
#tStringParts.sType := 'Warnung';
3:
#tStringParts.sType := 'Info';
4:
#tStringParts.sType := 'Debug';
ELSE:
#tStringParts.sType := 'WrongNType';
END_CASE;
#tStringParts.sNumber := UINT_TO_STRING(#nAlarmNoOffset + #nInAlarmNumber);
#tStringParts.sNumber[1] := ' '; // Vorzeichen entfernen
END_REGION
REGION Function Name
#tStringParts.sFunctionName := CONCAT(IN1 := ' in ', IN2 := #stSettings.sFctnName);
END_REGION
REGION Zusammenfügen
#tString := CONCAT(IN1 := #tStringParts.sType ,IN2 := #tStringParts.sNumber, IN3 := #tStringParts.sFunctionName, IN4 := ' | ', IN5 := #sInPrefix);
IF #sInPrefix <> '' THEN
#tString := CONCAT(IN1 := #tString, IN2 := ' | ');
END_IF;
#tString := CONCAT(IN1 := #tString, IN2 := #sInAlarmMessage);
IF #sInAlarmMessage <> '' THEN
#tString := CONCAT(IN1 := #tString, IN2 := ' | ');
END_IF;
#sErrorString := CONCAT(IN1 := #tString, IN2 := #sInSuffix);
END_REGION
REGION Nummer überprüfen
IF #nInAlarmNumber > #stSettings.nNoMaxErrors - 1 OR
#nInAlarmNumber < 0 THEN
#sErrorString := CONCAT(IN1 := 'Falsche Fehlernummer in Baustein: ', IN2 := #stSettings.sFctnName);
END_IF;
END_REGION
END_IF;
END_REGION
REGION ProgramAlarm Setzen
IF #tRunProgramAlarm THEN
#fbProgram_Alarm(SIG := #xSetProgramAlarm,
Status => #wStatus,
Error => #xTemp,
SD_1 := #wInTextListId_Message,
SD_2 := #sInPrefix,
SD_3 := #sInSuffix,
SD_4 := #wInTextListId_Function,
SD_5 := #wInTextListId_Separator);
END_IF;
END_REGION
REGION Datalog schreiben
// Es ist nur 1 Datalog pro Zyklus möglich. Deshalb werden Fehler in einen Fehlerbuffer (FIFO) geschrieben und abgearbeitet.
// Datalogs werden nur geschrieben wenn die Priorität hoch genug ist.
IF #tSetDataLog AND #nInAlarmPriority <= 0 THEN
#tDataLogBuffer."Time" := "FC_TimeAsString"();
#tDataLogBuffer.AlarmNr := UINT_TO_INT(#nAlarmNoOffset + #nInAlarmNumber);
#tDataLogBuffer.AlarmType := #tStringParts.sType;
#tDataLogBuffer.Error := CONCAT(IN1 := #sInPrefix, IN2 := ' ', IN3 := #sInAlarmMessage, IN4 := ' ', IN5 := #sInSuffix);
#tDataLogBuffer.Function := #stSettings.sFctnName;
// #xTemp := "FC_WriteDatalogToDB"(#tDataLogBuffer);
END_IF;
END_REGION
REGION Ausgänge setzen
#xOutRdy := NOT #xInAlarm AND NOT #xAlarmFlag AND #nAlarmNoOffset > 0;
END_REGION
REGION Flanken
#xAlarmFlag := #xInAlarm;
END_REGION
REGION Fehler in ProgramAlarm Bearbeitung
IF #xTemp AND ((#wStatus = 16#80C1) OR (#wStatus = 16#80C2) OR (#wStatus = 16#80C3) OR (#wStatus = 16#80C4)) THEN
#xRetryProgramAlarm := TRUE;
END_IF;
END_REGION
END_FUNCTION_BLOCK
@@ -0,0 +1,10 @@
LibraryType:
Guid: 888dc75b-b6b6-4900-a239-6d2c867697ea
Comment:
de-DE: Programalarm generieren und loggen
LibraryVersion:
VersionNumber: 2.0.0
Author: e.yueksel
IsDefault: true
Comment:
de-DE: Freigegeben für IBN (EY, 22.04.2025)
@@ -0,0 +1,9 @@
DocumentHash:
- FileName: FC_GetAlarmNo.scl
Hash: H/tFUomshUYn5dYMInLRfleNMB+PwbpA+b3+giDVjFs=
LibraryMetaFileHash: gNUMIwX7GvGkdjnbfiTIVPr93Im0dRYbjZMh9oRsoZU=
LibraryVersion:
Guid: 46cc0419-40ed-460b-a195-d0a08c48c8de
DependsOn:
- TypeName: FC_MRoundINT
VersionNumber: 2.0.0
@@ -0,0 +1,14 @@
FUNCTION "FC_GetAlarmNo" : UInt
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
VAR_INPUT
nNoAlarm : UInt; // Anzahl verschiedner Fehler die Auftreten können
END_VAR
BEGIN
#FC_GetAlarmNo := "DB_AlarmGlobal".nAlarmNoOffsetGlobal;
"DB_AlarmGlobal".nAlarmNoOffsetGlobal := "FC_MRoundINT"(nValue := "DB_AlarmGlobal".nAlarmNoOffsetGlobal,
nMultiple := #nNoAlarm); // Auf nAlarmNoStep(5) Alarmmeldungen aufgerundet für Reserve
END_FUNCTION
@@ -0,0 +1,13 @@
LibraryType:
Guid: 60039f0c-6948-419b-9eb0-5d641af2177b
Comment:
de-DE: Runden
LibraryVersion:
VersionNumber: 2.0.0
Author: e.yueksel
IsDefault: true
Comment:
de-DE: |-
Hilfsfunktion
Freigegeben für IBN (EY, 22.04.2025)
@@ -0,0 +1,6 @@
DocumentHash:
- FileName: FC_MRoundINT.scl
Hash: 75aNBNxizotakl5O0+1wefqiE67S9myaXJgqUlayvcs=
LibraryMetaFileHash: UKwXqVbmQc4TBZx2p1kL1DVN4ybbDB7G23epDyckupU=
LibraryVersion:
Guid: 8c5f4bbf-9313-4dc8-ad58-26945063526b
@@ -0,0 +1,13 @@
FUNCTION "FC_MRoundINT" : UInt
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
VAR_INPUT
nValue : UInt; // Die Zahl, die gerundet werden soll.
nMultiple : UInt; // Dass Vielfache von "Schritt", auf das Sie die Zahl runden möchten.
END_VAR
BEGIN
#FC_MRoundINT := #nValue + #nMultiple - (#nValue MOD #nMultiple);
END_FUNCTION
@@ -0,0 +1,13 @@
LibraryType:
Guid: b4a3aa59-45cc-465c-8f40-a66ab7837469
Comment:
de-DE: Programalarm generieren und loggen
LibraryVersion:
VersionNumber: 2.0.0
Author: e.yueksel
IsDefault: true
Comment:
de-DE: |-
Programalarm generieren und loggen
Freigabe für IBN (EY, 22.04.2025)

Some files were not shown because too many files have changed in this diff Show More