diff --git a/1_BaseSystemLib/100_Common/FB_Blinker.libinfo b/1_BaseSystemLib/100_Common/FB_Blinker.libinfo new file mode 100644 index 0000000..244314d --- /dev/null +++ b/1_BaseSystemLib/100_Common/FB_Blinker.libinfo @@ -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) diff --git a/1_BaseSystemLib/100_Common/FB_Blinker.libint b/1_BaseSystemLib/100_Common/FB_Blinker.libint new file mode 100644 index 0000000..fb2679c --- /dev/null +++ b/1_BaseSystemLib/100_Common/FB_Blinker.libint @@ -0,0 +1,6 @@ +DocumentHash: + - FileName: FB_Blinker.scl + Hash: 7BD6hj5VYn+rKNDdupCZ7URQVKvXdDd/Ugg8DHpghIY= +LibraryMetaFileHash: E7qOimsmciFEInzFA+XMEIrhTgTKp9xNTj8qMkDXBz0= +LibraryVersion: + Guid: fa6b40b5-8048-40b8-9a10-460377c0a038 diff --git a/1_BaseSystemLib/100_Common/FB_Blinker.scl b/1_BaseSystemLib/100_Common/FB_Blinker.scl new file mode 100644 index 0000000..fb587ed --- /dev/null +++ b/1_BaseSystemLib/100_Common/FB_Blinker.scl @@ -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 + diff --git a/1_BaseSystemLib/100_Common/FB_CycleTime.libinfo b/1_BaseSystemLib/100_Common/FB_CycleTime.libinfo new file mode 100644 index 0000000..15a3bfb --- /dev/null +++ b/1_BaseSystemLib/100_Common/FB_CycleTime.libinfo @@ -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) diff --git a/1_BaseSystemLib/100_Common/FB_CycleTime.libint b/1_BaseSystemLib/100_Common/FB_CycleTime.libint new file mode 100644 index 0000000..afa4c28 --- /dev/null +++ b/1_BaseSystemLib/100_Common/FB_CycleTime.libint @@ -0,0 +1,6 @@ +DocumentHash: + - FileName: FB_CycleTime.scl + Hash: 2Z6NJMSKGY05RyA+gla5h62TX6LIB5u3QhWELu+SPK4= +LibraryMetaFileHash: SFLc5/VUD4IaggRRMBqedlgDMtDuKtPjaRskpHX46E8= +LibraryVersion: + Guid: 25d2e38e-f4fc-4204-8d07-336d2fe1fa8c diff --git a/1_BaseSystemLib/100_Common/FB_CycleTime.scl b/1_BaseSystemLib/100_Common/FB_CycleTime.scl new file mode 100644 index 0000000..ea39949 --- /dev/null +++ b/1_BaseSystemLib/100_Common/FB_CycleTime.scl @@ -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 + diff --git a/1_BaseSystemLib/100_Common/HelperFunctions/FC_DateAsString.libinfo b/1_BaseSystemLib/100_Common/HelperFunctions/FC_DateAsString.libinfo new file mode 100644 index 0000000..ae02c04 --- /dev/null +++ b/1_BaseSystemLib/100_Common/HelperFunctions/FC_DateAsString.libinfo @@ -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' diff --git a/1_BaseSystemLib/100_Common/HelperFunctions/FC_DateAsString.libint b/1_BaseSystemLib/100_Common/HelperFunctions/FC_DateAsString.libint new file mode 100644 index 0000000..fc00432 --- /dev/null +++ b/1_BaseSystemLib/100_Common/HelperFunctions/FC_DateAsString.libint @@ -0,0 +1,6 @@ +DocumentHash: + - FileName: FC_DateAsString.scl + Hash: sxW9MGlJNzQwHlUucUIrXWLqFFj9XVJTFDBvIpZg2Qs= +LibraryMetaFileHash: 6Yo0WP5KqjVpHhTLfUTFC+re32KTNH1ye9pj7xdoYqc= +LibraryVersion: + Guid: 34059056-04c6-4b56-b5a2-abd5a842540e diff --git a/1_BaseSystemLib/100_Common/HelperFunctions/FC_DateAsString.scl b/1_BaseSystemLib/100_Common/HelperFunctions/FC_DateAsString.scl new file mode 100644 index 0000000..40fd7d6 --- /dev/null +++ b/1_BaseSystemLib/100_Common/HelperFunctions/FC_DateAsString.scl @@ -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 + diff --git a/1_BaseSystemLib/100_Common/HelperFunctions/FC_RemoveStringPart.libinfo b/1_BaseSystemLib/100_Common/HelperFunctions/FC_RemoveStringPart.libinfo new file mode 100644 index 0000000..376d307 --- /dev/null +++ b/1_BaseSystemLib/100_Common/HelperFunctions/FC_RemoveStringPart.libinfo @@ -0,0 +1,6 @@ +LibraryType: + Guid: 75fdb852-33f8-4860-bfe0-74c853d48987 +LibraryVersion: + VersionNumber: 2.0.0 + Author: e.yueksel + IsDefault: true diff --git a/1_BaseSystemLib/100_Common/HelperFunctions/FC_RemoveStringPart.libint b/1_BaseSystemLib/100_Common/HelperFunctions/FC_RemoveStringPart.libint new file mode 100644 index 0000000..bd60041 --- /dev/null +++ b/1_BaseSystemLib/100_Common/HelperFunctions/FC_RemoveStringPart.libint @@ -0,0 +1,6 @@ +DocumentHash: + - FileName: FC_RemoveStringPart.scl + Hash: M/GpwHJPz23hLSM9fCEJmNAQWH5VNKnkCvRvibwFVuI= +LibraryMetaFileHash: YxePwWkwi+6JBpfN1P+bJ2t85wqoDQfUarH23N+mI1o= +LibraryVersion: + Guid: c0a01750-6a1f-47ba-b034-8732c973f038 diff --git a/1_BaseSystemLib/100_Common/HelperFunctions/FC_RemoveStringPart.scl b/1_BaseSystemLib/100_Common/HelperFunctions/FC_RemoveStringPart.scl new file mode 100644 index 0000000..5593d46 --- /dev/null +++ b/1_BaseSystemLib/100_Common/HelperFunctions/FC_RemoveStringPart.scl @@ -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 + diff --git a/1_BaseSystemLib/100_Common/HelperFunctions/FC_TimeAsString.libinfo b/1_BaseSystemLib/100_Common/HelperFunctions/FC_TimeAsString.libinfo new file mode 100644 index 0000000..4385fc3 --- /dev/null +++ b/1_BaseSystemLib/100_Common/HelperFunctions/FC_TimeAsString.libinfo @@ -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 diff --git a/1_BaseSystemLib/100_Common/HelperFunctions/FC_TimeAsString.libint b/1_BaseSystemLib/100_Common/HelperFunctions/FC_TimeAsString.libint new file mode 100644 index 0000000..bb69189 --- /dev/null +++ b/1_BaseSystemLib/100_Common/HelperFunctions/FC_TimeAsString.libint @@ -0,0 +1,6 @@ +DocumentHash: + - FileName: FC_TimeAsString.scl + Hash: 3WJUl9RFht2vorDlH8QAIOs7AhSUh8JVzkcdrRKQwZo= +LibraryMetaFileHash: rKdgHvTDa65A90nGw/BUqSQ1XoRp0ZITlOxvdtrZTnQ= +LibraryVersion: + Guid: 4a99e138-618d-44bb-915f-75873870e021 diff --git a/1_BaseSystemLib/100_Common/HelperFunctions/FC_TimeAsString.scl b/1_BaseSystemLib/100_Common/HelperFunctions/FC_TimeAsString.scl new file mode 100644 index 0000000..cb2a4e0 --- /dev/null +++ b/1_BaseSystemLib/100_Common/HelperFunctions/FC_TimeAsString.scl @@ -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 + diff --git a/1_BaseSystemLib/100_Common/LGF/FIFO/FC_FIFO_Append.libinfo b/1_BaseSystemLib/100_Common/LGF/FIFO/FC_FIFO_Append.libinfo new file mode 100644 index 0000000..66781ad --- /dev/null +++ b/1_BaseSystemLib/100_Common/LGF/FIFO/FC_FIFO_Append.libinfo @@ -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) diff --git a/1_BaseSystemLib/100_Common/LGF/FIFO/FC_FIFO_Append.libint b/1_BaseSystemLib/100_Common/LGF/FIFO/FC_FIFO_Append.libint new file mode 100644 index 0000000..331325e --- /dev/null +++ b/1_BaseSystemLib/100_Common/LGF/FIFO/FC_FIFO_Append.libint @@ -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 diff --git a/1_BaseSystemLib/100_Common/LGF/FIFO/FC_FIFO_Append.scl b/1_BaseSystemLib/100_Common/LGF/FIFO/FC_FIFO_Append.scl new file mode 100644 index 0000000..fd57449 --- /dev/null +++ b/1_BaseSystemLib/100_Common/LGF/FIFO/FC_FIFO_Append.scl @@ -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 + diff --git a/1_BaseSystemLib/100_Common/LGF/FIFO/FC_FIFO_GetFirst.libinfo b/1_BaseSystemLib/100_Common/LGF/FIFO/FC_FIFO_GetFirst.libinfo new file mode 100644 index 0000000..6196b61 --- /dev/null +++ b/1_BaseSystemLib/100_Common/LGF/FIFO/FC_FIFO_GetFirst.libinfo @@ -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) " diff --git a/1_BaseSystemLib/100_Common/LGF/FIFO/FC_FIFO_GetFirst.libint b/1_BaseSystemLib/100_Common/LGF/FIFO/FC_FIFO_GetFirst.libint new file mode 100644 index 0000000..4e6e73a --- /dev/null +++ b/1_BaseSystemLib/100_Common/LGF/FIFO/FC_FIFO_GetFirst.libint @@ -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 diff --git a/1_BaseSystemLib/100_Common/LGF/FIFO/FC_FIFO_GetFirst.scl b/1_BaseSystemLib/100_Common/LGF/FIFO/FC_FIFO_GetFirst.scl new file mode 100644 index 0000000..9373ce8 --- /dev/null +++ b/1_BaseSystemLib/100_Common/LGF/FIFO/FC_FIFO_GetFirst.scl @@ -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 + diff --git a/1_BaseSystemLib/100_Common/LGF/FIFO/FC_FIFO_GetFirst_Test.libinfo b/1_BaseSystemLib/100_Common/LGF/FIFO/FC_FIFO_GetFirst_Test.libinfo new file mode 100644 index 0000000..df783fc --- /dev/null +++ b/1_BaseSystemLib/100_Common/LGF/FIFO/FC_FIFO_GetFirst_Test.libinfo @@ -0,0 +1,6 @@ +LibraryType: + Guid: 0f749c18-e0f3-4bcc-957e-a77803394a52 +LibraryVersion: + VersionNumber: 0.0.2 + Author: e.yueksel + IsDefault: true diff --git a/1_BaseSystemLib/100_Common/LGF/FIFO/FC_FIFO_GetFirst_Test.libint b/1_BaseSystemLib/100_Common/LGF/FIFO/FC_FIFO_GetFirst_Test.libint new file mode 100644 index 0000000..798f454 --- /dev/null +++ b/1_BaseSystemLib/100_Common/LGF/FIFO/FC_FIFO_GetFirst_Test.libint @@ -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 diff --git a/1_BaseSystemLib/100_Common/LGF/FIFO/FC_FIFO_GetFirst_Test.scl b/1_BaseSystemLib/100_Common/LGF/FIFO/FC_FIFO_GetFirst_Test.scl new file mode 100644 index 0000000..b2c605f --- /dev/null +++ b/1_BaseSystemLib/100_Common/LGF/FIFO/FC_FIFO_GetFirst_Test.scl @@ -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 + diff --git a/1_BaseSystemLib/100_Common/LGF/FIFO/LGF_FIFO.libinfo b/1_BaseSystemLib/100_Common/LGF/FIFO/LGF_FIFO.libinfo new file mode 100644 index 0000000..3288df3 --- /dev/null +++ b/1_BaseSystemLib/100_Common/LGF/FIFO/LGF_FIFO.libinfo @@ -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) " diff --git a/1_BaseSystemLib/100_Common/LGF/FIFO/LGF_FIFO.libint b/1_BaseSystemLib/100_Common/LGF/FIFO/LGF_FIFO.libint new file mode 100644 index 0000000..abd21ae --- /dev/null +++ b/1_BaseSystemLib/100_Common/LGF/FIFO/LGF_FIFO.libint @@ -0,0 +1,6 @@ +DocumentHash: + - FileName: LGF_FIFO.scl + Hash: BIfbhj29jufO1l1arCSCphOQSLppKO8CJWeKftAqSGc= +LibraryMetaFileHash: YbN2PYZ8AkYvSAAoX7IlQQcHgXBeUPYkgUs0xiYeHLY= +LibraryVersion: + Guid: bae66bce-23a3-475d-93bf-65bd96466183 diff --git a/1_BaseSystemLib/100_Common/LGF/FIFO/LGF_FIFO.scl b/1_BaseSystemLib/100_Common/LGF/FIFO/LGF_FIFO.scl new file mode 100644 index 0000000..18bd9b7 --- /dev/null +++ b/1_BaseSystemLib/100_Common/LGF/FIFO/LGF_FIFO.scl @@ -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 + diff --git a/1_BaseSystemLib/100_Common/RunTimeMonitoring/FB_RTM.libinfo b/1_BaseSystemLib/100_Common/RunTimeMonitoring/FB_RTM.libinfo new file mode 100644 index 0000000..657bac5 --- /dev/null +++ b/1_BaseSystemLib/100_Common/RunTimeMonitoring/FB_RTM.libinfo @@ -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 diff --git a/1_BaseSystemLib/100_Common/RunTimeMonitoring/FB_RTM.libint b/1_BaseSystemLib/100_Common/RunTimeMonitoring/FB_RTM.libint new file mode 100644 index 0000000..1449038 --- /dev/null +++ b/1_BaseSystemLib/100_Common/RunTimeMonitoring/FB_RTM.libint @@ -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 diff --git a/1_BaseSystemLib/100_Common/RunTimeMonitoring/FB_RTM.scl b/1_BaseSystemLib/100_Common/RunTimeMonitoring/FB_RTM.scl new file mode 100644 index 0000000..6e1dbed --- /dev/null +++ b/1_BaseSystemLib/100_Common/RunTimeMonitoring/FB_RTM.scl @@ -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 + diff --git a/1_BaseSystemLib/100_Common/RunTimeMonitoring/UDT/UDT_RTM.libinfo b/1_BaseSystemLib/100_Common/RunTimeMonitoring/UDT/UDT_RTM.libinfo new file mode 100644 index 0000000..b900834 --- /dev/null +++ b/1_BaseSystemLib/100_Common/RunTimeMonitoring/UDT/UDT_RTM.libinfo @@ -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 diff --git a/1_BaseSystemLib/100_Common/RunTimeMonitoring/UDT/UDT_RTM.libint b/1_BaseSystemLib/100_Common/RunTimeMonitoring/UDT/UDT_RTM.libint new file mode 100644 index 0000000..1e419be --- /dev/null +++ b/1_BaseSystemLib/100_Common/RunTimeMonitoring/UDT/UDT_RTM.libint @@ -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 diff --git a/1_BaseSystemLib/100_Common/RunTimeMonitoring/UDT/UDT_RTM.xml b/1_BaseSystemLib/100_Common/RunTimeMonitoring/UDT/UDT_RTM.xml new file mode 100644 index 0000000..a04cf1b --- /dev/null +++ b/1_BaseSystemLib/100_Common/RunTimeMonitoring/UDT/UDT_RTM.xml @@ -0,0 +1,56 @@ + + + + + + +
+ + + true + + + + + true + + + + + true + + + + + true + + +
+
+ UDT_RTM + +
+ + + + + + de-DE + + + + + + + + + + de-DE + + + + + + +
+
\ No newline at end of file diff --git a/1_BaseSystemLib/100_Common/RunTimeMonitoring/UDT/UDT_RTM_Flags.libinfo b/1_BaseSystemLib/100_Common/RunTimeMonitoring/UDT/UDT_RTM_Flags.libinfo new file mode 100644 index 0000000..1f6be07 --- /dev/null +++ b/1_BaseSystemLib/100_Common/RunTimeMonitoring/UDT/UDT_RTM_Flags.libinfo @@ -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 diff --git a/1_BaseSystemLib/100_Common/RunTimeMonitoring/UDT/UDT_RTM_Flags.libint b/1_BaseSystemLib/100_Common/RunTimeMonitoring/UDT/UDT_RTM_Flags.libint new file mode 100644 index 0000000..599c241 --- /dev/null +++ b/1_BaseSystemLib/100_Common/RunTimeMonitoring/UDT/UDT_RTM_Flags.libint @@ -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 diff --git a/1_BaseSystemLib/100_Common/RunTimeMonitoring/UDT/UDT_RTM_Flags.xml b/1_BaseSystemLib/100_Common/RunTimeMonitoring/UDT/UDT_RTM_Flags.xml new file mode 100644 index 0000000..e5d7d8d --- /dev/null +++ b/1_BaseSystemLib/100_Common/RunTimeMonitoring/UDT/UDT_RTM_Flags.xml @@ -0,0 +1,41 @@ + + + + + + +
+ + + + + +
+
+ UDT_RTM_Flags + +
+ + + + + + de-DE + + + + + + + + + + de-DE + + + + + + +
+
\ No newline at end of file diff --git a/1_BaseSystemLib/100_Common/RunTimeMonitoring/UDT/UDT_RTM_Maintenance.libinfo b/1_BaseSystemLib/100_Common/RunTimeMonitoring/UDT/UDT_RTM_Maintenance.libinfo new file mode 100644 index 0000000..e867451 --- /dev/null +++ b/1_BaseSystemLib/100_Common/RunTimeMonitoring/UDT/UDT_RTM_Maintenance.libinfo @@ -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 diff --git a/1_BaseSystemLib/100_Common/RunTimeMonitoring/UDT/UDT_RTM_Maintenance.libint b/1_BaseSystemLib/100_Common/RunTimeMonitoring/UDT/UDT_RTM_Maintenance.libint new file mode 100644 index 0000000..622991e --- /dev/null +++ b/1_BaseSystemLib/100_Common/RunTimeMonitoring/UDT/UDT_RTM_Maintenance.libint @@ -0,0 +1,6 @@ +DocumentHash: + - FileName: UDT_RTM_Maintenance.xml + Hash: KXV53rFL0ONooLjl08qJ73DjMpOsI9S8luaWGgluJG4= +LibraryMetaFileHash: 0l0zZpMtg/sKV4XRWqLlL+bHKf6Gr4YBebFrG2+GZSQ= +LibraryVersion: + Guid: 3f388807-4b41-4a6d-8f8a-c60ab16ba84f diff --git a/1_BaseSystemLib/100_Common/RunTimeMonitoring/UDT/UDT_RTM_Maintenance.xml b/1_BaseSystemLib/100_Common/RunTimeMonitoring/UDT/UDT_RTM_Maintenance.xml new file mode 100644 index 0000000..d53afc0 --- /dev/null +++ b/1_BaseSystemLib/100_Common/RunTimeMonitoring/UDT/UDT_RTM_Maintenance.xml @@ -0,0 +1,41 @@ + + + + + + +
+ + + + + +
+
+ UDT_RTM_Maintenance + +
+ + + + + + de-DE + + + + + + + + + + de-DE + + + + + + +
+
\ No newline at end of file diff --git a/1_BaseSystemLib/100_Common/RunTimeMonitoring/UDT/UDT_RTM_Time.libinfo b/1_BaseSystemLib/100_Common/RunTimeMonitoring/UDT/UDT_RTM_Time.libinfo new file mode 100644 index 0000000..18869ae --- /dev/null +++ b/1_BaseSystemLib/100_Common/RunTimeMonitoring/UDT/UDT_RTM_Time.libinfo @@ -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 diff --git a/1_BaseSystemLib/100_Common/RunTimeMonitoring/UDT/UDT_RTM_Time.libint b/1_BaseSystemLib/100_Common/RunTimeMonitoring/UDT/UDT_RTM_Time.libint new file mode 100644 index 0000000..b9e946d --- /dev/null +++ b/1_BaseSystemLib/100_Common/RunTimeMonitoring/UDT/UDT_RTM_Time.libint @@ -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 diff --git a/1_BaseSystemLib/100_Common/RunTimeMonitoring/UDT/UDT_RTM_Time.xml b/1_BaseSystemLib/100_Common/RunTimeMonitoring/UDT/UDT_RTM_Time.xml new file mode 100644 index 0000000..798af7d --- /dev/null +++ b/1_BaseSystemLib/100_Common/RunTimeMonitoring/UDT/UDT_RTM_Time.xml @@ -0,0 +1,39 @@ + + + + + + +
+ + + +
+
+ UDT_RTM_Time + +
+ + + + + + de-DE + + + + + + + + + + de-DE + + + + + + +
+
\ No newline at end of file diff --git a/1_BaseSystemLib/100_Common/StateMain/FB_StateMain.libinfo b/1_BaseSystemLib/100_Common/StateMain/FB_StateMain.libinfo new file mode 100644 index 0000000..2c092e8 --- /dev/null +++ b/1_BaseSystemLib/100_Common/StateMain/FB_StateMain.libinfo @@ -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 diff --git a/1_BaseSystemLib/100_Common/StateMain/FB_StateMain.libint b/1_BaseSystemLib/100_Common/StateMain/FB_StateMain.libint new file mode 100644 index 0000000..ed27e5d --- /dev/null +++ b/1_BaseSystemLib/100_Common/StateMain/FB_StateMain.libint @@ -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 diff --git a/1_BaseSystemLib/100_Common/StateMain/FB_StateMain.scl b/1_BaseSystemLib/100_Common/StateMain/FB_StateMain.scl new file mode 100644 index 0000000..90b2a4a --- /dev/null +++ b/1_BaseSystemLib/100_Common/StateMain/FB_StateMain.scl @@ -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 + diff --git a/1_BaseSystemLib/100_Common/StateMain/HMI/UDT_HMI_StateMachine.libinfo b/1_BaseSystemLib/100_Common/StateMain/HMI/UDT_HMI_StateMachine.libinfo new file mode 100644 index 0000000..a3e8bac --- /dev/null +++ b/1_BaseSystemLib/100_Common/StateMain/HMI/UDT_HMI_StateMachine.libinfo @@ -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) diff --git a/1_BaseSystemLib/100_Common/StateMain/HMI/UDT_HMI_StateMachine.libint b/1_BaseSystemLib/100_Common/StateMain/HMI/UDT_HMI_StateMachine.libint new file mode 100644 index 0000000..7383e9c --- /dev/null +++ b/1_BaseSystemLib/100_Common/StateMain/HMI/UDT_HMI_StateMachine.libint @@ -0,0 +1,6 @@ +DocumentHash: + - FileName: UDT_HMI_StateMachine.xml + Hash: YqTb5Kyt7R2GxFrle2a0EDCZZaopcl49Qy34HgCTLgE= +LibraryMetaFileHash: DCa7PFui0vP0Ap3+CzccEnRwXeGVD/9IVuSPN1Z7DKQ= +LibraryVersion: + Guid: 56ad7890-8af6-435b-bc6e-eb1b1452b2de diff --git a/1_BaseSystemLib/100_Common/StateMain/HMI/UDT_HMI_StateMachine.xml b/1_BaseSystemLib/100_Common/StateMain/HMI/UDT_HMI_StateMachine.xml new file mode 100644 index 0000000..265f38e --- /dev/null +++ b/1_BaseSystemLib/100_Common/StateMain/HMI/UDT_HMI_StateMachine.xml @@ -0,0 +1,71 @@ + + + + + + +
+ + + State Status + + + + + Ein + + + + + Aus + + + + + Quittieren + + + + + Abort / Not-Aus + + + + + Restart + + + + + Rev Request + + +
+
+ UDT_HMI_StateMachine + +
+ + + + + + de-DE + + + + + + + + + + de-DE + + + + + + +
+
\ No newline at end of file diff --git a/1_BaseSystemLib/100_Common/StateMain/UDT/UDT_MainState.libinfo b/1_BaseSystemLib/100_Common/StateMain/UDT/UDT_MainState.libinfo new file mode 100644 index 0000000..c81587c --- /dev/null +++ b/1_BaseSystemLib/100_Common/StateMain/UDT/UDT_MainState.libinfo @@ -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) diff --git a/1_BaseSystemLib/100_Common/StateMain/UDT/UDT_MainState.libint b/1_BaseSystemLib/100_Common/StateMain/UDT/UDT_MainState.libint new file mode 100644 index 0000000..07b94a9 --- /dev/null +++ b/1_BaseSystemLib/100_Common/StateMain/UDT/UDT_MainState.libint @@ -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 diff --git a/1_BaseSystemLib/100_Common/StateMain/UDT/UDT_MainState.xml b/1_BaseSystemLib/100_Common/StateMain/UDT/UDT_MainState.xml new file mode 100644 index 0000000..618fd1e --- /dev/null +++ b/1_BaseSystemLib/100_Common/StateMain/UDT/UDT_MainState.xml @@ -0,0 +1,86 @@ + + + + + + +
+ + + Anlage Automatikbetrieb + + + + + Start nach Störung + + + + + Any Error active + + + + + Maschine startet + + + + + Neustart + + + + + LED Anlage Ein + + + + + Maschine wird durch dieses Bit angehalten + + + + + Anfahrwarnung + + + + + Anfrage, dass die Safety aktiviert wird + + + + + Safety ist aktiviert + + +
+
+ UDT_MainState + +
+ + + + + + de-DE + + + + + + + + + + de-DE + + + + + + +
+
\ No newline at end of file diff --git a/1_BaseSystemLib/100_Common/StateManager/FB_StateManager.libinfo b/1_BaseSystemLib/100_Common/StateManager/FB_StateManager.libinfo new file mode 100644 index 0000000..c50d399 --- /dev/null +++ b/1_BaseSystemLib/100_Common/StateManager/FB_StateManager.libinfo @@ -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) diff --git a/1_BaseSystemLib/100_Common/StateManager/FB_StateManager.libint b/1_BaseSystemLib/100_Common/StateManager/FB_StateManager.libint new file mode 100644 index 0000000..28dfb86 --- /dev/null +++ b/1_BaseSystemLib/100_Common/StateManager/FB_StateManager.libint @@ -0,0 +1,6 @@ +DocumentHash: + - FileName: FB_StateManager.scl + Hash: bcEUtDKqV8LMMdpaYVhVCfjBuKlBilNyJprtURyTJZc= +LibraryMetaFileHash: 2PYH+EJhUOAQSvx/5tKDPTmfq3RYznpIYVnZ2XbSK1M= +LibraryVersion: + Guid: cb3fd588-4989-4a4a-a2a6-5529192cbc90 diff --git a/1_BaseSystemLib/100_Common/StateManager/FB_StateManager.scl b/1_BaseSystemLib/100_Common/StateManager/FB_StateManager.scl new file mode 100644 index 0000000..dd8b93e --- /dev/null +++ b/1_BaseSystemLib/100_Common/StateManager/FB_StateManager.scl @@ -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 + diff --git a/1_BaseSystemLib/110_PROFINET/Barcode-Reader/FB_BarcodeReaderCognex.libinfo b/1_BaseSystemLib/110_PROFINET/Barcode-Reader/FB_BarcodeReaderCognex.libinfo new file mode 100644 index 0000000..cbf2dd4 --- /dev/null +++ b/1_BaseSystemLib/110_PROFINET/Barcode-Reader/FB_BarcodeReaderCognex.libinfo @@ -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 diff --git a/1_BaseSystemLib/110_PROFINET/Barcode-Reader/FB_BarcodeReaderCognex.libint b/1_BaseSystemLib/110_PROFINET/Barcode-Reader/FB_BarcodeReaderCognex.libint new file mode 100644 index 0000000..683c8d1 --- /dev/null +++ b/1_BaseSystemLib/110_PROFINET/Barcode-Reader/FB_BarcodeReaderCognex.libint @@ -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 diff --git a/1_BaseSystemLib/110_PROFINET/Barcode-Reader/FB_BarcodeReaderCognex.scl b/1_BaseSystemLib/110_PROFINET/Barcode-Reader/FB_BarcodeReaderCognex.scl new file mode 100644 index 0000000..c245d23 --- /dev/null +++ b/1_BaseSystemLib/110_PROFINET/Barcode-Reader/FB_BarcodeReaderCognex.scl @@ -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 + diff --git a/1_BaseSystemLib/110_PROFINET/Barcode-Reader/UDT_BarcodeReader.libinfo b/1_BaseSystemLib/110_PROFINET/Barcode-Reader/UDT_BarcodeReader.libinfo new file mode 100644 index 0000000..13d39d6 --- /dev/null +++ b/1_BaseSystemLib/110_PROFINET/Barcode-Reader/UDT_BarcodeReader.libinfo @@ -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 diff --git a/1_BaseSystemLib/110_PROFINET/Barcode-Reader/UDT_BarcodeReader.libint b/1_BaseSystemLib/110_PROFINET/Barcode-Reader/UDT_BarcodeReader.libint new file mode 100644 index 0000000..97d8b79 --- /dev/null +++ b/1_BaseSystemLib/110_PROFINET/Barcode-Reader/UDT_BarcodeReader.libint @@ -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 diff --git a/1_BaseSystemLib/110_PROFINET/Barcode-Reader/UDT_BarcodeReader.xml b/1_BaseSystemLib/110_PROFINET/Barcode-Reader/UDT_BarcodeReader.xml new file mode 100644 index 0000000..94f0c57 --- /dev/null +++ b/1_BaseSystemLib/110_PROFINET/Barcode-Reader/UDT_BarcodeReader.xml @@ -0,0 +1,135 @@ + + + + + + +
+ + + Standardized status + + + + + Kamera Triggermodus (Single, Continuous...) + + + + + Interne Nummerierung + + + + + Kamera Bezeichnung (z.B. DM262-9FC5D4) + + + + + Standort + + + + + IP-Adresse + + + + + Schwellwert um die Lesequalität zu bewerten (z.B. 99 [%]) + + + + + Schnittstelle Kamera Baustein + + + + + Anzahl Scans + + + + + Anzahl No-Read + + + + + No-Read in Prozent + + + + + Letzter Barcode empfangen + + + + + Letzter No-Read empfangen + + + + + Letzter Reset + + + + + Alle Statistiken rücksetzen + + +
+
+ UDT_BarcodeReader + +
+ + + + + + de-DE + + + + + + en-US + + + + + + cs-CZ + + + + + + + + + + de-DE + + + + + + en-US + + + + + + cs-CZ + + + + + + +
+
\ No newline at end of file diff --git a/1_BaseSystemLib/110_PROFINET/Barcode-Reader/UDT_SettingsBarcodeReader.libinfo b/1_BaseSystemLib/110_PROFINET/Barcode-Reader/UDT_SettingsBarcodeReader.libinfo new file mode 100644 index 0000000..6c52b9e --- /dev/null +++ b/1_BaseSystemLib/110_PROFINET/Barcode-Reader/UDT_SettingsBarcodeReader.libinfo @@ -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) diff --git a/1_BaseSystemLib/110_PROFINET/Barcode-Reader/UDT_SettingsBarcodeReader.libint b/1_BaseSystemLib/110_PROFINET/Barcode-Reader/UDT_SettingsBarcodeReader.libint new file mode 100644 index 0000000..c99440b --- /dev/null +++ b/1_BaseSystemLib/110_PROFINET/Barcode-Reader/UDT_SettingsBarcodeReader.libint @@ -0,0 +1,6 @@ +DocumentHash: + - FileName: UDT_SettingsBarcodeReader.xml + Hash: WIqXsAFeE/opnVa20/ZCVUkon6tOnniE9KMUlnjvY2Y= +LibraryMetaFileHash: OTpcVojAkzlEEy/DPvJe96WcLeEDZJvnkXLUgt3MvdA= +LibraryVersion: + Guid: 6be7977f-bd26-4a22-a946-663b8c2af2c1 diff --git a/1_BaseSystemLib/110_PROFINET/Barcode-Reader/UDT_SettingsBarcodeReader.xml b/1_BaseSystemLib/110_PROFINET/Barcode-Reader/UDT_SettingsBarcodeReader.xml new file mode 100644 index 0000000..0fc242c --- /dev/null +++ b/1_BaseSystemLib/110_PROFINET/Barcode-Reader/UDT_SettingsBarcodeReader.xml @@ -0,0 +1,58 @@ + + + + + + +
+ + + Nummer + + + + + Leser Aufgabe (Trolley Barcode, Teil Barcode...) + + + + + ASCI Prüfung aktiveren + + true + + + + Timeout Lesung + + T#5s + +
+
+ UDT_SettingsBarcodeReader + +
+ + + + + + de-DE + + + + + + + + + + de-DE + + + + + + +
+
\ No newline at end of file diff --git a/1_BaseSystemLib/110_PROFINET/Barcode-Reader/stCognexInterface.libinfo b/1_BaseSystemLib/110_PROFINET/Barcode-Reader/stCognexInterface.libinfo new file mode 100644 index 0000000..a7b7a04 --- /dev/null +++ b/1_BaseSystemLib/110_PROFINET/Barcode-Reader/stCognexInterface.libinfo @@ -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) diff --git a/1_BaseSystemLib/110_PROFINET/Barcode-Reader/stCognexInterface.libint b/1_BaseSystemLib/110_PROFINET/Barcode-Reader/stCognexInterface.libint new file mode 100644 index 0000000..4c6b277 --- /dev/null +++ b/1_BaseSystemLib/110_PROFINET/Barcode-Reader/stCognexInterface.libint @@ -0,0 +1,6 @@ +DocumentHash: + - FileName: stCognexInterface.xml + Hash: J+LAf7w1glPlo9Ow1PIqSnnM5HGz4UPc30sj3AR/oKU= +LibraryMetaFileHash: XheQv51sz6RtFuNhNKVf2R1rrw7mGvCKbif6zVxhlPM= +LibraryVersion: + Guid: fd4fcb5f-2541-42a7-b6e0-a0e94d47950e diff --git a/1_BaseSystemLib/110_PROFINET/Barcode-Reader/stCognexInterface.xml b/1_BaseSystemLib/110_PROFINET/Barcode-Reader/stCognexInterface.xml new file mode 100644 index 0000000..acfeb73 --- /dev/null +++ b/1_BaseSystemLib/110_PROFINET/Barcode-Reader/stCognexInterface.xml @@ -0,0 +1,87 @@ + + + + + + +
+ + + Cognex Acquisition Status Module + + + + + Cognex Acquisition Status Module + + + + + Cognex Results Status Module + + + + + Cognex Results Status Module + + + + + Cognex Result Data Module + + + + + Cognex Result Data Module + + + + + Cognex Result Data Module + + + + + + Cognex Acquisition Control Module + + + + + Cogenx Acquisition Control Module + + + + + Cognex Results Control Module + + +
+
+ stCognexInterface + +
+ + + + + + de-DE + + + + + + + + + + de-DE + + + + + + +
+
\ No newline at end of file diff --git a/1_BaseSystemLib/110_PROFINET/Barcode-Reader/stHMI_BRCognexDM.libinfo b/1_BaseSystemLib/110_PROFINET/Barcode-Reader/stHMI_BRCognexDM.libinfo new file mode 100644 index 0000000..5f220f9 --- /dev/null +++ b/1_BaseSystemLib/110_PROFINET/Barcode-Reader/stHMI_BRCognexDM.libinfo @@ -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) diff --git a/1_BaseSystemLib/110_PROFINET/Barcode-Reader/stHMI_BRCognexDM.libint b/1_BaseSystemLib/110_PROFINET/Barcode-Reader/stHMI_BRCognexDM.libint new file mode 100644 index 0000000..b927a60 --- /dev/null +++ b/1_BaseSystemLib/110_PROFINET/Barcode-Reader/stHMI_BRCognexDM.libint @@ -0,0 +1,6 @@ +DocumentHash: + - FileName: stHMI_BRCognexDM.xml + Hash: r2yXtsMPR1tYYayK89wCaBfoYnfvbcC8U08Pmqz3ghQ= +LibraryMetaFileHash: 2QmCAfK/VMBYGEhHb3XXb2Mlozb9v/F06igsbe8CqUI= +LibraryVersion: + Guid: 4292f22b-ef2b-4a96-8038-d15fd7be6b5a diff --git a/1_BaseSystemLib/110_PROFINET/Barcode-Reader/stHMI_BRCognexDM.xml b/1_BaseSystemLib/110_PROFINET/Barcode-Reader/stHMI_BRCognexDM.xml new file mode 100644 index 0000000..e314c30 --- /dev/null +++ b/1_BaseSystemLib/110_PROFINET/Barcode-Reader/stHMI_BRCognexDM.xml @@ -0,0 +1,42 @@ + + + + + + +
+ + + + + + +
+
+ stHMI_BRCognexDM + +
+ + + + + + de-DE + + + + + + + + + + de-DE + + + + + + +
+
\ No newline at end of file diff --git a/1_BaseSystemLib/110_PROFINET/Encoder/ILS/FB_EncoderTR.libinfo b/1_BaseSystemLib/110_PROFINET/Encoder/ILS/FB_EncoderTR.libinfo new file mode 100644 index 0000000..e69a4ad --- /dev/null +++ b/1_BaseSystemLib/110_PROFINET/Encoder/ILS/FB_EncoderTR.libinfo @@ -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) diff --git a/1_BaseSystemLib/110_PROFINET/Encoder/ILS/FB_EncoderTR.libint b/1_BaseSystemLib/110_PROFINET/Encoder/ILS/FB_EncoderTR.libint new file mode 100644 index 0000000..5e7ce03 --- /dev/null +++ b/1_BaseSystemLib/110_PROFINET/Encoder/ILS/FB_EncoderTR.libint @@ -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 diff --git a/1_BaseSystemLib/110_PROFINET/Encoder/ILS/FB_EncoderTR.scl b/1_BaseSystemLib/110_PROFINET/Encoder/ILS/FB_EncoderTR.scl new file mode 100644 index 0000000..4b63365 --- /dev/null +++ b/1_BaseSystemLib/110_PROFINET/Encoder/ILS/FB_EncoderTR.scl @@ -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 + diff --git a/1_BaseSystemLib/110_PROFINET/Sensors/FB_SensorInput.libinfo b/1_BaseSystemLib/110_PROFINET/Sensors/FB_SensorInput.libinfo new file mode 100644 index 0000000..95cc004 --- /dev/null +++ b/1_BaseSystemLib/110_PROFINET/Sensors/FB_SensorInput.libinfo @@ -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 diff --git a/1_BaseSystemLib/110_PROFINET/Sensors/FB_SensorInput.libint b/1_BaseSystemLib/110_PROFINET/Sensors/FB_SensorInput.libint new file mode 100644 index 0000000..4c715e6 --- /dev/null +++ b/1_BaseSystemLib/110_PROFINET/Sensors/FB_SensorInput.libint @@ -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 diff --git a/1_BaseSystemLib/110_PROFINET/Sensors/FB_SensorInput.scl b/1_BaseSystemLib/110_PROFINET/Sensors/FB_SensorInput.scl new file mode 100644 index 0000000..06f6f97 --- /dev/null +++ b/1_BaseSystemLib/110_PROFINET/Sensors/FB_SensorInput.scl @@ -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 + diff --git a/1_BaseSystemLib/110_PROFINET/Sensors/UDT/UDT_HMI_Sensor.libinfo b/1_BaseSystemLib/110_PROFINET/Sensors/UDT/UDT_HMI_Sensor.libinfo new file mode 100644 index 0000000..6d08f59 --- /dev/null +++ b/1_BaseSystemLib/110_PROFINET/Sensors/UDT/UDT_HMI_Sensor.libinfo @@ -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) diff --git a/1_BaseSystemLib/110_PROFINET/Sensors/UDT/UDT_HMI_Sensor.libint b/1_BaseSystemLib/110_PROFINET/Sensors/UDT/UDT_HMI_Sensor.libint new file mode 100644 index 0000000..af246c9 --- /dev/null +++ b/1_BaseSystemLib/110_PROFINET/Sensors/UDT/UDT_HMI_Sensor.libint @@ -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 diff --git a/1_BaseSystemLib/110_PROFINET/Sensors/UDT/UDT_HMI_Sensor.xml b/1_BaseSystemLib/110_PROFINET/Sensors/UDT/UDT_HMI_Sensor.xml new file mode 100644 index 0000000..555a879 --- /dev/null +++ b/1_BaseSystemLib/110_PROFINET/Sensors/UDT/UDT_HMI_Sensor.xml @@ -0,0 +1,51 @@ + + + + + + +
+ + + true + + + + + true + + + + + true + + +
+
+ UDT_HMI_Sensor + +
+ + + + + + de-DE + + + + + + + + + + de-DE + + + + + + +
+
\ No newline at end of file diff --git a/1_BaseSystemLib/110_PROFINET/Sensors/UDT/UDT_HMI_Sensor_Config.libinfo b/1_BaseSystemLib/110_PROFINET/Sensors/UDT/UDT_HMI_Sensor_Config.libinfo new file mode 100644 index 0000000..bb559d9 --- /dev/null +++ b/1_BaseSystemLib/110_PROFINET/Sensors/UDT/UDT_HMI_Sensor_Config.libinfo @@ -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) diff --git a/1_BaseSystemLib/110_PROFINET/Sensors/UDT/UDT_HMI_Sensor_Config.libint b/1_BaseSystemLib/110_PROFINET/Sensors/UDT/UDT_HMI_Sensor_Config.libint new file mode 100644 index 0000000..ea8f88a --- /dev/null +++ b/1_BaseSystemLib/110_PROFINET/Sensors/UDT/UDT_HMI_Sensor_Config.libint @@ -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 diff --git a/1_BaseSystemLib/110_PROFINET/Sensors/UDT/UDT_HMI_Sensor_Config.xml b/1_BaseSystemLib/110_PROFINET/Sensors/UDT/UDT_HMI_Sensor_Config.xml new file mode 100644 index 0000000..197dd02 --- /dev/null +++ b/1_BaseSystemLib/110_PROFINET/Sensors/UDT/UDT_HMI_Sensor_Config.xml @@ -0,0 +1,66 @@ + + + + + + +
+ + + Entprellzeit für Debounced + + + + + Zeit die als "Flackern" eingestuft wird + + + + + Zeit bis Stau steigende Flanke + + + + + Zeit bis Stau fallende Flanke + + + + + Sensor seit Zeit x frei (Zeit 1, kurz) + + + + + Sensor seit Ueit x frei (Zeit 2, lang) + + +
+
+ UDT_HMI_Sensor_Config + +
+ + + + + + de-DE + + + + + + + + + + de-DE + + + + + + +
+
\ No newline at end of file diff --git a/1_BaseSystemLib/110_PROFINET/Sensors/UDT/UDT_HMI_Sensor_Control.libinfo b/1_BaseSystemLib/110_PROFINET/Sensors/UDT/UDT_HMI_Sensor_Control.libinfo new file mode 100644 index 0000000..327f2e4 --- /dev/null +++ b/1_BaseSystemLib/110_PROFINET/Sensors/UDT/UDT_HMI_Sensor_Control.libinfo @@ -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) diff --git a/1_BaseSystemLib/110_PROFINET/Sensors/UDT/UDT_HMI_Sensor_Control.libint b/1_BaseSystemLib/110_PROFINET/Sensors/UDT/UDT_HMI_Sensor_Control.libint new file mode 100644 index 0000000..cc85d8e --- /dev/null +++ b/1_BaseSystemLib/110_PROFINET/Sensors/UDT/UDT_HMI_Sensor_Control.libint @@ -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 diff --git a/1_BaseSystemLib/110_PROFINET/Sensors/UDT/UDT_HMI_Sensor_Control.xml b/1_BaseSystemLib/110_PROFINET/Sensors/UDT/UDT_HMI_Sensor_Control.xml new file mode 100644 index 0000000..cf9fd5c --- /dev/null +++ b/1_BaseSystemLib/110_PROFINET/Sensors/UDT/UDT_HMI_Sensor_Control.xml @@ -0,0 +1,46 @@ + + + + + + +
+ + + Sensor per HMI steuern aktivieren + + + + + Sensor HMI + + +
+
+ UDT_HMI_Sensor_Control + +
+ + + + + + de-DE + + + + + + + + + + de-DE + + + + + + +
+
\ No newline at end of file diff --git a/1_BaseSystemLib/110_PROFINET/Sensors/UDT/UDT_Sensor.libinfo b/1_BaseSystemLib/110_PROFINET/Sensors/UDT/UDT_Sensor.libinfo new file mode 100644 index 0000000..16b24da --- /dev/null +++ b/1_BaseSystemLib/110_PROFINET/Sensors/UDT/UDT_Sensor.libinfo @@ -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) diff --git a/1_BaseSystemLib/110_PROFINET/Sensors/UDT/UDT_Sensor.libint b/1_BaseSystemLib/110_PROFINET/Sensors/UDT/UDT_Sensor.libint new file mode 100644 index 0000000..15e1894 --- /dev/null +++ b/1_BaseSystemLib/110_PROFINET/Sensors/UDT/UDT_Sensor.libint @@ -0,0 +1,6 @@ +DocumentHash: + - FileName: UDT_Sensor.xml + Hash: gZqmsqXcGDYJlbUue+QglmkruFD+MU4TdxwktDL+wSM= +LibraryMetaFileHash: fmiqCPUQjv/AmVJlc2IJ0GwWtyG6giYM7RrNeIVaX2Y= +LibraryVersion: + Guid: d053d64c-e366-43e2-bd21-474f5cd34c8f diff --git a/1_BaseSystemLib/110_PROFINET/Sensors/UDT/UDT_Sensor.xml b/1_BaseSystemLib/110_PROFINET/Sensors/UDT/UDT_Sensor.xml new file mode 100644 index 0000000..5ebd51a --- /dev/null +++ b/1_BaseSystemLib/110_PROFINET/Sensors/UDT/UDT_Sensor.xml @@ -0,0 +1,81 @@ + + + + + + +
+ + + Sensor BMK + + + + + Direktes Signal ohne Verarbeitung + + + + + Positive Flanke + + + + + Negative Flanke + + + + + Zeit seit letzter Änderung Signalwechsel + + + + + Entprelltes Signal + + + + + Entprellte positive Flanke + + + + + Entprellte negative Flanke + + + + + Stau Indikator + + +
+
+ UDT_Sensor + +
+ + + + + + de-DE + + + + + + + + + + de-DE + + + + + + +
+
\ No newline at end of file diff --git a/1_BaseSystemLib/160_Monitoring/FB_Monitoring.libinfo b/1_BaseSystemLib/160_Monitoring/FB_Monitoring.libinfo new file mode 100644 index 0000000..33622f0 --- /dev/null +++ b/1_BaseSystemLib/160_Monitoring/FB_Monitoring.libinfo @@ -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 diff --git a/1_BaseSystemLib/160_Monitoring/FB_Monitoring.libint b/1_BaseSystemLib/160_Monitoring/FB_Monitoring.libint new file mode 100644 index 0000000..9eadc97 --- /dev/null +++ b/1_BaseSystemLib/160_Monitoring/FB_Monitoring.libint @@ -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 diff --git a/1_BaseSystemLib/160_Monitoring/FB_Monitoring.scl b/1_BaseSystemLib/160_Monitoring/FB_Monitoring.scl new file mode 100644 index 0000000..b60e2ad --- /dev/null +++ b/1_BaseSystemLib/160_Monitoring/FB_Monitoring.scl @@ -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 + diff --git a/1_BaseSystemLib/160_Monitoring/FB_SetAlarmAndLog.libinfo b/1_BaseSystemLib/160_Monitoring/FB_SetAlarmAndLog.libinfo new file mode 100644 index 0000000..3ca2249 --- /dev/null +++ b/1_BaseSystemLib/160_Monitoring/FB_SetAlarmAndLog.libinfo @@ -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 diff --git a/1_BaseSystemLib/160_Monitoring/FB_SetAlarmAndLog.libint b/1_BaseSystemLib/160_Monitoring/FB_SetAlarmAndLog.libint new file mode 100644 index 0000000..ecdfd9b --- /dev/null +++ b/1_BaseSystemLib/160_Monitoring/FB_SetAlarmAndLog.libint @@ -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 diff --git a/1_BaseSystemLib/160_Monitoring/FB_SetAlarmAndLog.scl b/1_BaseSystemLib/160_Monitoring/FB_SetAlarmAndLog.scl new file mode 100644 index 0000000..1736e65 --- /dev/null +++ b/1_BaseSystemLib/160_Monitoring/FB_SetAlarmAndLog.scl @@ -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 + diff --git a/1_BaseSystemLib/160_Monitoring/FC_GetAlarmNo.libinfo b/1_BaseSystemLib/160_Monitoring/FC_GetAlarmNo.libinfo new file mode 100644 index 0000000..7ff3395 --- /dev/null +++ b/1_BaseSystemLib/160_Monitoring/FC_GetAlarmNo.libinfo @@ -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) diff --git a/1_BaseSystemLib/160_Monitoring/FC_GetAlarmNo.libint b/1_BaseSystemLib/160_Monitoring/FC_GetAlarmNo.libint new file mode 100644 index 0000000..55192c4 --- /dev/null +++ b/1_BaseSystemLib/160_Monitoring/FC_GetAlarmNo.libint @@ -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 diff --git a/1_BaseSystemLib/160_Monitoring/FC_GetAlarmNo.scl b/1_BaseSystemLib/160_Monitoring/FC_GetAlarmNo.scl new file mode 100644 index 0000000..d8d2037 --- /dev/null +++ b/1_BaseSystemLib/160_Monitoring/FC_GetAlarmNo.scl @@ -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 + diff --git a/1_BaseSystemLib/160_Monitoring/FC_MRoundINT.libinfo b/1_BaseSystemLib/160_Monitoring/FC_MRoundINT.libinfo new file mode 100644 index 0000000..53dec9d --- /dev/null +++ b/1_BaseSystemLib/160_Monitoring/FC_MRoundINT.libinfo @@ -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) diff --git a/1_BaseSystemLib/160_Monitoring/FC_MRoundINT.libint b/1_BaseSystemLib/160_Monitoring/FC_MRoundINT.libint new file mode 100644 index 0000000..b58ffdd --- /dev/null +++ b/1_BaseSystemLib/160_Monitoring/FC_MRoundINT.libint @@ -0,0 +1,6 @@ +DocumentHash: + - FileName: FC_MRoundINT.scl + Hash: 75aNBNxizotakl5O0+1wefqiE67S9myaXJgqUlayvcs= +LibraryMetaFileHash: UKwXqVbmQc4TBZx2p1kL1DVN4ybbDB7G23epDyckupU= +LibraryVersion: + Guid: 8c5f4bbf-9313-4dc8-ad58-26945063526b diff --git a/1_BaseSystemLib/160_Monitoring/FC_MRoundINT.scl b/1_BaseSystemLib/160_Monitoring/FC_MRoundINT.scl new file mode 100644 index 0000000..f5b4a68 --- /dev/null +++ b/1_BaseSystemLib/160_Monitoring/FC_MRoundINT.scl @@ -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 + diff --git a/1_BaseSystemLib/160_Monitoring/FC_WriteDatalogToDB.libinfo b/1_BaseSystemLib/160_Monitoring/FC_WriteDatalogToDB.libinfo new file mode 100644 index 0000000..5fe765c --- /dev/null +++ b/1_BaseSystemLib/160_Monitoring/FC_WriteDatalogToDB.libinfo @@ -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) diff --git a/1_BaseSystemLib/160_Monitoring/FC_WriteDatalogToDB.libint b/1_BaseSystemLib/160_Monitoring/FC_WriteDatalogToDB.libint new file mode 100644 index 0000000..0dcc6fa --- /dev/null +++ b/1_BaseSystemLib/160_Monitoring/FC_WriteDatalogToDB.libint @@ -0,0 +1,9 @@ +DocumentHash: + - FileName: FC_WriteDatalogToDB.scl + Hash: qP3IJanqyDL0OH/8ei64PZI1Eohk4g2swFzqp4i98+4= +LibraryMetaFileHash: PkfPoMnvzgk+wT7+MhvRvuBMbgq02wAWmlKk4lEV81I= +LibraryVersion: + Guid: f1863774-f1fb-420a-923e-2a5bfaf420cd + DependsOn: + - TypeName: DataLogBuffer + VersionNumber: 2.0.0 diff --git a/1_BaseSystemLib/160_Monitoring/FC_WriteDatalogToDB.scl b/1_BaseSystemLib/160_Monitoring/FC_WriteDatalogToDB.scl new file mode 100644 index 0000000..10a02a1 --- /dev/null +++ b/1_BaseSystemLib/160_Monitoring/FC_WriteDatalogToDB.scl @@ -0,0 +1,24 @@ +FUNCTION "FC_WriteDatalogToDB" : Bool +{ S7_Optimized_Access := 'TRUE' } +VERSION : 0.1 + VAR_INPUT + sErrorData : "DataLogBuffer"; + END_VAR + + +BEGIN + // unten reinschieben -> Fifo + + IF "dbDataLogBuffer".nIdx < "cNoTempDataLog" THEN + "dbDataLogBuffer".nIdx += 1; + "dbDataLogBuffer".DataLogBuffer["dbDataLogBuffer".nIdx] := #sErrorData; + IF "dbDataLogBuffer".nIdxMax < "dbDataLogBuffer".nIdx THEN + "dbDataLogBuffer".nIdxMax := "dbDataLogBuffer".nIdx; + END_IF; + #FC_WriteDatalogToDB := TRUE; + ELSE + #FC_WriteDatalogToDB := FALSE; + END_IF; + +END_FUNCTION + diff --git a/1_BaseSystemLib/160_Monitoring/UDT/DataLogBuffer.libinfo b/1_BaseSystemLib/160_Monitoring/UDT/DataLogBuffer.libinfo new file mode 100644 index 0000000..4a10cc1 --- /dev/null +++ b/1_BaseSystemLib/160_Monitoring/UDT/DataLogBuffer.libinfo @@ -0,0 +1,13 @@ +LibraryType: + Guid: df9e1d69-e6ce-4ac1-9ae0-7fbf009a214e + Comment: + de-DE: Inkonsistenz bereinigen +LibraryVersion: + VersionNumber: 2.0.0 + Author: e.yueksel + IsDefault: true + Comment: + de-DE: |- + Inkonsistenz bereinigen + + Freigabe für IBN (EY, 22.04.2025) diff --git a/1_BaseSystemLib/160_Monitoring/UDT/DataLogBuffer.libint b/1_BaseSystemLib/160_Monitoring/UDT/DataLogBuffer.libint new file mode 100644 index 0000000..5370750 --- /dev/null +++ b/1_BaseSystemLib/160_Monitoring/UDT/DataLogBuffer.libint @@ -0,0 +1,6 @@ +DocumentHash: + - FileName: DataLogBuffer.xml + Hash: 6N+W+a9WyZnAz7B0/BWTS6K2TTM5ZNuw6Xw6/7WY56Q= +LibraryMetaFileHash: xR0A4p6EhJv48uLAyPtadKsHbH00a/mHjrYYPHej+dI= +LibraryVersion: + Guid: 662af92b-5a15-46a6-b86f-f079e0b6c023 diff --git a/1_BaseSystemLib/160_Monitoring/UDT/DataLogBuffer.xml b/1_BaseSystemLib/160_Monitoring/UDT/DataLogBuffer.xml new file mode 100644 index 0000000..50f0cc5 --- /dev/null +++ b/1_BaseSystemLib/160_Monitoring/UDT/DataLogBuffer.xml @@ -0,0 +1,45 @@ + + + + + + +
+ + + bsp.:23:59:59:123 + + + + + + +
+
+ DataLogBuffer + +
+ + + + + + de-DE + + + + + + + + + + de-DE + + + + + + +
+
\ No newline at end of file diff --git a/1_BaseSystemLib/160_Monitoring/UDT_HMI_Monitoring.libinfo b/1_BaseSystemLib/160_Monitoring/UDT_HMI_Monitoring.libinfo new file mode 100644 index 0000000..54236e7 --- /dev/null +++ b/1_BaseSystemLib/160_Monitoring/UDT_HMI_Monitoring.libinfo @@ -0,0 +1,10 @@ +LibraryType: + Guid: 1318a870-c8b2-4276-897a-cd2ea2f4218c + Comment: + de-DE: Monitoring HMI Interface +LibraryVersion: + VersionNumber: 2.0.0 + Author: e.yueksel + IsDefault: true + Comment: + de-DE: Monitoring HMI Interface diff --git a/1_BaseSystemLib/160_Monitoring/UDT_HMI_Monitoring.libint b/1_BaseSystemLib/160_Monitoring/UDT_HMI_Monitoring.libint new file mode 100644 index 0000000..1d68575 --- /dev/null +++ b/1_BaseSystemLib/160_Monitoring/UDT_HMI_Monitoring.libint @@ -0,0 +1,6 @@ +DocumentHash: + - FileName: UDT_HMI_Monitoring.xml + Hash: uVmpjpNpQxa3CzL23H/F4G7Os4wbMyFBra9kgsv1vqw= +LibraryMetaFileHash: jKoNhC0+DXpjrwdpnIS3PZGje1seYYvqlZ5+1ljX1fA= +LibraryVersion: + Guid: 5ca767c2-29a7-4ab8-9216-04d3eb721ae9 diff --git a/1_BaseSystemLib/160_Monitoring/UDT_HMI_Monitoring.xml b/1_BaseSystemLib/160_Monitoring/UDT_HMI_Monitoring.xml new file mode 100644 index 0000000..34bfea3 --- /dev/null +++ b/1_BaseSystemLib/160_Monitoring/UDT_HMI_Monitoring.xml @@ -0,0 +1,70 @@ + + + + + + +
+ + + 1 = Signal ist i.O. (z.B. grüner Haken) | 0 = Signal ist n.i.O (z.B. rotes X) + + + + + Signal ist i.O. aber Überwachung muss noch quittiert werden + + +
+
+ UDT_HMI_Monitoring + +
+ + + + + + de-DE + Überwachung eines Signals. Schnittstelle zur HMI + + + + + en-US + + + + + + cs-CZ + + + + + + + + + + de-DE + + + + + + en-US + + + + + + cs-CZ + + + + + + +
+
\ No newline at end of file diff --git a/1_BaseSystemLib/170_Communications/Misc/FC_CheckSumTel_MCopy.libinfo b/1_BaseSystemLib/170_Communications/Misc/FC_CheckSumTel_MCopy.libinfo new file mode 100644 index 0000000..a51e131 --- /dev/null +++ b/1_BaseSystemLib/170_Communications/Misc/FC_CheckSumTel_MCopy.libinfo @@ -0,0 +1,6 @@ +LibraryType: + Guid: 1bccc25d-f0e3-41bf-bf8f-556451b48635 +LibraryVersion: + VersionNumber: 0.0.1 + Author: e.yueksel + IsDefault: true diff --git a/1_BaseSystemLib/170_Communications/Misc/FC_CheckSumTel_MCopy.libint b/1_BaseSystemLib/170_Communications/Misc/FC_CheckSumTel_MCopy.libint new file mode 100644 index 0000000..db05889 --- /dev/null +++ b/1_BaseSystemLib/170_Communications/Misc/FC_CheckSumTel_MCopy.libint @@ -0,0 +1,9 @@ +DocumentHash: + - FileName: FC_CheckSumTel_MCopy.scl + Hash: zcrADDK8lZALDCIxGb5qBh+pGgaCJUi9wXbHiZvlHdw= +LibraryMetaFileHash: TNziG1GxJT4svgIKOyJQgS92gdrlR+wYUjQB1GtjE54= +LibraryVersion: + Guid: 904645a8-99b5-49ae-958e-8bd0900b6f5c + DependsOn: + - TypeName: FC_LenTel_DigitSingle_MCopy + VersionNumber: 0.0.1 diff --git a/1_BaseSystemLib/170_Communications/Misc/FC_CheckSumTel_MCopy.scl b/1_BaseSystemLib/170_Communications/Misc/FC_CheckSumTel_MCopy.scl new file mode 100644 index 0000000..fd5c2df --- /dev/null +++ b/1_BaseSystemLib/170_Communications/Misc/FC_CheckSumTel_MCopy.scl @@ -0,0 +1,77 @@ +FUNCTION "FC_CheckSumTel_MCopy" : Void +{ S7_Optimized_Access := 'TRUE' } +VERSION : 0.1 + VAR_INPUT + "Byte" : Array[1..10] of Byte; + END_VAR + + VAR_OUTPUT + nOutCheckSum : UDInt; + xOutError : Bool; + END_VAR + + VAR_TEMP + TempInt : Array[1..10] of UDInt; + TempError : Array[1..10] of Bool; + TempResult : UDInt; + TempErrorIndex : USInt; + TempIntIndex : USInt; + END_VAR + + +BEGIN + "FC_LenTel_DigitSingle_MCopy"(bIn := #Byte[1], + nOut => #TempInt[1], + xOutError => #TempError[1]); + "FC_LenTel_DigitSingle_MCopy"(bIn := #Byte[2], + nOut => #TempInt[2], + xOutError => #TempError[2]); + "FC_LenTel_DigitSingle_MCopy"(bIn := #Byte[3], + nOut => #TempInt[3], + xOutError => #TempError[3]); + "FC_LenTel_DigitSingle_MCopy"(bIn := #Byte[4], + nOut => #TempInt[4], + xOutError => #TempError[4]); + "FC_LenTel_DigitSingle_MCopy"(bIn := #Byte[5], + nOut => #TempInt[5], + xOutError => #TempError[5]); + "FC_LenTel_DigitSingle_MCopy"(bIn := #Byte[6], + nOut => #TempInt[6], + xOutError => #TempError[6]); + "FC_LenTel_DigitSingle_MCopy"(bIn := #Byte[7], + nOut => #TempInt[7], + xOutError => #TempError[7]); + "FC_LenTel_DigitSingle_MCopy"(bIn := #Byte[8], + nOut => #TempInt[8], + xOutError => #TempError[8]); + "FC_LenTel_DigitSingle_MCopy"(bIn := #Byte[9], + nOut => #TempInt[9], + xOutError => #TempError[9]); + "FC_LenTel_DigitSingle_MCopy"(bIn := #Byte[10], + nOut => #TempInt[10], + xOutError => #TempError[10]); + + FOR #TempErrorIndex := 1 TO 10 DO + IF #TempError[#TempErrorIndex] THEN + #nOutCheckSum := 0; + #xOutError := true; + FOR #TempIntIndex := 1 TO 10 DO + #TempInt[#TempIntIndex] := 0; + END_FOR; + EXIT; + END_IF; + #xOutError := false; + END_FOR; + + #TempResult := (#TempInt[1] * 1000000000) + (#TempInt[2] * 100000000) + (#TempInt[3] * 10000000) + (#TempInt[4] * 1000000) + (#TempInt[5] * 100000) + (#TempInt[6] * 10000) + (#TempInt[7] * 1000) + (#TempInt[8] * 100) + (#TempInt[9] * 10) + (#TempInt[10] * 1); + + IF #TempResult <= 4294967295 AND #TempResult > 0 THEN + #nOutCheckSum := #TempResult; + #xOutError := false; + ELSE + #nOutCheckSum := 0; + #xOutError := TRUE; + END_IF; + +END_FUNCTION + diff --git a/1_BaseSystemLib/170_Communications/Misc/FC_LenTel_DigitSingle_MCopy.libinfo b/1_BaseSystemLib/170_Communications/Misc/FC_LenTel_DigitSingle_MCopy.libinfo new file mode 100644 index 0000000..7bc2375 --- /dev/null +++ b/1_BaseSystemLib/170_Communications/Misc/FC_LenTel_DigitSingle_MCopy.libinfo @@ -0,0 +1,6 @@ +LibraryType: + Guid: be300a29-366c-4af7-86d4-03b57ad189ac +LibraryVersion: + VersionNumber: 0.0.1 + Author: e.yueksel + IsDefault: true diff --git a/1_BaseSystemLib/170_Communications/Misc/FC_LenTel_DigitSingle_MCopy.libint b/1_BaseSystemLib/170_Communications/Misc/FC_LenTel_DigitSingle_MCopy.libint new file mode 100644 index 0000000..5c73367 --- /dev/null +++ b/1_BaseSystemLib/170_Communications/Misc/FC_LenTel_DigitSingle_MCopy.libint @@ -0,0 +1,6 @@ +DocumentHash: + - FileName: FC_LenTel_DigitSingle_MCopy.scl + Hash: vMlfZS59FkD9vRhU7J4yRkq5IFleg7ON3Y9Ou2gbBCY= +LibraryMetaFileHash: LM23JFYgY7nJI+beJASWy2jiG1lV0xBvHBKcbXzbl5Q= +LibraryVersion: + Guid: 4649d6fe-3163-4b85-9cac-01dbba1c2535 diff --git a/1_BaseSystemLib/170_Communications/Misc/FC_LenTel_DigitSingle_MCopy.scl b/1_BaseSystemLib/170_Communications/Misc/FC_LenTel_DigitSingle_MCopy.scl new file mode 100644 index 0000000..34f59a0 --- /dev/null +++ b/1_BaseSystemLib/170_Communications/Misc/FC_LenTel_DigitSingle_MCopy.scl @@ -0,0 +1,53 @@ +FUNCTION "FC_LenTel_DigitSingle_MCopy" : Void +{ S7_Optimized_Access := 'TRUE' } +VERSION : 0.1 + VAR_INPUT + bIn : Byte; + END_VAR + + VAR_OUTPUT + nOut : UDInt; + xOutError : Bool; + END_VAR + + +BEGIN + + CASE #bIn OF + 16#30: + #nOut := 0; + #xOutError := FALSE; + 16#31: + #nOut := 1; + #xOutError := FALSE; + 16#32: + #nOut := 2; + #xOutError := FALSE; + 16#33: + #nOut := 3; + #xOutError := FALSE; + 16#34: + #nOut := 4; + #xOutError := FALSE; + 16#35: + #nOut := 5; + #xOutError := FALSE; + 16#36: + #nOut := 6; + #xOutError := FALSE; + 16#37: + #nOut := 7; + #xOutError := FALSE; + 16#38: + #nOut := 8; + #xOutError := FALSE; + 16#39: + #nOut := 9; + #xOutError := FALSE; + ELSE + #xOutError := TRUE + ; + END_CASE; + +END_FUNCTION + diff --git a/1_BaseSystemLib/170_Communications/Misc/FC_LenTel_MCopy.libinfo b/1_BaseSystemLib/170_Communications/Misc/FC_LenTel_MCopy.libinfo new file mode 100644 index 0000000..8d4b819 --- /dev/null +++ b/1_BaseSystemLib/170_Communications/Misc/FC_LenTel_MCopy.libinfo @@ -0,0 +1,6 @@ +LibraryType: + Guid: c2de9ced-3384-4ae5-b061-c56131670178 +LibraryVersion: + VersionNumber: 0.0.1 + Author: e.yueksel + IsDefault: true diff --git a/1_BaseSystemLib/170_Communications/Misc/FC_LenTel_MCopy.libint b/1_BaseSystemLib/170_Communications/Misc/FC_LenTel_MCopy.libint new file mode 100644 index 0000000..6c0d90a --- /dev/null +++ b/1_BaseSystemLib/170_Communications/Misc/FC_LenTel_MCopy.libint @@ -0,0 +1,9 @@ +DocumentHash: + - FileName: FC_LenTel_MCopy.scl + Hash: T4kd83QvV4KwH5zjQ+4AcNWXs+c3obLLTTuar2wzbFQ= +LibraryMetaFileHash: SSQYpgHCkqDK4frap08MmA/MXYZ+UPnlm5mGZAunOks= +LibraryVersion: + Guid: 72381b85-e571-49f5-9b1e-12b557d735ff + DependsOn: + - TypeName: FC_LenTel_DigitSingle_MCopy + VersionNumber: 0.0.1 diff --git a/1_BaseSystemLib/170_Communications/Misc/FC_LenTel_MCopy.scl b/1_BaseSystemLib/170_Communications/Misc/FC_LenTel_MCopy.scl new file mode 100644 index 0000000..238fe53 --- /dev/null +++ b/1_BaseSystemLib/170_Communications/Misc/FC_LenTel_MCopy.scl @@ -0,0 +1,68 @@ +FUNCTION "FC_LenTel_MCopy" : Void +{ S7_Optimized_Access := 'TRUE' } +VERSION : 0.1 + VAR_INPUT + "Byte" : Array[1..7] of Byte; + END_VAR + + VAR_OUTPUT + nOutLen : Int; + xOutError : Bool; + END_VAR + + VAR_TEMP + TempInt : Array[1..7] of UDInt; + TempError : Array[1..7] of Bool; + TempResult : UDInt; + TempErrorIndex : USInt; + TempIntIndex : USInt; + END_VAR + + +BEGIN + "FC_LenTel_DigitSingle_MCopy"(bIn:= #Byte[1], + nOut=> #TempInt[1], + xOutError=> #TempError[1]); + "FC_LenTel_DigitSingle_MCopy"(bIn := #Byte[2], + nOut => #TempInt[2], + xOutError => #TempError[2]); + "FC_LenTel_DigitSingle_MCopy"(bIn := #Byte[3], + nOut => #TempInt[3], + xOutError => #TempError[3]); + "FC_LenTel_DigitSingle_MCopy"(bIn := #Byte[4], + nOut => #TempInt[4], + xOutError => #TempError[4]); + "FC_LenTel_DigitSingle_MCopy"(bIn := #Byte[5], + nOut => #TempInt[5], + xOutError => #TempError[5]); + "FC_LenTel_DigitSingle_MCopy"(bIn := #Byte[6], + nOut => #TempInt[6], + xOutError => #TempError[6]); + "FC_LenTel_DigitSingle_MCopy"(bIn := #Byte[7], + nOut => #TempInt[7], + xOutError => #TempError[7]); + + FOR #TempErrorIndex := 1 TO 7 DO + IF #TempError[#TempErrorIndex] THEN + #nOutLen := 0; + #xOutError := true; + FOR #TempIntIndex := 1 TO 7 DO + #TempInt[#TempIntIndex] := 0; + END_FOR; + EXIT; + END_IF; + #xOutError := false; + END_FOR; + + #TempResult := (#TempInt[1] * 1000000) + (#TempInt[2] * 100000) + (#TempInt[3] * 10000) + (#TempInt[4] * 1000) + (#TempInt[5] * 100) + (#TempInt[6] * 10) + (#TempInt[7] * 1); + + IF #TempResult <= 65535 AND #TempResult > 0 THEN + #nOutLen := UDINT_TO_INT(#TempResult); + #xOutError := false; + ELSE + #nOutLen := 0; + #xOutError := TRUE; + END_IF; + +END_FUNCTION + diff --git a/1_BaseSystemLib/170_Communications/Misc/LGF_CalcCRC32Advanced_MCopy.libinfo b/1_BaseSystemLib/170_Communications/Misc/LGF_CalcCRC32Advanced_MCopy.libinfo new file mode 100644 index 0000000..cc22c7b --- /dev/null +++ b/1_BaseSystemLib/170_Communications/Misc/LGF_CalcCRC32Advanced_MCopy.libinfo @@ -0,0 +1,6 @@ +LibraryType: + Guid: 3d599b5b-0213-46f8-8892-325ed0394c19 +LibraryVersion: + VersionNumber: 0.0.1 + Author: e.yueksel + IsDefault: true diff --git a/1_BaseSystemLib/170_Communications/Misc/LGF_CalcCRC32Advanced_MCopy.libint b/1_BaseSystemLib/170_Communications/Misc/LGF_CalcCRC32Advanced_MCopy.libint new file mode 100644 index 0000000..bf4297d --- /dev/null +++ b/1_BaseSystemLib/170_Communications/Misc/LGF_CalcCRC32Advanced_MCopy.libint @@ -0,0 +1,6 @@ +DocumentHash: + - FileName: LGF_CalcCRC32Advanced_MCopy.scl + Hash: 1qqS4TkbI0CoSZdszKz6k+3lkVQa0jWbmnNgukz1Iqg= +LibraryMetaFileHash: KkCWyXRn3OXenxTY0Y4Iwgskl07io9/EARfgdrNs/mE= +LibraryVersion: + Guid: 31658ecf-f5da-4a76-a463-cd1e98d4aa4e diff --git a/1_BaseSystemLib/170_Communications/Misc/LGF_CalcCRC32Advanced_MCopy.scl b/1_BaseSystemLib/170_Communications/Misc/LGF_CalcCRC32Advanced_MCopy.scl new file mode 100644 index 0000000..73ad417 --- /dev/null +++ b/1_BaseSystemLib/170_Communications/Misc/LGF_CalcCRC32Advanced_MCopy.scl @@ -0,0 +1,175 @@ +FUNCTION "LGF_CalcCRC32Advanced_MCopy" : DWord +TITLE = LGF_CalcCRC32Advanced +{ S7_Optimized_Access := 'TRUE' } +AUTHOR : Siemens_Industry_Support +FAMILY : LGF +NAME : LGF_CRC32Advanced +//Die CRC-Berechnung wird für die Fehlererkennung bei der Datenübertragung verwendet. Das Ergebnis einer Berechnung liefert einen CRC-Wert über die gesendeten Daten. Der Empfänger erkennt eine fehlerhafte Übertragung aufgrund des ungleichen CRC-Werts. Die Funktion `LGF_CalcCRC32Advanced` verwendet als Generatorpolynom (Maske) 32 Bit sowie die Parameter `finalXorValue`, `reflectInput` und `reflectResult`. + VAR_INPUT + initValue { S7_PredefinedAssignment := '16#00'} : DWord; // Startwert, mit dem die Berechnung durchgeführt wird. Wenn keinen Startwert notwendig ist - 16#00 zuweisen. + mask { S7_PredefinedAssignment := '16#00'} : DWord; // Generatorpolynom, mit dem die Berechnung durchgeführt wird. (Maske / CRC Polynom) + finalXorValue { S7_PredefinedAssignment := '16#00'} : DWord; // Wert, mit dem am Ende eine weitere XOR-Operation durchgeführt wird + nInLowerLimit : Int; + nInUpperLimit : Int; + reflectInput { S7_PredefinedAssignment := 'FALSE'} : Bool; // TRUE: wird die Reihenfolge der Bits innerhalb des Eingangsbytes gespiegelt. Aus der Reihenfolge 0…7 wird 7…0. + reflectResult { S7_PredefinedAssignment := 'FALSE'} : Bool; // TRUE: wird die Reihenfolge der Bits innerhalb des Ergebnisses gespiegelt. Aus der Reihenfolge 0…7 wird 7…0. + END_VAR + + VAR_IN_OUT + "array" : Array[*] of Byte; // Datenstrom, für den der CRC-Wert berechnet werden soll. + END_VAR + + VAR_TEMP + tempInput : Byte; // Temp aktuelles eingangs Byte + tempCRC : DWord; // Temp CRC Prüfsumme + tempInvCRC : DWord; // Temp invertierte CRC Prüfsumme + tempLowerLimit : DInt; // Temp Untergrenze Eingangs Array + tempUpperLimit : DInt; // Temp Obergrenze Eingangs Array + tempIndexArray : DInt; // Temp Array schleifen Index + tempIndexCRC : DInt; // Temp CRC Schleifen Index + END_VAR + + VAR CONSTANT + SHIFT_ONE_BIT : UInt := 1; // Schieben der CRC Berechnung um ein Bit + SHIFT_THREE_BYTE : UInt := 24; // Schieben um drei Byte (= 24 Bit) + ARRAY_FIRST_DIMENSION : UInt := 1; // Erste Dimension im Array + CRC_LOOP_LOWER_LIMIT : DInt := 0; // Untere Grenze für die CRC Berechnungsschleife + CRC_LOOP_UPPER_LIMIT : DInt := 7; // Obere Grenze für die CRC Berechnungsschleife + END_VAR + + +BEGIN + REGION Block info header + //=============================================================================== + // SIEMENS AG / (c)Copyright 2019 + //------------------------------------------------------------------------------- + // Title: LGF_CRC32Advanced + // Comment/Function: This function makes a CRC calculation according + // to the CRC-32 algorithm + // advanced because of reflect In/Out and final XOR combination + // 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 - no error handling, no failure possible + // Requirements: PLC (S7-1200 / S7-1500) + //------------------------------------------------------------------------------- + // Change log table: + // Version | Date | Expert in charge | Changes applied + //----------|------------|------------------------|------------------------------ + // 01.00.00 03.07.2018 Siemens Industry Online Support + // First released version + // 01.00.01 17.08.2018 Siemens Industry Online Support + // Upgrade: TIA V15 Update 2 + // 01.00.02 23.11.2018 Siemens Industry Online Support + // Upgrade: TIA V15.1 + // 01.00.03 09.10.2019 Simatic Systems Support + // Code refactoring, comments added + // 03.00.00 23.04.2020 Simatic Systems Support + // Set version to V3.0.0, harmonize the version of the whole library + // 03.00.01 12.11.2020 Simatic Systems Support + // Insert documentation + // Assign default start values to optional inputs - `initValue`, `mask`, `finalXorValue`, `reflectInput`, `reflectResult` + //============================================================================= + END_REGION Block info header + + REGION DESCRIPTION + (/* + Die Funktion berechnet aus einem beliebig großen Datenstrom den CRC-Wert. Der Datenstrom setzt sich aus den einzelnen Elementen des Arrays am Ein- / Ausgangsparameter `array` zusammen. Der Startwert `initValue` und das Generatorpolynom `mask` sind frei wählbar. + + Über die booleschen Eingangsparameter `reflectInput` und `reflectResult` können Sie optional die Bits der Eingangsdaten bzw. des CRC-Werts spiegeln. Außerdem wird mit dem CRC-Wert am Ende und dem Wert `finalXorValue` eine XOR-Operation durchgeführt. + + Hinweis + : Für die Berechnung der CRC-Werte stehen verschiedene Online-Tools zur Verfügung. Die Funktion des Bausteins wurde mit folgendem Online-Tool getestet, da es die Eingangsparameter `mask` (Polynom) und `initValue` (Initial Value) unterstützt: + : http://www.sunshine2k.de/coding/javascript/crc/crc_js.html + */) + END_REGION DESCRIPTION + + REGION Initialization and input data processing + // Input array size calculation + #tempLowerLimit := #nInLowerLimit;//LOWER_BOUND(ARR := #array, DIM := #ARRAY_FIRST_DIMENSION); + #tempUpperLimit := #nInUpperLimit;//UPPER_BOUND(ARR := #array, DIM := #ARRAY_FIRST_DIMENSION); + // Defining initial value for algorithm + #tempCRC := #initValue; + END_REGION + + REGION CRC calculation + FOR #tempIndexArray := #tempLowerLimit TO #tempUpperLimit DO + + IF #reflectInput THEN + // Reverse bit order in input byte + #tempInput.%X7 := #array[#tempIndexArray].%X0; + #tempInput.%X6 := #array[#tempIndexArray].%X1; + #tempInput.%X5 := #array[#tempIndexArray].%X2; + #tempInput.%X4 := #array[#tempIndexArray].%X3; + #tempInput.%X3 := #array[#tempIndexArray].%X4; + #tempInput.%X2 := #array[#tempIndexArray].%X5; + #tempInput.%X1 := #array[#tempIndexArray].%X6; + #tempInput.%X0 := #array[#tempIndexArray].%X7; + ELSE + #tempInput := #array[#tempIndexArray]; + END_IF; + + // Perform division using XOR function for appropriate DWord in array (with shift byte into MSB of 32bit CRC) + #tempCRC := #tempCRC XOR SHL(IN := BYTE_TO_DWORD(#tempInput), N := #SHIFT_THREE_BYTE); + + FOR #tempIndexCRC := #CRC_LOOP_LOWER_LIMIT TO #CRC_LOOP_UPPER_LIMIT DO + // Check if MSB is set + IF #tempCRC.%X31 THEN + // Shift left and perform division by mask polynomial using XOR function + #tempCRC := SHL(IN := #tempCRC, N := #SHIFT_ONE_BIT) XOR #mask; + ELSE + // Shift left without division + #tempCRC := SHL(IN := #tempCRC, N := #SHIFT_ONE_BIT); + END_IF; + END_FOR; + + END_FOR; + END_REGION + + REGION Outputs assignment + IF #reflectResult THEN + // Reverse bit order in CRC checksum + #tempInvCRC.%X31 := #tempCRC.%X0; + #tempInvCRC.%X30 := #tempCRC.%X1; + #tempInvCRC.%X29 := #tempCRC.%X2; + #tempInvCRC.%X28 := #tempCRC.%X3; + #tempInvCRC.%X27 := #tempCRC.%X4; + #tempInvCRC.%X26 := #tempCRC.%X5; + #tempInvCRC.%X25 := #tempCRC.%X6; + #tempInvCRC.%X24 := #tempCRC.%X7; + #tempInvCRC.%X23 := #tempCRC.%X8; + #tempInvCRC.%X22 := #tempCRC.%X9; + #tempInvCRC.%X21 := #tempCRC.%X10; + #tempInvCRC.%X20 := #tempCRC.%X11; + #tempInvCRC.%X19 := #tempCRC.%X12; + #tempInvCRC.%X18 := #tempCRC.%X13; + #tempInvCRC.%X17 := #tempCRC.%X14; + #tempInvCRC.%X16 := #tempCRC.%X15; + #tempInvCRC.%X15 := #tempCRC.%X16; + #tempInvCRC.%X14 := #tempCRC.%X17; + #tempInvCRC.%X13 := #tempCRC.%X18; + #tempInvCRC.%X12 := #tempCRC.%X19; + #tempInvCRC.%X11 := #tempCRC.%X20; + #tempInvCRC.%X10 := #tempCRC.%X21; + #tempInvCRC.%X9 := #tempCRC.%X22; + #tempInvCRC.%X8 := #tempCRC.%X23; + #tempInvCRC.%X7 := #tempCRC.%X24; + #tempInvCRC.%X6 := #tempCRC.%X25; + #tempInvCRC.%X5 := #tempCRC.%X26; + #tempInvCRC.%X4 := #tempCRC.%X27; + #tempInvCRC.%X3 := #tempCRC.%X28; + #tempInvCRC.%X2 := #tempCRC.%X29; + #tempInvCRC.%X1 := #tempCRC.%X30; + #tempInvCRC.%X0 := #tempCRC.%X31; + + #LGF_CalcCRC32Advanced_MCopy := #tempInvCRC XOR #finalXorValue; + ELSE + #LGF_CalcCRC32Advanced_MCopy := #tempCRC XOR #finalXorValue; + END_IF; + // no error handling needed + ENO := TRUE; + END_REGION + +END_FUNCTION + diff --git a/1_BaseSystemLib/170_Communications/TCP/TCPServer/FB_OUC_TCP.libinfo b/1_BaseSystemLib/170_Communications/TCP/TCPServer/FB_OUC_TCP.libinfo new file mode 100644 index 0000000..3bfb889 --- /dev/null +++ b/1_BaseSystemLib/170_Communications/TCP/TCPServer/FB_OUC_TCP.libinfo @@ -0,0 +1,10 @@ +LibraryType: + Guid: 80cf5fc6-be82-4277-af7f-88c3b4ff7626 + Comment: + de-DE: Siemens OUC TCP Kommunikationsbaustein +LibraryVersion: + VersionNumber: 2.0.0 + Author: e.yueksel + IsDefault: true + Comment: + de-DE: Siemens OUC TCP Kommunikationsbaustein diff --git a/1_BaseSystemLib/170_Communications/TCP/TCPServer/FB_OUC_TCP.libint b/1_BaseSystemLib/170_Communications/TCP/TCPServer/FB_OUC_TCP.libint new file mode 100644 index 0000000..fd27954 --- /dev/null +++ b/1_BaseSystemLib/170_Communications/TCP/TCPServer/FB_OUC_TCP.libint @@ -0,0 +1,9 @@ +DocumentHash: + - FileName: FB_OUC_TCP.scl + Hash: nwFqWTIjLRoxAWgy6RXq3N+7xBPUodzEt9DMk5oKkW0= +LibraryMetaFileHash: 8xXIwLyl8E96ICjYbs61bN17CHdQJRj0Fx8Ez/i9uKI= +LibraryVersion: + Guid: 0db585c5-46ed-491e-9e90-b7934568d4b8 + DependsOn: + - TypeName: typeDiagnostics + VersionNumber: 1.0.0 diff --git a/1_BaseSystemLib/170_Communications/TCP/TCPServer/FB_OUC_TCP.scl b/1_BaseSystemLib/170_Communications/TCP/TCPServer/FB_OUC_TCP.scl new file mode 100644 index 0000000..e19eee2 --- /dev/null +++ b/1_BaseSystemLib/170_Communications/TCP/TCPServer/FB_OUC_TCP.scl @@ -0,0 +1,382 @@ +FUNCTION_BLOCK "FB_OUC_TCP" +{ S7_Optimized_Access := 'TRUE' } +AUTHOR : SIOS +FAMILY : OUC +VERSION : 2.0 + VAR_INPUT + enable : Bool; + send : Bool; + rcvLen : UDInt; + sendLen : UDInt; + adhocMode : Bool; + connParam {InstructionName := 'TCON_IP_v4'; LibVersion := '1.0'} : TCON_IP_v4; + END_VAR + + VAR_OUTPUT + valid { ExternalWritable := 'False'} : Bool; + done { ExternalWritable := 'False'} : Bool; + ndr { ExternalWritable := 'False'} : Bool; + busy { ExternalWritable := 'False'} : Bool; + error { ExternalWritable := 'False'} : Bool; + status { ExternalWritable := 'False'} : Word := #STATUS_NO_CALL; + diagnostics { ExternalWritable := 'False'} : "typeDiagnostics"; + rcvdLen { ExternalWritable := 'False'} : UDInt; + END_VAR + + VAR_IN_OUT + rcvdData : Array[*] of Byte; + sendData : Array[*] of Byte; + END_VAR + + VAR + statEnableOld { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; + statSendOld { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; + statValid { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; + statDone { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; + statNdr { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; + statBusy { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; + statError { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; + statErrorUserCleared { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; + statErrorAutoCleared { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; + statStatus { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Word := #STATUS_NO_CALL; + statSubfunctionStatus { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Word; + statFBErrorState { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : DInt; + statFBState { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : DInt := #FB_STATE_NO_PROCESSING; + statDisablingCompleted { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; + statEmptyDiagnostics { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : "typeDiagnostics"; + statConnParam {InstructionName := 'TCON_IP_v4'; LibVersion := '1.0'; ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : TCON_IP_v4; + instTCon {InstructionName := 'TCON'; LibVersion := '4.0'; ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : TCON; + instTRcv {InstructionName := 'TRCV'; LibVersion := '4.0'; ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : TRCV; + instTSend {InstructionName := 'TSEND'; LibVersion := '4.0'; ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : TSEND; + instTDiscon {InstructionName := 'TDISCON'; LibVersion := '2.1'; ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : TDISCON; + statRcvdLen { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : UDInt; + statRcvEnable { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; + statConReq { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; + statDisconReq { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; + statSendReq { ExternalAccessible := 'False'; ExternalVisible := 'False'; ExternalWritable := 'False'} : Bool; + END_VAR + + VAR_TEMP + tempEnable : Bool; + tempSend : Bool; + tempAdhocMode : Bool; + tempRcvLen : UDInt; + tempSendLen : UDInt; + END_VAR + + VAR CONSTANT + FB_STATE_NO_PROCESSING : DInt := 0; + FB_STATE_ENABLING : DInt := 10; + FB_STATE_CONNECTED : DInt := 50; + FB_STATE_DISABLING : DInt := 90; + STATUS_EXECUTION_FINISHED : Word := 16#0000; + STATUS_NO_CALL : Word := 16#7000; + STATUS_FIRST_CALL : Word := 16#7001; + STATUS_SUBSEQUENT_CALL : Word := 16#7002; + SUB_STATUS_NO_ERROR : Word := 16#0000; + ERR_IN_BLOCK_OPERATION : Word := 16#8001; + ERR_PARAMETRIZATION : Word := 16#8200; + ERR_PROCESSING_EXTERN : Word := 16#8400; + ERR_PROCESSING_INTERN : Word := 16#8600; + ERR_UNDEFINED_STATE : Word := 16#8600; + ERR_TCON : Word := 16#8601; + ERR_TSEND : Word := 16#8602; + ERR_TRCV : Word := 16#8603; + ERR_AREA_RESERVED : Word := 16#8800; + ERR_USER_DEFINED_CLASSES : Word := 16#9000; + ERR_OUC_PARTNER_TERMINATED_CONNECTION : Word := 16#80C5; + ERR_OUC_CANNOT_REACH_PARTNER : Word := 16#80C6; + END_VAR + + +BEGIN + REGION BLOCK INFO HEADER + //=============================================================================== + // (company) / (c)Copyright (year) + //------------------------------------------------------------------------------- + // Title: (Title of this Block / Enable Template) + // Comment/Function: (that is implemented in the block) + // (Template for an FB with Enable / Valid handling based on PLCopen standard "Function Blocks for Motion Control" V2.0) + // Library/Family: (that the source is dedicated to) + // Author: (department / person in charge / contact) + // Tested with: (test system with FW version) + // Engineering: TIA Portal (SW version) + // Restrictions: (OB types, etc.) + // Requirements: (hardware, technological package, memory needed, etc.) + //------------------------------------------------------------------------------- + // Change log table: + // Version | Date | Expert in charge | Changes applied + //----------|------------|------------------------|------------------------------ + // 01.00.00 | yyyy-mm-dd | (name of expert) | First released version + //=============================================================================== + END_REGION + + // Create process image + #tempEnable := #enable; + #tempSend := #send; + #tempAdhocMode := #adhocMode; + + IF #tempAdhocMode = TRUE THEN // ignore parameter rcvLen in ad-hoc mode + #tempRcvLen := 0; + ELSIF #tempAdhocMode = FALSE THEN // normal mode + #tempRcvLen := #rcvLen; + END_IF; + #tempSendLen := #sendLen; + + REGION ENABLING/DISABLING + IF (#tempEnable = TRUE) AND (#statStatus = #STATUS_NO_CALL) THEN // Enable FB + // First call; initialize FB + #statValid := TRUE; + #statBusy := TRUE; + #statError := FALSE; + #statErrorUserCleared := FALSE; + #statErrorAutoCleared := FALSE; + #statSubfunctionStatus := #SUB_STATUS_NO_ERROR; + #statFBErrorState := 0; + #diagnostics := #statEmptyDiagnostics; + #statDisablingCompleted := FALSE; + // State machine - start functionality + #statFBState := #FB_STATE_ENABLING; + #statStatus := #STATUS_FIRST_CALL; + + #statConReq := FALSE; + #statDisconReq := FALSE; + #statRcvEnable := FALSE; + #statSendReq := FALSE; + #statRcvdLen := 0; + #statConnParam := #connParam; + #statDone := FALSE; + #statNdr := FALSE; + + ELSIF (#tempEnable = FALSE) AND (#statEnableOld = TRUE) THEN // Disable FB + #statFBState := #FB_STATE_DISABLING; + + ELSIF (#statStatus = #STATUS_FIRST_CALL) THEN // Set status identifier of subsequent call + #statStatus := #STATUS_SUBSEQUENT_CALL; + END_IF; + + // Edge detection 'enable' input + #statEnableOld := #tempEnable; + END_REGION ENABLING/DISABLING + + IF (#statStatus = #STATUS_NO_CALL) THEN // Nothing to do -> End here to reduce "system load" + RETURN; + END_IF; + + REGION STATE_MACHINE + CASE #statFBState OF // State machine of FB + #FB_STATE_NO_PROCESSING: + REGION no processing + // No processing active (Note: this state must always be present and left empty) + ; + END_REGION no processing + + #FB_STATE_ENABLING: // Enabling active + #statConReq := true; // Set here to create new rising edge after partner refused connection + + REGION enabling + IF (#instTCon.DONE = true) THEN + #statConReq := false; + #statRcvEnable := true; // Enable receiving + #statErrorAutoCleared := false; // Reset possible errors + #statFBState := #FB_STATE_CONNECTED; // TODO: Replace with #FB_STATE_SEND if data is sent before anything is expected + ELSIF (#instTCon.ERROR = true) THEN + #statConReq := false; + #statStatus := #ERR_TCON; + #statSubfunctionStatus := #instTCon.STATUS; + #statFBErrorState := #statFBState; + + IF (#instTCon.STATUS = #ERR_OUC_PARTNER_TERMINATED_CONNECTION) + OR (#instTCon.STATUS = #ERR_OUC_CANNOT_REACH_PARTNER) + THEN // Error can be cleared automatically + #statErrorAutoCleared := true; + // Remain in enabling state and wait for partner + ELSE // Error must be cleared by user + #statErrorUserCleared := true; + END_IF; + END_IF; + END_REGION enabling + + #FB_STATE_CONNECTED: // connection is established + REGION connected + // Further processing state + // TODO: Use this state for further application specific code + // In this template sending and receiving is processed simultaneously. If sequential processing is required, move the following code to separate states + + + #statNdr := false; // reset ndr after one cycle + + REGION receive + IF #instTRcv.NDR = TRUE THEN // new data received + REGION ndr + #statNdr := TRUE; + #statRcvdLen := #instTRcv.RCVD_LEN; // Save received length + END_REGION + + ELSIF (#instTRcv.ERROR = true) THEN + REGION error occured + #statErrorAutoCleared := true; // In this template no error of TRCV causes the processing of the FB to stop + #statStatus := #ERR_TRCV; + #statSubfunctionStatus := #instTRcv.STATUS; + #statFBErrorState := #statFBState; + END_REGION + + ELSIF (#instTRcv.ERROR = FALSE AND #statStatus = #ERR_TRCV) THEN + REGION error cleared + #statErrorAutoCleared := FALSE; // Reset any errors + #statStatus := #STATUS_SUBSEQUENT_CALL; // Reset status + END_REGION + END_IF; + END_REGION receive + + REGION send + REGION trigger + IF #tempSend = TRUE AND #statSendOld = FALSE THEN + #statSendReq := TRUE; + + ELSIF (#tempSend = FALSE AND (#statDone = TRUE OR #statError = TRUE)) THEN // Reset outputs + #statDone := FALSE; + IF #statStatus = #STATUS_EXECUTION_FINISHED OR #statStatus = #ERR_TSEND THEN + #statErrorAutoCleared := FALSE; // Reset possible errors + #statStatus := #STATUS_SUBSEQUENT_CALL; + END_IF; + END_IF; + + #statSendOld := #tempSend; + END_REGION + + IF (#instTSend.DONE = true) THEN // data was sent succcessfully + REGION successful + #statSendReq := false; + #statDone := true; + #statStatus := #STATUS_EXECUTION_FINISHED; + END_REGION + + ELSIF (#instTSend.ERROR = true) THEN + REGION error occured + #statSendReq := false; + #statErrorAutoCleared := true; // In this template no error of TSEND causes the processing of the FB to stop + #statStatus := #ERR_TSEND; + #statSubfunctionStatus := #instTSend.STATUS; + #statFBErrorState := #statFBState; + END_REGION + END_IF; + END_REGION send + + END_REGION connected + + #FB_STATE_DISABLING: // Disabling active + REGION disabling + #statConReq := false; + #statSendReq := false; + #statRcvEnable := false; + #statDisconReq := true; + + IF (#instTDiscon.DONE = true OR #instTDiscon.ERROR = true) THEN // Ignore errors from TDISCON + #statDisconReq := false; + #statFBState := #FB_STATE_NO_PROCESSING; + #statDisablingCompleted := TRUE; + END_IF; + END_REGION disabling + + ELSE // Undefined state in state machine reached + REGION undefined state + #statStatus := #ERR_UNDEFINED_STATE; + #statErrorUserCleared := TRUE; + END_REGION undefined state + END_CASE; + END_REGION STATE_MACHINE + + REGION INSTRUCTIONS + // call TCON to establish the connection + #instTCon(REQ := #statConReq, + ID := #statConnParam.ID, + CONNECT := #statConnParam); + + // call TDISCON to disconnect the connection + #instTDiscon(REQ := #statDisconReq, + ID := #statConnParam.ID); + + // call TRCV to receive data + #instTRcv(EN_R := #statRcvEnable, + ID := #statConnParam.ID, + LEN := #tempRcvLen, + ADHOC := #tempAdhocMode, + DATA := #rcvdData); // TODO: Replace with internal buffer if data shall be processed instead of output + + // call TSEND to send data + #instTSend(REQ := #statSendReq, + ID := #statConnParam.ID, + LEN := #tempSendLen, + DATA := #sendData); + END_REGION INSTRUCTIONS + + REGION OUTPUTS + // Write outputs + IF (#statDisablingCompleted = TRUE) THEN + REGION disabling + // Reset outputs if disabling completed + #statValid := FALSE; + #statBusy := FALSE; + #statError := FALSE; + #statErrorUserCleared := FALSE; + #statErrorAutoCleared := FALSE; + #statStatus := #STATUS_NO_CALL; + // TODO: Reset application specific outputs + #statRcvdLen := 0; + #statDone := false; + #statNdr := false; + END_REGION disabling + + ELSIF (#statErrorUserCleared = TRUE) AND (#statError = FALSE) THEN + REGION error user cleared + // Error can only be cleared by user; rising edge at enable input is needed to continue + #statValid := FALSE; + #statBusy := FALSE; + #statError := TRUE; + // Write diagnostics + #diagnostics.status := #statStatus; + #diagnostics.subfunctionStatus := #statSubfunctionStatus; + #diagnostics.stateNumber := #statFBErrorState; + // execution aborted --> set state no processing + #statFBState := #FB_STATE_NO_PROCESSING; + END_REGION error user cleared + + ELSIF (#statErrorAutoCleared = TRUE) AND (#statError = FALSE) THEN + REGION error auto cleared + // Error can be reset by FB automatically + #statValid := FALSE; + #statBusy := TRUE; + #statError := TRUE; + // Write diagnostics + #diagnostics.status := #statStatus; + #diagnostics.subfunctionStatus := #statSubfunctionStatus; + #diagnostics.stateNumber := #statFBErrorState; + END_REGION error auto cleared + + ELSIF (#statErrorAutoCleared = FALSE) AND (#statErrorUserCleared = FALSE) AND (#statError = TRUE) THEN + REGION after user/auto cleared + // If autocleared error is acknowledged + #statValid := TRUE; + #statBusy := TRUE; + #statError := FALSE; + #statStatus := #STATUS_SUBSEQUENT_CALL; + END_REGION after user/auto cleared + END_IF; + + REGION Write static values to outputs + #valid := #statValid; + #done := #statDone; + #ndr := #statNdr; + #busy := #statBusy; + #error := #statError; + #status := #statStatus; + // if ENO mechanism is not used / not wanted replace the following line by --> ENO := TRUE; + ENO := NOT #statError; + // TODO: Write application specific static values to outputs + #rcvdLen := #statRcvdLen; + END_REGION Write static values to outputs + END_REGION OUTPUTS + +END_FUNCTION_BLOCK + diff --git a/1_BaseSystemLib/170_Communications/TCP/TCPServer/FB_TcpCommServer.libinfo b/1_BaseSystemLib/170_Communications/TCP/TCPServer/FB_TcpCommServer.libinfo new file mode 100644 index 0000000..e493e63 --- /dev/null +++ b/1_BaseSystemLib/170_Communications/TCP/TCPServer/FB_TcpCommServer.libinfo @@ -0,0 +1,6 @@ +LibraryType: + Guid: 0062fd19-6682-49cc-834f-95307dbd2d72 +LibraryVersion: + VersionNumber: 0.0.7 + Author: e.yueksel + IsDefault: true diff --git a/1_BaseSystemLib/170_Communications/TCP/TCPServer/FB_TcpCommServer.libint b/1_BaseSystemLib/170_Communications/TCP/TCPServer/FB_TcpCommServer.libint new file mode 100644 index 0000000..c23d83f --- /dev/null +++ b/1_BaseSystemLib/170_Communications/TCP/TCPServer/FB_TcpCommServer.libint @@ -0,0 +1,6 @@ +DocumentHash: + - FileName: FB_TcpCommServer.scl + Hash: qFYsYkF16gjWmp+OcWlum9zmD3C/2IJo/WHaJF8To0Y= +LibraryMetaFileHash: eq0DDd4Z/WCx1XQLK2W2QhViASdtBjgypX7yqdQG/aY= +LibraryVersion: + Guid: 74221796-361b-4eaa-939e-0e1c0aadbd3e diff --git a/1_BaseSystemLib/170_Communications/TCP/TCPServer/FB_TcpCommServer.scl b/1_BaseSystemLib/170_Communications/TCP/TCPServer/FB_TcpCommServer.scl new file mode 100644 index 0000000..3eb5110 --- /dev/null +++ b/1_BaseSystemLib/170_Communications/TCP/TCPServer/FB_TcpCommServer.scl @@ -0,0 +1,622 @@ +FUNCTION_BLOCK "FB_TcpCommServer" +{ S7_Optimized_Access := 'TRUE' } +AUTHOR : SiemensAG +FAMILY : OpenUserComm +VERSION : 1.0 + VAR_INPUT + enable : Bool; // enables TCP/IP connection + sendRequest : Bool; // triggers a send request + rcvLen : UDInt; // length of data you want to receive from partner (opt. DBs = 0) + sendLen : UDInt; // length of date so send to partner + adhocMode : Bool; // activate adhoc Mode to receive data with variable len + tcpConnParam {InstructionName := 'TCON_IP_v4'; LibVersion := '1.0'} : TCON_IP_v4; // Connection Parameters + END_VAR + + VAR_OUTPUT + connectionEstablished : Bool; // connection to partner established + ndr : Bool; // new data received + done : Bool; // send request finished successully + busy : Bool; // block is busy + error : Bool; // error occurred + rcvdLen : UDInt; // length of received data (in byte) + statusID : UInt; // error location in block + status : Word; // status word from OUC blocks + END_VAR + + VAR_IN_OUT + sendData : Array[*] of Byte; // data to send to partner + rcvData : Array[*] of Byte; // received data from partner + END_VAR + + VAR + instTcon {InstructionName := 'TCON'; LibVersion := '4.0'} : TCON; + instTdiscon {InstructionName := 'TDISCON'; LibVersion := '2.1'} : TDISCON; + instTrcv {InstructionName := 'TRCV'; LibVersion := '4.0'} : TRCV; + instTsend {InstructionName := 'TSEND'; LibVersion := '4.0'} : TSEND; + statTcpConnParam {InstructionName := 'TCON_IP_v4'; LibVersion := '1.0'} : TCON_IP_v4; + instTimer {InstructionName := 'TON_TIME'; LibVersion := '1.0'} : TON_TIME; + statStartTimer : Bool; + statStoppTimer : Bool; + statTimeRun : Time; + statEdgeCon : Bool; + statEdgeConOld : Bool; + statEdgeDiscon : Bool; + statEdgeDisconOld : Bool; + statEdgeSendReq : Bool; + statEdgeSendReqOld : Bool; + statConnID : Word; + statConActive : Bool; + statStateValue : Int; + statStatus : Word; + statStatusId : UInt; + statConReEstablish : Bool; + statSendActive : Bool; + statPartnerDisconnected : Bool; + statTimerEnd : Bool; + statErrorIntern : Bool; + statDataBufferRcv : Array[1..65536] of Byte; + statRcvdLen : UDInt; + statRcvLen : UDInt; + statRcvFrameLen : DInt; + statRcvFrameLenSave : DInt; + statRcvBusy : Bool; + statCntRecv : Int; + statRcvDataLen : DWord; + statNdr : Bool; + statLenDetected : Bool; + statCntNdr : UInt; + statRcvLenTest : UDInt; + statLowerBoundSend : DInt; + statLowerBoundRcv : DInt; + statUpperBoundSend : DInt; + statUpperBoundRcv : DInt; + statRcvdLenNotDetected : Bool; + END_VAR + + VAR_TEMP + tempRetVal : Int; + tempPos : DInt; + END_VAR + + VAR CONSTANT + STATE_IDLE : Int := 1; // idle mode - wating for events + STATE_PARAM : Int := 2; // take over IsoOnTcp parameters + STATE_CONNECT : Int := 3; // establish IsoOnTcp connection + STATE_DISCONNECT : Int := 4; // disconnect IsoOnTcp connection + STATE_SEND : Int := 5; // send data to partner + STATE_RECEIVE : Int := 6; // receive data + STATE_CONNECTED : Int := 7; // connection established + STATE_ERROR : Int := 8; // error state + STATUS_ID_INT_ERROR : UInt := 1; // error location state - initialization + STATUS_ID_CON : UInt := 2; // error location state - connect + STATUS_ID_DISCON : UInt := 5; // error location - disconnect + STATUS_ID_SEND : UInt := 4; // error location -send data + STATUS_ID_RCV : UInt := 3; // error location - receive data + ERR_COMM_NOT_STARTED : Word := 16#8101; // communication not startet + ERR_WATCHDOG_TIMER : Word := 16#8102; // watchdog timer expired + ERR_COMM_ID_IN_USE : Word := 16#80A3; // connection ID is already used (TCON) + ERR_COMM_TEMP : Word := 16#80C4; // temporary communication error + ERR_COMM_TCON_NOT_COMPLETED : Word := 16#80A7; // executed "TDISCON" before "TCON" had completed + ERR_COMM_PARTNER_TERMINATE_CONNETION : Word := 16#80C5; // connection partner refuses to establish connection or terminated connection actively + ERR_COMM_CONNECTION_NOT_EXIST : Word := 16#80A3; // connection does exist (TDISCON) + ERR_COMM_CONNECTION_TERMINATED : Word := 16#80A1; // communication already terminated + CONST_LEN_HEADER : UDInt := 4; + CONST_WATCHDOG_TIME : Time := T#180s; // watchdog time + CONST_WORD_0 : Word := 16#0000; + CONST_UINT_0 : UInt := 0; + CONST_UDINT_0 : UDInt := 0; + CONST_DINT_0 : DInt := 0; + CONST_MAX_RCVD_DATA_LEN : UDInt := 65536; + CONST_MIN_RCVD_DATA_LEN : UDInt := 0; + END_VAR + + +BEGIN + //============================================================================= + //SIEMENES AG + //(c)Copyright 2020 All Rights Reserved + //----------------------------------------------------------------------------- + //Library: LOpenUserComm + //Tested with: (S7-1500 V2.8; S7-1200 V4.4) + //Engineering: TIA Portal V16 + //Restrictions: call in cyclic main OB + //Requirements: + //Functionality: Open User Communication Template for TCP connections + // Shows the basic steps to use the OUC blocks to establish + // reliable TCP/IP connections in an state machine + // .... + //NEUER TEST + //----------------------------------------------------------------------------- + //Change log table: + //Version Date Expert in charge Changes applied + //01.01.02 18.02.2020 (DI CS SD CSS KMT) Update of the released version V1.1.1 + //============================================================================= + + + #statLowerBoundSend:=LOWER_BOUND(ARR := #sendData, DIM := 1); + #statLowerBoundRcv:= LOWER_BOUND(ARR:=#rcvData, DIM:=1); + #statUpperBoundSend := UPPER_BOUND(ARR := #sendData, DIM := 1); + #statUpperBoundRcv := UPPER_BOUND(ARR := #rcvData, DIM := 1); + + REGION edgeDetection + + //evaluluate pos edge on input enable for connection establishment + #statEdgeCon := #enable AND NOT + #statEdgeConOld; + #statEdgeConOld := #enable; + + //evaluluate neg edge on input enable for connection termination + #statEdgeDiscon := NOT #enable AND + #statEdgeDisconOld; + #statEdgeDisconOld := #enable; + + //evaluluate pos edge on input sendRequest + #statEdgeSendReq := #sendRequest AND NOT + #statEdgeSendReqOld; + #statEdgeSendReqOld := #sendRequest; + + END_REGION + + REGION initStates // evaluates the correct init state due to the input parameters + + //establish connection to partner + IF (#statEdgeCon = true) + THEN + IF (#busy = false) + THEN + #busy := true; + #statStateValue := #STATE_PARAM; + ELSE + #statStatusId := #STATUS_ID_INT_ERROR; // internal initialization error + #statStatus := #ERR_COMM_NOT_STARTED; // 16#8101: communication not startet + #statStateValue := #STATE_ERROR; + END_IF; + END_IF; + + //If disconnect required, set state to STATE_DISCONNECT + IF (#statEdgeDiscon = true) + THEN + #statStateValue := #STATE_DISCONNECT; + END_IF; + + //If sendRequest is required and connection is established set state to STATE_SEND + IF ((#statEdgeSendReq = true) + AND (#statConActive = true)) + THEN + #statStateValue := #STATE_SEND; + END_IF; + + // Watchdog timer to supervise connection + #instTimer(IN := #statStartTimer, + PT := #CONST_WATCHDOG_TIME, + Q => #statStoppTimer, + ET => #statTimeRun); + + // Go to state STATE_DISCONNECT when watchdog timer expired during connection establishment. + IF (#statStoppTimer = true) + THEN + #error := false; + #statStartTimer := false; //reset watchdog timer + #statTimerEnd := true; // trigger watchdog timer is expired + #statStateValue := #STATE_DISCONNECT; //when watchdog timer is expired got to STATE_DISCONNECT for connection termination + END_IF; + + END_REGION + + REGION stateMachine // contains the state machine + // TCP/IP management + // This section manages all the states to handle the Open User Communication blocks in a coordinated state machine. + + CASE #statStateValue OF + #STATE_IDLE: // idle mode, waiting for events + + #busy := false; + #error := false; + #status := #CONST_WORD_0; + #statusID := #CONST_UINT_0; + #statStatus := #CONST_WORD_0; + #statStatusId := #CONST_UINT_0; + #ndr := false; + #done := false; + #rcvdLen := #CONST_UDINT_0; + #statRcvdLen := #CONST_UDINT_0; + #statRcvFrameLen := #CONST_DINT_0; + #connectionEstablished := false; + #statStartTimer := false; //reset watchdog timer + #instTcon.REQ := false; //stop all TCON activities + #instTdiscon.REQ := false; //stop all TDISCON activities + #instTrcv.EN_R := false; // stop all TRCV activities + #statSendActive := false; + + #STATE_PARAM: // read connection parameters from input + + #instTcon.REQ := false; //stop all TCON activities + #instTdiscon.REQ := false; //stop all TDISCON activities + #instTrcv.EN_R := false; // stop all TRCV activities + #statTcpConnParam := #tcpConnParam; //connection parameters + #statConnID := #statTcpConnParam.ID; //unique connection ID + #statStateValue := #STATE_CONNECT; //set state machine to STATE_CONNECT + + #STATE_CONNECT: //establish connection + + REGION connect + + IF (#statConActive = false) //no active connection + THEN + #instTcon.REQ := true; //activate TCON block + #statStartTimer := true; //activate watchdog timer to supervise connection process + ELSIF (#statConActive = true) //connection already active + THEN + #statStateValue := #STATE_CONNECTED; //set state machine to STATE_CONNECTED + END_IF; + + IF ((#instTcon.DONE = TRUE) + AND (#instTcon.BUSY = FALSE)) //connection is established + THEN + #instTcon.REQ := false; + #statStartTimer := false; //reset watchdog timer + #statConActive := true; //conenction is active + ELSIF (#instTcon.ERROR = true) //error on establishing Tcp connection + THEN + //prepare error location information + #instTcon.REQ := false; + #statStatusId := #STATUS_ID_CON; //error occurred while establishing connection + #statStatus := #instTcon.STATUS; //error code from OUC block TCON + #statStateValue := #STATE_ERROR; // set state machine to STATE_ERROR while connection establishment + END_IF; + + END_REGION + + #STATE_DISCONNECT: //disconnect connection + + REGION disconnect + + //TDISCON is activated: + IF ((#statConActive = true) //when disconnect is required by input enable=0 and conenction is active, + OR (#statConReEstablish = true) //before connection is re-established + OR (#statTimerEnd = true)) //when watch dog timer is expired + THEN + #instTdiscon.REQ := true; //activate TDISCON block + ELSIF (#statConActive = false) // connection is not active + THEN + #statStateValue := #STATE_IDLE; //go to STATE_IDLE because connection is not active + END_IF; + + IF (#instTdiscon.DONE = TRUE) + THEN + #instTdiscon.REQ := false; //conenction is disconnected + #statConActive := false; // connection isn`t active + #statConReEstablish := false; //reset trigger for connection termination before re-establishment + END_IF; + + IF (#instTdiscon.ERROR = true) //error on disconnecting Tcp connection + THEN + //prepare error location information + #instTdiscon.REQ := false; + #statStatus := #instTdiscon.STATUS; //error code from OUC block TDISCON + #statStatusId := #STATUS_ID_DISCON; //error occurred while disconnecting connection + #statStateValue := #STATE_ERROR; // set state machine to STATE_ERROR while connection termination + #statConReEstablish := false; //reset trigger for connection termination before re-establishment + END_IF; + + END_REGION + + #STATE_CONNECTED: //connection is successful established to partner + + REGION connected + // REGION connected + + #done := false; + #ndr := false; //reset output ndr=0 + #busy := true; + #rcvdLen := #CONST_UINT_0; // reset output rcvdLen=0; + #instTrcv.EN_R := true; //activate TRCV block for incoming telegrams + #connectionEstablished := NOT (#statPartnerDisconnected); + #statRcvdLenNotDetected := false; + + IF #adhocMode = TRUE + THEN + #statRcvLen := 0; + ELSIF #adhocMode=FALSE + THEN + #statRcvLen := #rcvLen; + END_IF; + + IF (#instTrcv.NDR = TRUE) //New Data Received + THEN + + IF #statCntNdr >= 50 + THEN + #statCntRecv := 0; + END_IF; + + #statCntNdr := #statCntNdr + 1; + + #statRcvdLen := #instTrcv.RCVD_LEN; // set output rcvdLen to the length of received data + #statRcvLenTest := #instTrcv.RCVD_LEN; + + #statStateValue := #STATE_RECEIVE; + + ELSIF (#instTrcv.ERROR = true) // error occurred on receiving data in block TRCV + THEN + //prepare error location information + #statStatusId := #STATUS_ID_RCV; //error occurred while receiving data + #statStatus := #instTrcv.STATUS; //error code from OUC block TRCV + #statStateValue := #STATE_ERROR; // set state machine to STATE_ERROR while receiving data + ELSE + #status := #CONST_WORD_0; + #statusID := #CONST_UINT_0; + #error := false; + #statPartnerDisconnected := false; + END_IF; + + END_REGION + + #STATE_SEND: //send data to partner + + REGION sendData + + + IF (#statSendActive = false) + THEN + #instTsend.REQ := true; //activate TSEND block + #statSendActive := true; //send job is active (no other request to sendRequest is possible) + END_IF; + + IF (#instTsend.DONE) // data send successfully + THEN + #statSendActive := false; // no send job active + #statStateValue := #STATE_CONNECTED; // set state to STATE_CONNECTED + #done := true; // send request is finished successfully + #busy := false; // set busy=false + ELSIF #instTsend.ERROR = true //error on send data + THEN + //prepare error location information + #statSendActive := false; + #statStatusId := #STATUS_ID_SEND; //error occurred while sending data + #statStatus := #instTsend.STATUS; //error code from OUC block TSEND + #statStateValue := #STATE_ERROR; // set state machine to STATE_ERROR while sending data + END_IF; + + END_REGION + + #STATE_RECEIVE: + + REGION receiveData + + // handle here the received data individual for your purposes + // in this template received data is simply copied to paramter #rcvData + + // adhoc mode is activated + IF #adhocMode = TRUE + THEN + + IF #statLenDetected = FALSE + // THEN + // #statRcvDataLen.%B0 := #statDataBufferRcv[4]; + // #statRcvDataLen.%B1 := #statDataBufferRcv[3]; + // #statRcvDataLen.%B2 := #statDataBufferRcv[2]; + // #statRcvDataLen.%B3 := #statDataBufferRcv[1]; + + // IF (DWORD_TO_UDINT(#statRcvDataLen) >= #CONST_MIN_RCVD_DATA_LEN) + // AND (DWORD_TO_UDINT(#statRcvDataLen) <= #CONST_MAX_RCVD_DATA_LEN) + THEN + #statLenDetected := true; + #tempRetVal := MOVE_BLK_VARIANT(SRC := #statDataBufferRcv, + COUNT := #statRcvdLen, + SRC_INDEX := #CONST_DINT_0, + DEST_INDEX := #CONST_DINT_0, + DEST => #rcvData); + // ELSE + + // #rcvdLen := 0; + // #statRcvFrameLen := 0; + // #statRcvdLen := 0; + // #statRcvdLenNotDetected := true; + // END_IF; + + ELSE + + + #tempRetVal := MOVE_BLK_VARIANT(SRC := #statDataBufferRcv, + COUNT := #statRcvdLen, + SRC_INDEX := #CONST_DINT_0, + DEST_INDEX := #statRcvFrameLen, + DEST => #rcvData); + END_IF; + + + #statRcvFrameLen := #statRcvFrameLen + UDINT_TO_DINT(#statRcvdLen); + + IF (#statRcvFrameLen >= #statRcvDataLen) + AND (#statRcvdLenNotDetected = false) + THEN + #statRcvFrameLenSave := #statRcvFrameLen; + #rcvdLen := DINT_TO_UDINT(#statRcvFrameLen); + #statRcvFrameLen := 0; + #statRcvdLen := 0; + #statLenDetected := false; + #ndr := true; + END_IF; + + //adhoc mode is deactivated + ELSE + + #tempRetVal := MOVE_BLK_VARIANT(SRC := #statDataBufferRcv, + COUNT := #statRcvdLen, + SRC_INDEX := 0, + DEST_INDEX := 0, + DEST => #rcvData); + + + #ndr := true; + #rcvdLen := #statRcvdLen; + + END_IF; + + IF #statCntRecv >= 50 + THEN + #statCntRecv := 0; + END_IF; + + #statCntRecv := #statCntRecv + 1; + + + #statStateValue := #STATE_CONNECTED; + + + END_REGION + + #STATE_ERROR: // error handling + + REGION errorHandling + + //Error source: occurred in STATE_CONNECT - establishing connection + IF (#statStatusId = #STATUS_ID_CON) + THEN + + // re-establishment of connection nesccessary when: + IF ((#statStatus = #ERR_COMM_ID_IN_USE) //16#80A3 ID is used by a connection created by the user program, which uses the same connection description at the CONNECT parameter. + OR (#statStatus = #ERR_COMM_TCON_NOT_COMPLETED)) // 16#80A7 Communication error: You executed "TDISCON" before "TCON" had completed. + THEN + #statConReEstablish := true; //trigger for re-establishment + #statStateValue := #STATE_DISCONNECT; // set state to STATE_DISCONNECT for connection termination before re-establishment + + // go to STATE_CONNECT again, when client isn`t connected + //16#80C5: connection partner refuses to establish connection or terminated connection actively. + ELSIF (#statStatus = #ERR_COMM_PARTNER_TERMINATE_CONNETION) + THEN + #statStateValue := #STATE_CONNECT; // set state to STATE_CONNECT + #statErrorIntern := true; + ELSE + #statStateValue := #STATE_IDLE; //set state to STATE_IDLE in any other error cases and wait for new user events + END_IF; + + //Error source: occurred in STATE_DISCONNECT - disconnecting connection + ELSIF (#statStatusId = #STATUS_ID_DISCON) + THEN + + IF (#statStatus = #ERR_COMM_CONNECTION_NOT_EXIST) // 16#80A3 Connection doesn`t exist or isn`t established + THEN + + //When watchdog timer is expired connection isn`t established. TDISCON shows status 16#80A3. + //In this case change error location information + IF (#statTimerEnd = TRUE) + THEN + #statTimerEnd := false; //reset trigger watchdog timer expired + #statStatusId := #STATUS_ID_INT_ERROR; //internal error + #statStatus := #ERR_WATCHDOG_TIMER; //16#8102 watchdog timer is expired + END_IF; + + #statConActive := false; //no active connection + #statStateValue := #STATE_IDLE; //When status 16#80A3 isn`t cause by watchdog timmer go to STATE_IDLE + ELSE + #statStateValue := #STATE_DISCONNECT; // in any other error cases go to STATE_DISCONNECT for connection termination + END_IF; + + //Error source: occurred in STATE_CONNECTED - receive new data + ELSIF #statStatusId = #STATUS_ID_RCV + THEN + + // connection is terminated or temporary communication error + IF ((#statStatus = #ERR_COMM_TEMP) + OR (#statStatus = #ERR_COMM_CONNECTION_TERMINATED)) + THEN + + IF (#enable = true) //when input enable = true partner has terminated the connection + THEN + #statPartnerDisconnected := true; // trigger that partner has disconnected the connection + #statErrorIntern := true; // Trigger internal Error -> no action by user neccessary + #statStateValue := #STATE_CONNECTED; // when partner has terminated connection stay in STATE_CONNECTED and wait for the partner + ELSE // connection termination was required via input enable = 0 + #statStateValue := #STATE_IDLE; // set state to IDLE_STATE + END_IF; + + // The partner has disconnected + ELSIF (#statStatus = #ERR_COMM_PARTNER_TERMINATE_CONNETION) + THEN + #statPartnerDisconnected := true; // trigger that partner has disconnected the connection + #statErrorIntern := true; // Trigger internal Error -> no action by user neccessary + #statStateValue := #STATE_CONNECTED; // when partner has terminated connection stay in STATE_CONNECTED and wait for the partner + + ELSE //any other error cases + #statStateValue := #STATE_DISCONNECT; //set state to STATE_DISCONNECT for connection termination + END_IF; + + ELSIF (#statStatusId = #STATUS_ID_SEND) //Error source: occurred in STATE_SEND - send data + THEN + // connection is terminated or temporary communication error + IF ((#statStatus = #ERR_COMM_TEMP) + OR (#statStatus = #ERR_COMM_CONNECTION_TERMINATED)) + THEN + + IF (#enable = true) //when input enable = true partner has terminated the connection + THEN + #statPartnerDisconnected := true; //when input enable = true partner has terminated the connection + #statErrorIntern := true; // Trigger internal Error -> no action by user neccessary + #statStateValue := #STATE_CONNECTED; // when partner has terminated connection stay in STATE_CONNECTED and wait for the partner + ELSE // connection termination was required via input enable = 0 + #statStateValue := #STATE_IDLE; // set state to IDLE_STATE + END_IF; + + // The partner has disconnected + ELSIF (#statStatus = #ERR_COMM_PARTNER_TERMINATE_CONNETION) + THEN + #statPartnerDisconnected := true; //when input enable = true partner has terminated the connection + #statErrorIntern := true; // Trigger internal Error -> no action by user neccessary + #statStateValue := #STATE_CONNECTED; // when partner has terminated connection stay in STATE_CONNECTED and wait for the partner + ELSE //any other error cases + #statStateValue := #STATE_DISCONNECT; //set state to STATE_DISCONNECT for connection termination + END_IF; + + ELSIF (#statStatusId = #STATUS_ID_INT_ERROR) + THEN + #statStateValue:=#STATE_IDLE; + END_IF; + + //set output parameters + IF (#statErrorIntern = true) // internal error (no activity by the user neccessary) + THEN + #statErrorIntern := false; + #busy := true; // do not reset the output busy (FB works) + ELSE //other error cases + #busy := false; //reset output #busy (FB doesn't works) + END_IF; + + #status := #statStatus; + #statusID := #statStatusId; + #error := true; + + END_REGION + + ELSE // Statement section ELSE + #statStateValue := #STATE_IDLE; + END_CASE; + + END_REGION + + REGION callOUCBlocks // call of all OUC blocks + + // TCON + #instTcon(ID := #statConnID, + CONNECT := #statTcpConnParam); + + // TDISCON + #instTdiscon(ID := #statConnID); + + // TRCV + #instTrcv(ID := #statConnID, + ADHOC := #adhocMode, + LEN := #statRcvLen, + DATA := #statDataBufferRcv); + + //TSEND + #instTsend(ID := #statConnID, + LEN := #sendLen, + DATA := #sendData); + + #instTsend.REQ := false; + + END_REGION +END_FUNCTION_BLOCK + diff --git a/1_BaseSystemLib/170_Communications/TCP/TeleHandler/FB_EventLog_Root.libinfo b/1_BaseSystemLib/170_Communications/TCP/TeleHandler/FB_EventLog_Root.libinfo new file mode 100644 index 0000000..87b89cb --- /dev/null +++ b/1_BaseSystemLib/170_Communications/TCP/TeleHandler/FB_EventLog_Root.libinfo @@ -0,0 +1,10 @@ +LibraryType: + Guid: 507f060d-3ada-4f0d-be55-ad0a573f4197 + Comment: + de-DE: Logging integriert +LibraryVersion: + VersionNumber: 0.0.14 + Author: t.schiller + IsDefault: true + Comment: + de-DE: Logging integriert diff --git a/1_BaseSystemLib/170_Communications/TCP/TeleHandler/FB_EventLog_Root.libint b/1_BaseSystemLib/170_Communications/TCP/TeleHandler/FB_EventLog_Root.libint new file mode 100644 index 0000000..d607a28 --- /dev/null +++ b/1_BaseSystemLib/170_Communications/TCP/TeleHandler/FB_EventLog_Root.libint @@ -0,0 +1,13 @@ +DocumentHash: + - FileName: FB_EventLog_Root.scl + Hash: dYC6DBRTM3y/UqKlq9GtiXf0RMqTdz95JqM4YR4MH4I= +LibraryMetaFileHash: Z07lDSYlhb8WZYii7fMbAe/9XKI4zUKNS6ioRRiae8s= +LibraryVersion: + Guid: 0eb2e25d-8a3e-4933-a967-d5e3f0e48bb4 + DependsOn: + - TypeName: FC_DateAsString + VersionNumber: 0.0.14 + - TypeName: FC_TimeAsString + VersionNumber: 0.0.14 + - TypeName: FC_Loglevel_to_String + VersionNumber: 0.0.14 diff --git a/1_BaseSystemLib/170_Communications/TCP/TeleHandler/FB_EventLog_Root.scl b/1_BaseSystemLib/170_Communications/TCP/TeleHandler/FB_EventLog_Root.scl new file mode 100644 index 0000000..d82a260 --- /dev/null +++ b/1_BaseSystemLib/170_Communications/TCP/TeleHandler/FB_EventLog_Root.scl @@ -0,0 +1,57 @@ +FUNCTION_BLOCK "FB_EventLog_Root" +{ S7_Optimized_Access := 'TRUE' } +VERSION : 0.1 + VAR_INPUT + xInTrigger : Bool; + sInInstance : String[50]; // he instance that called the function - see Beckhoff {attribute 'instance-path'} or library example project for how to retrieve this automatically. + nInLogLevel : Int; + sInMessage : String; + END_VAR + + VAR + fbProgram_Alarm {InstructionName := 'Program_Alarm'; LibVersion := '1.0'} : Program_Alarm; + wStatus : Word; + xTriggerFlag : Bool; + END_VAR + + VAR_TEMP + xError : Bool; + sLogMessage : String; + xLogEnable : Bool; + END_VAR + + VAR CONSTANT + cSeperationChar : String := ';'; + END_VAR + + +BEGIN + //#sInInstanceName := GetInstancePath(size:=1); + #xLogEnable := #nInLogLevel <= "DB_MachineGlobal".nLogLevel; + REGION Meldetext + IF #xInTrigger AND NOT #xTriggerFlag THEN + #sLogMessage := CONCAT_STRING(IN1 := "FC_DateAsString"(), + IN2 := #cSeperationChar, + IN3 := "FC_TimeAsString"(), + IN4 := #cSeperationChar, + IN5 := "FC_Loglevel_to_String"(#nInLogLevel), + IN6 := #cSeperationChar, + IN7 := #sInInstance, + IN8 := #cSeperationChar, + IN9 := #sInMessage); + END_IF; + END_REGION + + REGION Program Alarm + #fbProgram_Alarm(SIG := #xInTrigger AND NOT #xTriggerFlag AND #xLogEnable, + SD_1 := #sLogMessage, + Status => #wStatus, + Error => #xError); + END_REGION + + + REGION Flanken + #xTriggerFlag := #xInTrigger; + END_REGION +END_FUNCTION_BLOCK + diff --git a/1_BaseSystemLib/170_Communications/TCP/TeleHandler/FC_DateAsString.libinfo b/1_BaseSystemLib/170_Communications/TCP/TeleHandler/FC_DateAsString.libinfo new file mode 100644 index 0000000..289b719 --- /dev/null +++ b/1_BaseSystemLib/170_Communications/TCP/TeleHandler/FC_DateAsString.libinfo @@ -0,0 +1,10 @@ +LibraryType: + Guid: ec1c1f34-0a2d-4751-84a8-f9c4ee84884b + Comment: + de-DE: Logging integriert +LibraryVersion: + VersionNumber: 0.0.14 + Author: t.schiller + IsDefault: true + Comment: + de-DE: Logging integriert diff --git a/1_BaseSystemLib/170_Communications/TCP/TeleHandler/FC_DateAsString.libint b/1_BaseSystemLib/170_Communications/TCP/TeleHandler/FC_DateAsString.libint new file mode 100644 index 0000000..040de0c --- /dev/null +++ b/1_BaseSystemLib/170_Communications/TCP/TeleHandler/FC_DateAsString.libint @@ -0,0 +1,6 @@ +DocumentHash: + - FileName: FC_DateAsString.scl + Hash: sxW9MGlJNzQwHlUucUIrXWLqFFj9XVJTFDBvIpZg2Qs= +LibraryMetaFileHash: wzQfhgpRB7r0PHMXGTocBFU9yvk1Vr0feBlk7pR9Mcs= +LibraryVersion: + Guid: 4adee4de-c703-4794-9700-da57684c5c9f diff --git a/1_BaseSystemLib/170_Communications/TCP/TeleHandler/FC_DateAsString.scl b/1_BaseSystemLib/170_Communications/TCP/TeleHandler/FC_DateAsString.scl new file mode 100644 index 0000000..40fd7d6 --- /dev/null +++ b/1_BaseSystemLib/170_Communications/TCP/TeleHandler/FC_DateAsString.scl @@ -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 + diff --git a/1_BaseSystemLib/170_Communications/TCP/TeleHandler/FC_Loglevel_to_String.libinfo b/1_BaseSystemLib/170_Communications/TCP/TeleHandler/FC_Loglevel_to_String.libinfo new file mode 100644 index 0000000..efbd238 --- /dev/null +++ b/1_BaseSystemLib/170_Communications/TCP/TeleHandler/FC_Loglevel_to_String.libinfo @@ -0,0 +1,10 @@ +LibraryType: + Guid: ecdcb816-c5f6-4500-b05f-1b5b1f79ef0b + Comment: + de-DE: Logging integriert +LibraryVersion: + VersionNumber: 0.0.14 + Author: t.schiller + IsDefault: true + Comment: + de-DE: Logging integriert diff --git a/1_BaseSystemLib/170_Communications/TCP/TeleHandler/FC_Loglevel_to_String.libint b/1_BaseSystemLib/170_Communications/TCP/TeleHandler/FC_Loglevel_to_String.libint new file mode 100644 index 0000000..f188b10 --- /dev/null +++ b/1_BaseSystemLib/170_Communications/TCP/TeleHandler/FC_Loglevel_to_String.libint @@ -0,0 +1,6 @@ +DocumentHash: + - FileName: FC_Loglevel_to_String.scl + Hash: 0nOn7U6FrudaUAoJ0lbC3MqMbfsVeEOSIk31dwrXw8U= +LibraryMetaFileHash: pC45QV67Xh2HrolPKgzDv3+YCEc3tG189rMarPR4Ym8= +LibraryVersion: + Guid: 85d69f29-f857-4428-90a9-872b80e36573 diff --git a/1_BaseSystemLib/170_Communications/TCP/TeleHandler/FC_Loglevel_to_String.scl b/1_BaseSystemLib/170_Communications/TCP/TeleHandler/FC_Loglevel_to_String.scl new file mode 100644 index 0000000..ee105ab --- /dev/null +++ b/1_BaseSystemLib/170_Communications/TCP/TeleHandler/FC_Loglevel_to_String.scl @@ -0,0 +1,25 @@ +FUNCTION "FC_Loglevel_to_String" : String +{ S7_Optimized_Access := 'TRUE' } +VERSION : 0.1 + VAR_INPUT + nLogLevel : Int; + END_VAR + + +BEGIN + CASE #nLogLevel OF + "E_LogLevel.DEBUG": + #FC_Loglevel_to_String := 'DEBUG'; + "E_LogLevel.ERROR": + #FC_Loglevel_to_String := 'ERROR'; + "E_LogLevel.INFO": + #FC_Loglevel_to_String := 'INFO'; + "E_LogLevel.INT_ERROR": + #FC_Loglevel_to_String := 'INT_ERROR'; + "E_LogLevel.WARNING": + #FC_Loglevel_to_String := 'WARNING'; + ELSE + #FC_Loglevel_to_String := 'UNKNOWN'; + END_CASE; +END_FUNCTION + diff --git a/1_BaseSystemLib/170_Communications/TCP/TeleHandler/FC_TimeAsString.libinfo b/1_BaseSystemLib/170_Communications/TCP/TeleHandler/FC_TimeAsString.libinfo new file mode 100644 index 0000000..213d32d --- /dev/null +++ b/1_BaseSystemLib/170_Communications/TCP/TeleHandler/FC_TimeAsString.libinfo @@ -0,0 +1,10 @@ +LibraryType: + Guid: e790056b-d8d1-47bb-bce9-c6e26c157eec + Comment: + de-DE: Logging integriert +LibraryVersion: + VersionNumber: 0.0.14 + Author: t.schiller + IsDefault: true + Comment: + de-DE: Logging integriert diff --git a/1_BaseSystemLib/170_Communications/TCP/TeleHandler/FC_TimeAsString.libint b/1_BaseSystemLib/170_Communications/TCP/TeleHandler/FC_TimeAsString.libint new file mode 100644 index 0000000..63c5f04 --- /dev/null +++ b/1_BaseSystemLib/170_Communications/TCP/TeleHandler/FC_TimeAsString.libint @@ -0,0 +1,6 @@ +DocumentHash: + - FileName: FC_TimeAsString.scl + Hash: 3WJUl9RFht2vorDlH8QAIOs7AhSUh8JVzkcdrRKQwZo= +LibraryMetaFileHash: 4RB0ELjNFkABN8RO9ZmmvbU+HNP4H+TccEh5oYuI2rI= +LibraryVersion: + Guid: 36b9f032-4747-42aa-b87f-9637f121af9c diff --git a/1_BaseSystemLib/170_Communications/TCP/TeleHandler/FC_TimeAsString.scl b/1_BaseSystemLib/170_Communications/TCP/TeleHandler/FC_TimeAsString.scl new file mode 100644 index 0000000..cb2a4e0 --- /dev/null +++ b/1_BaseSystemLib/170_Communications/TCP/TeleHandler/FC_TimeAsString.scl @@ -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 + diff --git a/1_BaseSystemLib/170_Communications/TCP/TeleHandler/Parser/FC_ParseCheckForEnd.libinfo b/1_BaseSystemLib/170_Communications/TCP/TeleHandler/Parser/FC_ParseCheckForEnd.libinfo new file mode 100644 index 0000000..a91c334 --- /dev/null +++ b/1_BaseSystemLib/170_Communications/TCP/TeleHandler/Parser/FC_ParseCheckForEnd.libinfo @@ -0,0 +1,8 @@ +LibraryType: + Guid: 7462bbc8-2811-4b0d-bdf1-031a6aa286ee +LibraryVersion: + VersionNumber: 0.0.6 + Author: e.yueksel + IsDefault: true + Comment: + de-DE: Inkonsistenz bereinigen diff --git a/1_BaseSystemLib/170_Communications/TCP/TeleHandler/Parser/FC_ParseCheckForEnd.libint b/1_BaseSystemLib/170_Communications/TCP/TeleHandler/Parser/FC_ParseCheckForEnd.libint new file mode 100644 index 0000000..9901f30 --- /dev/null +++ b/1_BaseSystemLib/170_Communications/TCP/TeleHandler/Parser/FC_ParseCheckForEnd.libint @@ -0,0 +1,9 @@ +DocumentHash: + - FileName: FC_ParseCheckForEnd.scl + Hash: 9/ZVb2UiTOhclEguONKnCzWJfK1tn9Z9sOJsqztg35M= +LibraryMetaFileHash: l4eOdmK051pj+qL8jJiaNVxTNzEGtoXFkqzf7GlEhpQ= +LibraryVersion: + Guid: c0b69439-324f-4624-bfa7-02fc724e52f7 + DependsOn: + - TypeName: UDT_TelegramDefinition + VersionNumber: 0.0.5 diff --git a/1_BaseSystemLib/170_Communications/TCP/TeleHandler/Parser/FC_ParseCheckForEnd.scl b/1_BaseSystemLib/170_Communications/TCP/TeleHandler/Parser/FC_ParseCheckForEnd.scl new file mode 100644 index 0000000..f400cb7 --- /dev/null +++ b/1_BaseSystemLib/170_Communications/TCP/TeleHandler/Parser/FC_ParseCheckForEnd.scl @@ -0,0 +1,44 @@ +FUNCTION "FC_ParseCheckForEnd" : Bool +TITLE = FC_ParseCheckForEnd +{ S7_Optimized_Access := 'TRUE' } +AUTHOR : 'e.yueksel' +FAMILY : Parser +VERSION : 0.1 +//Diese Baustein überprüft neue Telegramme auf Endekennung entsprechend der Telegrammdefinition. + VAR_INPUT + bInNewData : Byte; // The byte we compare to the end marker + arInBuffer : Array[*] of Byte; // The buffer (Array of bytes) we are currently parsing + nInBufferLen : DInt; // Length of the buffer + stInTelegramDefinition : "UDT_TelegramDefinition"; // The definition of the telegram (Parameters) + END_VAR + + VAR_TEMP + j : DInt; // Loop variable + END_VAR + + +BEGIN + IF (#stInTelegramDefinition.nEndMarkerLen > 0) THEN + IF (#bInNewData = #stInTelegramDefinition.sEndMarker[#stInTelegramDefinition.nEndMarkerLen] AND + #nInBufferLen >= UDINT_TO_DINT(#stInTelegramDefinition.nStartMarkerLen + #stInTelegramDefinition.nEndMarkerLen)) THEN + FOR #j := 0 TO UDINT_TO_DINT(#stInTelegramDefinition.nEndMarkerLen - 1) DO + IF (#arInBuffer[#nInBufferLen - 1 - #j] <> #stInTelegramDefinition.sEndMarker[UDINT_TO_DINT(#stInTelegramDefinition.nEndMarkerLen) - #j]) THEN + #FC_ParseCheckForEnd := FALSE; + RETURN; + END_IF; + END_FOR; + + IF (#stInTelegramDefinition.nLength > 0) THEN + #FC_ParseCheckForEnd := (#nInBufferLen = UDINT_TO_DINT(#stInTelegramDefinition.nLength)); + ELSE + #FC_ParseCheckForEnd := TRUE; + END_IF; + ELSE + #FC_ParseCheckForEnd := FALSE; + END_IF; + ELSE + #FC_ParseCheckForEnd := (#nInBufferLen = UDINT_TO_DINT(#stInTelegramDefinition.nLength)); + END_IF; + +END_FUNCTION + diff --git a/1_BaseSystemLib/170_Communications/TCP/TeleHandler/Parser/FC_ParseCheckForStart.libinfo b/1_BaseSystemLib/170_Communications/TCP/TeleHandler/Parser/FC_ParseCheckForStart.libinfo new file mode 100644 index 0000000..851c434 --- /dev/null +++ b/1_BaseSystemLib/170_Communications/TCP/TeleHandler/Parser/FC_ParseCheckForStart.libinfo @@ -0,0 +1,8 @@ +LibraryType: + Guid: 9058dc9e-b9e7-4405-8e1d-e48b9273bd5f +LibraryVersion: + VersionNumber: 0.0.6 + Author: e.yueksel + IsDefault: true + Comment: + de-DE: Inkonsistenz bereinigen diff --git a/1_BaseSystemLib/170_Communications/TCP/TeleHandler/Parser/FC_ParseCheckForStart.libint b/1_BaseSystemLib/170_Communications/TCP/TeleHandler/Parser/FC_ParseCheckForStart.libint new file mode 100644 index 0000000..9986ede --- /dev/null +++ b/1_BaseSystemLib/170_Communications/TCP/TeleHandler/Parser/FC_ParseCheckForStart.libint @@ -0,0 +1,9 @@ +DocumentHash: + - FileName: FC_ParseCheckForStart.scl + Hash: 9k9Nch0mhI2FlPOZygpnN+PfrnpwH9iV2hqhIx8frpQ= +LibraryMetaFileHash: RvU2tTT+yCMb2ZwWGKDCVMASSZnGv/yIPXb59NkUwLY= +LibraryVersion: + Guid: 592d2c58-e2fc-4ba6-a0b2-d15ffd39706c + DependsOn: + - TypeName: UDT_TelegramDefinition + VersionNumber: 0.0.5 diff --git a/1_BaseSystemLib/170_Communications/TCP/TeleHandler/Parser/FC_ParseCheckForStart.scl b/1_BaseSystemLib/170_Communications/TCP/TeleHandler/Parser/FC_ParseCheckForStart.scl new file mode 100644 index 0000000..39395d6 --- /dev/null +++ b/1_BaseSystemLib/170_Communications/TCP/TeleHandler/Parser/FC_ParseCheckForStart.scl @@ -0,0 +1,39 @@ +FUNCTION "FC_ParseCheckForStart" : Bool +TITLE = FC_ParseCheckForStart +{ S7_Optimized_Access := 'TRUE' } +AUTHOR : 'e.yueksel' +FAMILY : Parser +VERSION : 0.1 +//Diese Baustein überprüft neue Telegramme auf Anfangskennung entsprechend der Telegrammdefinition. + VAR_INPUT + bInNewData : Byte; // The byte we compare to the Start marker + arInBuffer : Array[*] of Byte; // The buffer (Array of bytes) we are parsing + nInBufferLen : DInt; // Length of the buffer + stInTelegramDefinition : "UDT_TelegramDefinition"; // The definition of the telegram (Parameters) + END_VAR + + VAR_TEMP + j : DInt; // Loop variable + END_VAR + + +BEGIN + IF (#stInTelegramDefinition.nStartMarkerLen > 0) THEN + IF (#bInNewData = #stInTelegramDefinition.sStartMarker[#stInTelegramDefinition.nStartMarkerLen] AND + (#nInBufferLen >= UDINT_TO_DINT(#stInTelegramDefinition.nStartMarkerLen))) THEN + FOR #j := 0 TO UDINT_TO_DINT(#stInTelegramDefinition.nStartMarkerLen - 1) DO + IF (#arInBuffer[#nInBufferLen -1 - #j] <> #stInTelegramDefinition.sStartMarker[UDINT_TO_DINT(#stInTelegramDefinition.nStartMarkerLen)-#j]) THEN + #FC_ParseCheckForStart := FALSE; + RETURN; + END_IF; + END_FOR; + + #FC_ParseCheckForStart := TRUE; + ELSE + #FC_ParseCheckForStart := FALSE; + END_IF; + ELSE + #FC_ParseCheckForStart := FALSE; // In case there is no start pattern specified, the parser state machine recognizes the telegram start itself regarding to its state. + END_IF; +END_FUNCTION + diff --git a/1_BaseSystemLib/170_Communications/TCP/TeleHandler/Telegram/FC_TeleAddDataField.libinfo b/1_BaseSystemLib/170_Communications/TCP/TeleHandler/Telegram/FC_TeleAddDataField.libinfo new file mode 100644 index 0000000..43ad96d --- /dev/null +++ b/1_BaseSystemLib/170_Communications/TCP/TeleHandler/Telegram/FC_TeleAddDataField.libinfo @@ -0,0 +1,10 @@ +LibraryType: + Guid: 9e889e59-adc4-4817-8885-2d408e4ff768 + Comment: + de-DE: This function adds a data field to the specified telegram structure. +LibraryVersion: + VersionNumber: 0.0.9 + Author: e.yueksel + IsDefault: true + Comment: + de-DE: Inkonsistenzen bereinigen diff --git a/1_BaseSystemLib/170_Communications/TCP/TeleHandler/Telegram/FC_TeleAddDataField.libint b/1_BaseSystemLib/170_Communications/TCP/TeleHandler/Telegram/FC_TeleAddDataField.libint new file mode 100644 index 0000000..533433e --- /dev/null +++ b/1_BaseSystemLib/170_Communications/TCP/TeleHandler/Telegram/FC_TeleAddDataField.libint @@ -0,0 +1,9 @@ +DocumentHash: + - FileName: FC_TeleAddDataField.scl + Hash: 63DCFc6AOKpwg1krHbJjA5Tz/waL4QqqsZvV9AMenTU= +LibraryMetaFileHash: G0WbKZtqy7nLffNAddkbfu3qRl0eIzYFamjIKGv99uQ= +LibraryVersion: + Guid: 6be99168-8a2f-46e7-a409-2f15f6e67651 + DependsOn: + - TypeName: UDT_TelegramData_Send + VersionNumber: 0.0.7 diff --git a/1_BaseSystemLib/170_Communications/TCP/TeleHandler/Telegram/FC_TeleAddDataField.scl b/1_BaseSystemLib/170_Communications/TCP/TeleHandler/Telegram/FC_TeleAddDataField.scl new file mode 100644 index 0000000..5ff78e1 --- /dev/null +++ b/1_BaseSystemLib/170_Communications/TCP/TeleHandler/Telegram/FC_TeleAddDataField.scl @@ -0,0 +1,27 @@ +FUNCTION "FC_TeleAddDataField" : Bool +{ S7_Optimized_Access := 'TRUE' } +VERSION : 0.1 + VAR_INPUT + sData : String; // The data field string to be added to the telegram structure. + END_VAR + + VAR_IN_OUT + stInOutTelegram : "UDT_TelegramData_Send"; // The telegram structure the data field has to be added to. + END_VAR + + +BEGIN + IF (#stInOutTelegram.nDataCount < "TELEGRAM_DATA_MAX") THEN + IF (#stInOutTelegram.nDataCount < 0) THEN + #stInOutTelegram.nDataCount := 0; + END_IF; + + #stInOutTelegram.nDataCount := #stInOutTelegram.nDataCount + 1; + #stInOutTelegram.arDataString[#stInOutTelegram.nDataCount] := #sData; + + #FC_TeleAddDataField := TRUE; + ELSE + #FC_TeleAddDataField := FALSE; + END_IF; +END_FUNCTION + diff --git a/1_BaseSystemLib/170_Communications/TCP/TeleHandler/Telegram/FC_TeleClear.libinfo b/1_BaseSystemLib/170_Communications/TCP/TeleHandler/Telegram/FC_TeleClear.libinfo new file mode 100644 index 0000000..91339a6 --- /dev/null +++ b/1_BaseSystemLib/170_Communications/TCP/TeleHandler/Telegram/FC_TeleClear.libinfo @@ -0,0 +1,10 @@ +LibraryType: + Guid: 272019d6-a5d4-42eb-ab50-ec388ffd3f94 + Comment: + de-DE: Clears all data from a telegram structure. +LibraryVersion: + VersionNumber: 0.0.9 + Author: e.yueksel + IsDefault: true + Comment: + de-DE: Inkonsistenz bereinigen diff --git a/1_BaseSystemLib/170_Communications/TCP/TeleHandler/Telegram/FC_TeleClear.libint b/1_BaseSystemLib/170_Communications/TCP/TeleHandler/Telegram/FC_TeleClear.libint new file mode 100644 index 0000000..03080fa --- /dev/null +++ b/1_BaseSystemLib/170_Communications/TCP/TeleHandler/Telegram/FC_TeleClear.libint @@ -0,0 +1,9 @@ +DocumentHash: + - FileName: FC_TeleClear.scl + Hash: hEY0IFNekUPh+kWKDAoyWT+QezW7yIaW/5arbGJdFpo= +LibraryMetaFileHash: EF4Y+gXJ2WtV4auuc+0dAkuvfHCj+O0RUGVJzamyNVU= +LibraryVersion: + Guid: 28843e37-741d-4597-b662-bf6665818a62 + DependsOn: + - TypeName: UDT_TelegramData_Send + VersionNumber: 0.0.7 diff --git a/1_BaseSystemLib/170_Communications/TCP/TeleHandler/Telegram/FC_TeleClear.scl b/1_BaseSystemLib/170_Communications/TCP/TeleHandler/Telegram/FC_TeleClear.scl new file mode 100644 index 0000000..a38c415 --- /dev/null +++ b/1_BaseSystemLib/170_Communications/TCP/TeleHandler/Telegram/FC_TeleClear.scl @@ -0,0 +1,34 @@ +FUNCTION "FC_TeleClear" : Void +{ S7_Optimized_Access := 'TRUE' } +VERSION : 0.1 + VAR_IN_OUT + stInOutTelegram : "UDT_TelegramData_Send"; // The telegram structure that will be cleared + END_VAR + + VAR_TEMP + i : DInt; // Loop-Variable + j : DInt; // Loop-Variable + k : DInt; // Loop-Variable + END_VAR + + +BEGIN + #stInOutTelegram.sIDString := ''; + #stInOutTelegram.nID := 0; + #stInOutTelegram.xCRC32ValidationResult := FALSE; + + // FOR #i := 1 TO "TELEGRAM_DATA_MAX" DO + // FOR #j := 1 TO "TELEGRAM_DATA_FIELD_MAX" DO + // #stInOutTelegram.arData[#i, #j] := 0; + // END_FOR; + // END_FOR; + + + FOR #k := 1 TO "TELEGRAM_DATA_MAX" DO + #stInOutTelegram.arDataString[#k] := ''; + END_FOR; + + #stInOutTelegram.nDataCount := 1; + +END_FUNCTION + diff --git a/1_BaseSystemLib/170_Communications/TCP/TeleHandler/Telegram/FC_TeleSetData.libinfo b/1_BaseSystemLib/170_Communications/TCP/TeleHandler/Telegram/FC_TeleSetData.libinfo new file mode 100644 index 0000000..abec9ed --- /dev/null +++ b/1_BaseSystemLib/170_Communications/TCP/TeleHandler/Telegram/FC_TeleSetData.libinfo @@ -0,0 +1,10 @@ +LibraryType: + Guid: 99766d0f-bd08-454b-9e46-328d2cb77a29 + Comment: + de-DE: Function for setting specific data fields in a telegram +LibraryVersion: + VersionNumber: 0.0.9 + Author: e.yueksel + IsDefault: true + Comment: + de-DE: Inkonsistenz bereinigen diff --git a/1_BaseSystemLib/170_Communications/TCP/TeleHandler/Telegram/FC_TeleSetData.libint b/1_BaseSystemLib/170_Communications/TCP/TeleHandler/Telegram/FC_TeleSetData.libint new file mode 100644 index 0000000..c47204a --- /dev/null +++ b/1_BaseSystemLib/170_Communications/TCP/TeleHandler/Telegram/FC_TeleSetData.libint @@ -0,0 +1,9 @@ +DocumentHash: + - FileName: FC_TeleSetData.scl + Hash: wbtLBqYtEiaMEj2GtP61PV9zGa+soXeltzAIYTqOOLI= +LibraryMetaFileHash: EOKSC9YV8b05PN8z3LARS3fY6EjohMYHJjagmgMXWfA= +LibraryVersion: + Guid: 60db9e8b-a41d-46fc-a29c-9293ce5b3b45 + DependsOn: + - TypeName: UDT_TelegramData_Send + VersionNumber: 0.0.7 diff --git a/1_BaseSystemLib/170_Communications/TCP/TeleHandler/Telegram/FC_TeleSetData.scl b/1_BaseSystemLib/170_Communications/TCP/TeleHandler/Telegram/FC_TeleSetData.scl new file mode 100644 index 0000000..c82bda9 --- /dev/null +++ b/1_BaseSystemLib/170_Communications/TCP/TeleHandler/Telegram/FC_TeleSetData.scl @@ -0,0 +1,27 @@ +FUNCTION "FC_TeleSetData" : Bool +{ S7_Optimized_Access := 'TRUE' } +VERSION : 0.1 + VAR_INPUT + nDataField : UDInt; // The number of the data field to be modified, starts with "1". + sData : String; // The string that overwrites the existing data field value. + END_VAR + + VAR_IN_OUT + stInOutTelegram : "UDT_TelegramData_Send"; // The telegram structure that contains the data field to be modified. + END_VAR + + +BEGIN + IF (#nDataField >= 1 AND UDINT_TO_DINT(#nDataField) <= "TELEGRAM_DATA_MAX") THEN + #stInOutTelegram.arDataString[#nDataField] := #sData; + + IF (#stInOutTelegram.nDataCount < UDINT_TO_DINT(#nDataField)) THEN + #stInOutTelegram.nDataCount := UDINT_TO_DINT(#nDataField); + END_IF; + + #FC_TeleSetData := TRUE; + ELSE + #FC_TeleSetData := FALSE; + END_IF; +END_FUNCTION + diff --git a/1_BaseSystemLib/170_Communications/TCP/UDT/UDT_TelegramData.libinfo b/1_BaseSystemLib/170_Communications/TCP/UDT/UDT_TelegramData.libinfo new file mode 100644 index 0000000..93f7943 --- /dev/null +++ b/1_BaseSystemLib/170_Communications/TCP/UDT/UDT_TelegramData.libinfo @@ -0,0 +1,8 @@ +LibraryType: + Guid: f88be0d9-1f28-4bcb-a5a1-4b77b0e34878 +LibraryVersion: + VersionNumber: 0.0.8 + Author: e.yueksel + IsDefault: true + Comment: + de-DE: Inkonsistenz bereinigen diff --git a/1_BaseSystemLib/170_Communications/TCP/UDT/UDT_TelegramData.libint b/1_BaseSystemLib/170_Communications/TCP/UDT/UDT_TelegramData.libint new file mode 100644 index 0000000..e94ec98 --- /dev/null +++ b/1_BaseSystemLib/170_Communications/TCP/UDT/UDT_TelegramData.libint @@ -0,0 +1,6 @@ +DocumentHash: + - FileName: UDT_TelegramData.xml + Hash: onl5A2ZBXD1Osb9HpyJYM94U0gKjCtdo5NXjCUPG6d4= +LibraryMetaFileHash: Oe4DDTrGKgyFYBb5byBV2S5tlyI6GYHDaPGbe9u0en4= +LibraryVersion: + Guid: 98b089a9-4b8e-4a6f-8a92-5ae5a1509c03 diff --git a/1_BaseSystemLib/170_Communications/TCP/UDT/UDT_TelegramData.xml b/1_BaseSystemLib/170_Communications/TCP/UDT/UDT_TelegramData.xml new file mode 100644 index 0000000..e406732 --- /dev/null +++ b/1_BaseSystemLib/170_Communications/TCP/UDT/UDT_TelegramData.xml @@ -0,0 +1,62 @@ + + + + + + +
+ + + Wenn es eine Telegramm-ID gibt, wird sie hier angezeigt (not implemented) + + + + + Telegramm-ID als Nummer, wenn diese in der Telegramm-Definition vorgesehen wurde (not implemented) + + + + + Wenn eine Validierung mit CRC32 im Telegramm implementiert ist, dann steht hier das Ergebnis (TRUE = erfolgreich, FALSE = nicht erfolgreich/ nicht definiert) + + + + + Die Telegrammdaten als Array of String. Jeder String entspricht einem Datenfeld. + + + + + Anzahl der Datenfelder. + + 1 + +
+
+ UDT_TelegramData + +
+ + + + + + de-DE + + + + + + + + + + de-DE + + + + + + +
+
\ No newline at end of file diff --git a/1_BaseSystemLib/170_Communications/TCP/UDT/UDT_TelegramData_Send.libinfo b/1_BaseSystemLib/170_Communications/TCP/UDT/UDT_TelegramData_Send.libinfo new file mode 100644 index 0000000..48bfa87 --- /dev/null +++ b/1_BaseSystemLib/170_Communications/TCP/UDT/UDT_TelegramData_Send.libinfo @@ -0,0 +1,6 @@ +LibraryType: + Guid: 8ba5f026-f6a4-48b6-99af-dc7e461fdb45 +LibraryVersion: + VersionNumber: 0.0.7 + Author: e.yueksel + IsDefault: true diff --git a/1_BaseSystemLib/170_Communications/TCP/UDT/UDT_TelegramData_Send.libint b/1_BaseSystemLib/170_Communications/TCP/UDT/UDT_TelegramData_Send.libint new file mode 100644 index 0000000..f57d531 --- /dev/null +++ b/1_BaseSystemLib/170_Communications/TCP/UDT/UDT_TelegramData_Send.libint @@ -0,0 +1,6 @@ +DocumentHash: + - FileName: UDT_TelegramData_Send.xml + Hash: BQpYkFSPgx9BESwMa3p6bcSG7B5zPwgblsfSmxuhoMM= +LibraryMetaFileHash: cHNawuU7EPzVTRSwJgxUEYciiM7gvcd4ltOMZa0wIIg= +LibraryVersion: + Guid: 03564d6e-8226-4e22-a3ea-f92edd06e200 diff --git a/1_BaseSystemLib/170_Communications/TCP/UDT/UDT_TelegramData_Send.xml b/1_BaseSystemLib/170_Communications/TCP/UDT/UDT_TelegramData_Send.xml new file mode 100644 index 0000000..2ac32a4 --- /dev/null +++ b/1_BaseSystemLib/170_Communications/TCP/UDT/UDT_TelegramData_Send.xml @@ -0,0 +1,86 @@ + + + + + + +
+ + + Wenn es eine Telegramm-ID gibt, wird sie hier angezeigt (not implemented) + + + + + Telegramm-ID als Nummer, wenn diese in der Telegramm-Definition vorgesehen wurde (not implemented) + + + + + Wenn eine Validierung mit CRC32 im Telegramm implementiert ist, dann steht hier das Ergebnis (TRUE = erfolgreich, FALSE = nicht erfolgreich/ nicht definiert) + + + + + Die Telegrammdaten als Array of String. Jeder String entspricht einem Datenfeld. + + + + + Anzahl der Datenfelder. + + 1 + +
+
+ UDT_TelegramData_Send + +
+ + + + + + de-DE + + + + + + en-US + + + + + + cs-CZ + + + + + + + + + + de-DE + + + + + + en-US + + + + + + cs-CZ + + + + + + +
+
\ No newline at end of file diff --git a/1_BaseSystemLib/170_Communications/TCP/UDT/UDT_TelegramDefinition.libinfo b/1_BaseSystemLib/170_Communications/TCP/UDT/UDT_TelegramDefinition.libinfo new file mode 100644 index 0000000..c1d8698 --- /dev/null +++ b/1_BaseSystemLib/170_Communications/TCP/UDT/UDT_TelegramDefinition.libinfo @@ -0,0 +1,8 @@ +LibraryType: + Guid: 1e3c4983-857e-4011-8c76-51027a08bc9f +LibraryVersion: + VersionNumber: 0.0.5 + Author: e.yueksel + IsDefault: true + Comment: + de-DE: Added string limitation for start and end markers diff --git a/1_BaseSystemLib/170_Communications/TCP/UDT/UDT_TelegramDefinition.libint b/1_BaseSystemLib/170_Communications/TCP/UDT/UDT_TelegramDefinition.libint new file mode 100644 index 0000000..547c7c9 --- /dev/null +++ b/1_BaseSystemLib/170_Communications/TCP/UDT/UDT_TelegramDefinition.libint @@ -0,0 +1,6 @@ +DocumentHash: + - FileName: UDT_TelegramDefinition.xml + Hash: 0cV/CYkCUk207NJBfTvndbGASucn+Kzead/vMTVLarM= +LibraryMetaFileHash: TDtZpXRWGqg0j67MMPtliOMgW6X9H+XAL8n1wjhMMGs= +LibraryVersion: + Guid: 2d1cc429-2c73-4e6c-80c3-aba5ed21dc9a diff --git a/1_BaseSystemLib/170_Communications/TCP/UDT/UDT_TelegramDefinition.xml b/1_BaseSystemLib/170_Communications/TCP/UDT/UDT_TelegramDefinition.xml new file mode 100644 index 0000000..1946e95 --- /dev/null +++ b/1_BaseSystemLib/170_Communications/TCP/UDT/UDT_TelegramDefinition.xml @@ -0,0 +1,101 @@ + + + + + + +
+ + + Start marker / Start pattern of the telegram + + + + + Length of the start marker + + + + + End marker / End pattern of the telegram + + + + + Length of the end marker + + + + + Start marker / Start pattern of the telegram (for sending) + + + + + Length of the start marker (for sending) + + + + + End marker / End pattern of the telegram (for sending) + + + + + Length of the end marker (for sending) + + + + + The byte, used for separation of telegram content + + + + + The length of the telegram including start and end byte or zero to ignore the setting (fixed telegram length) + + + + + The number of the data field that contains the telegram ID or zero to ignore the setting (Not implemented) + + + + + Indicates whether the telegram ID is a number. When this parameter is set to TRUE, the ID string will be converted automatically (Not implemented) + + + + + The number of the data field that contains the CRC32-Checksum or zero to ignore the setting + + +
+
+ UDT_TelegramDefinition + +
+ + + + + + de-DE + + + + + + + + + + de-DE + + + + + + +
+
\ No newline at end of file diff --git a/1_BaseSystemLib/180_Safety/FB_ESTOPhandling.libinfo b/1_BaseSystemLib/180_Safety/FB_ESTOPhandling.libinfo new file mode 100644 index 0000000..1122b37 --- /dev/null +++ b/1_BaseSystemLib/180_Safety/FB_ESTOPhandling.libinfo @@ -0,0 +1,10 @@ +LibraryType: + Guid: bd77b34d-de4a-4cf4-b3fa-6af27ab4f306 + Comment: + de-DE: Not-Halt Tableau (Bedientableu, Schaltschrank etc.) +LibraryVersion: + VersionNumber: 2.0.3 + Author: e.yueksel + IsDefault: true + Comment: + de-DE: Änderung im unterlagerten Baustein diff --git a/1_BaseSystemLib/180_Safety/FB_ESTOPhandling.libint b/1_BaseSystemLib/180_Safety/FB_ESTOPhandling.libint new file mode 100644 index 0000000..b7c3788 --- /dev/null +++ b/1_BaseSystemLib/180_Safety/FB_ESTOPhandling.libint @@ -0,0 +1,15 @@ +DocumentHash: + - FileName: FB_ESTOPhandling.scl + Hash: 2UgFnNm8OIDLo3SBJ8cEH/7qdYZlAAJS3jH8D7nujFM= +LibraryMetaFileHash: QM7e5sxaiJw/1EJ6DSbGLGAnZxqKngK9/td0eEavTc4= +LibraryVersion: + Guid: bde5a261-573a-4feb-b079-cd5359d14c09 + DependsOn: + - TypeName: FB_Blinker + VersionNumber: 2.0.0 + - TypeName: FB_Monitoring + VersionNumber: 2.0.5 + - TypeName: UDT_MainState + VersionNumber: 2.0.0 + - TypeName: UDT_Panel_EmergencyStop + VersionNumber: 2.0.0 diff --git a/1_BaseSystemLib/180_Safety/FB_ESTOPhandling.scl b/1_BaseSystemLib/180_Safety/FB_ESTOPhandling.scl new file mode 100644 index 0000000..748a8ff --- /dev/null +++ b/1_BaseSystemLib/180_Safety/FB_ESTOPhandling.scl @@ -0,0 +1,123 @@ +FUNCTION_BLOCK "FB_ESTOPhandling" +{ S7_Optimized_Access := 'TRUE' } +VERSION : 0.1 + VAR_INPUT + tInPeriodicTime : Time := T#500ms; // BlinkTime LED Output + sInAlarmFunction : String[20]; // Alarm Function Name + sInAlarmDevice : String[16]; // Alarm Prefix + sInAlarmSuffix : String[16]; // Alarm Suffix + sInAlarmMessage : String; // Alarm Message + xInAckReqLocal : Bool; // Info from F-CPU: ESTOP.ACK_REQ + xInEstopOkLocal : Bool; // Info from F-CPU: ESTOP.Q Safety is Enabled + xInAckReqGlobal : Bool; // Sum-Info from Local ESTOP + xInSafetyNotOkGlobal : Bool; // Sum-Info from Local ESTOP + xInMainCabinet : Bool := false; // Activate Main Cabinet and global reset + wInTextListId_Message : Word; + wInTextListId_Function : Word; + wInTextListId_Prefix : Word; + wInTextListId_Suffix : Word; + END_VAR + + VAR_OUTPUT + xOutLed : Bool; // PushButton LED Output + xOutSafetyNotOk : Bool; // Info Output for MainCabinet + xOutAckReq : Bool; // Info Output for MainCabinet + END_VAR + + VAR_IN_OUT + stInOutControlUnitCabinet : "UDT_MainState"; // MachineState of FB_StateMain + stInOutHmiEstopPanel : "UDT_Panel_EmergencyStop"; + END_VAR + + VAR + FB_Blinker : "FB_Blinker"; + fbMonitoringEStop : "FB_Monitoring"; + END_VAR + + +BEGIN + REGION Blinker + // #FB_Blinker(tInPeriodicTime := #tInPeriodicTime, + // xInActivate := 1); + END_REGION + + REGION Logic + + // Local + IF NOT #xInMainCabinet THEN + + IF NOT #xInEstopOkLocal AND #xInAckReqLocal THEN + // Button not pressed but not Acknowledged + #xOutLed := "Clock_1Hz"(* #FB_Blinker.xOutput *); + #xOutSafetyNotOk := FALSE; + #xOutAckReq := TRUE; + + ELSIF NOT #xInEstopOkLocal AND NOT #xInAckReqLocal THEN + // Button pressed + #xOutLed := TRUE; + #xOutSafetyNotOk := TRUE; + #xOutAckReq := FALSE; + + ELSIF #xInEstopOkLocal AND NOT #xInAckReqLocal THEN + // ESTOP Activated + #xOutLed := FALSE; + #xOutSafetyNotOk := FALSE; + #xOutAckReq := FALSE; + + ELSE + // Button pressed or Hardware-Error + #xOutLed := TRUE; + #xOutSafetyNotOk := TRUE; + #xOutAckReq := FALSE; + + END_IF; + + ELSE // Global, Main Cabinet + + IF ((NOT #xInEstopOkLocal AND #xInAckReqLocal AND NOT #xInAckReqGlobal) OR + (#xInEstopOkLocal AND NOT #xInAckReqLocal AND #xInAckReqGlobal) OR + (NOT #xInEstopOkLocal AND #xInAckReqLocal AND #xInAckReqGlobal)) + AND NOT #xInSafetyNotOkGlobal THEN + #xOutLed := "Clock_1Hz"(* #FB_Blinker.xOutput *); + ELSIF (NOT #xInEstopOkLocal AND NOT #xInAckReqLocal) OR #xInSafetyNotOkGlobal THEN + #xOutLed := true; + ELSIF #xInEstopOkLocal AND NOT #xInAckReqLocal THEN + #xOutLed := false; + ELSE + #xOutLed := true; + END_IF; + + END_IF; + END_REGION + + REGION Monitoring + + #fbMonitoringEStop.stSettings.nErrorType := 1; + #fbMonitoringEStop.stSettings.xErrLedIfMachineIsOff := TRUE; + #fbMonitoringEStop.stSettings.xSelfQuit := TRUE; + #fbMonitoringEStop(sInFctnName := #sInAlarmFunction, + sInPrefix := #sInAlarmDevice, + sInSuffix := #sInAlarmSuffix, + InOutMachineState := #stInOutControlUnitCabinet, + xInQuitError := #stInOutControlUnitCabinet.xQuitError, + xInSignal := #xInEstopOkLocal, + wInTextListId_Message := 0, + wInTextListId_Function := #wInTextListId_Function, + wInTextListId_Prefix := #wInTextListId_Prefix, + wInTextListId_Suffix := #wInTextListId_Suffix, + sInAlarmMessage := #sInAlarmMessage); + + END_REGION + + REGION HMI + #stInOutHmiEstopPanel.sPanelName := #sInAlarmDevice; + #stInOutHmiEstopPanel.sBMKEStop := #sInAlarmSuffix; + + #stInOutHmiEstopPanel.sBMKResetButton := ''; + #stInOutHmiEstopPanel.sBMKResetLED := ''; + + #stInOutHmiEstopPanel.xEStopActive := NOT #xInEstopOkLocal; + #stInOutHmiEstopPanel.xReset := #xOutLed; + END_REGION +END_FUNCTION_BLOCK + diff --git a/1_BaseSystemLib/180_Safety/UDT_SafetyInterface.libinfo b/1_BaseSystemLib/180_Safety/UDT_SafetyInterface.libinfo new file mode 100644 index 0000000..c29b669 --- /dev/null +++ b/1_BaseSystemLib/180_Safety/UDT_SafetyInterface.libinfo @@ -0,0 +1,8 @@ +LibraryType: + Guid: fb864e13-ea61-4360-8d0f-d5d050b72048 +LibraryVersion: + VersionNumber: 2.0.0 + Author: e.yueksel + IsDefault: true + Comment: + de-DE: 'Stand: 29.08.2025' diff --git a/1_BaseSystemLib/180_Safety/UDT_SafetyInterface.libint b/1_BaseSystemLib/180_Safety/UDT_SafetyInterface.libint new file mode 100644 index 0000000..be40bac --- /dev/null +++ b/1_BaseSystemLib/180_Safety/UDT_SafetyInterface.libint @@ -0,0 +1,6 @@ +DocumentHash: + - FileName: UDT_SafetyInterface.xml + Hash: 7V6uuZopeaAuquveJTQTomhiu9/8dgcBkwUj72C9MsQ= +LibraryMetaFileHash: Z0Rw4OcHaWdU94RSCyr/pIjvuMIWeiLHlknCN1SHpIU= +LibraryVersion: + Guid: a11cbfca-b52e-4e12-9c12-bc76381e0450 diff --git a/1_BaseSystemLib/180_Safety/UDT_SafetyInterface.xml b/1_BaseSystemLib/180_Safety/UDT_SafetyInterface.xml new file mode 100644 index 0000000..fe2fb86 --- /dev/null +++ b/1_BaseSystemLib/180_Safety/UDT_SafetyInterface.xml @@ -0,0 +1,47 @@ + + + + + + +
+ + + Q-Signal vom ESTOP Baustein + + + + + + ACK_REQ-Signal vom ESTOP Baustein + + +
+
+ UDT_SafetyInterface + +
+ + + + + + de-DE + + + + + + + + + + de-DE + + + + + + +
+
\ No newline at end of file