BaseSystemLib hinzugefügt
This commit is contained in:
@@ -0,0 +1,6 @@
|
||||
LibraryType:
|
||||
Guid: 1bccc25d-f0e3-41bf-bf8f-556451b48635
|
||||
LibraryVersion:
|
||||
VersionNumber: 0.0.1
|
||||
Author: e.yueksel
|
||||
IsDefault: true
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
LibraryType:
|
||||
Guid: be300a29-366c-4af7-86d4-03b57ad189ac
|
||||
LibraryVersion:
|
||||
VersionNumber: 0.0.1
|
||||
Author: e.yueksel
|
||||
IsDefault: true
|
||||
@@ -0,0 +1,6 @@
|
||||
DocumentHash:
|
||||
- FileName: FC_LenTel_DigitSingle_MCopy.scl
|
||||
Hash: vMlfZS59FkD9vRhU7J4yRkq5IFleg7ON3Y9Ou2gbBCY=
|
||||
LibraryMetaFileHash: LM23JFYgY7nJI+beJASWy2jiG1lV0xBvHBKcbXzbl5Q=
|
||||
LibraryVersion:
|
||||
Guid: 4649d6fe-3163-4b85-9cac-01dbba1c2535
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
LibraryType:
|
||||
Guid: c2de9ced-3384-4ae5-b061-c56131670178
|
||||
LibraryVersion:
|
||||
VersionNumber: 0.0.1
|
||||
Author: e.yueksel
|
||||
IsDefault: true
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
LibraryType:
|
||||
Guid: 3d599b5b-0213-46f8-8892-325ed0394c19
|
||||
LibraryVersion:
|
||||
VersionNumber: 0.0.1
|
||||
Author: e.yueksel
|
||||
IsDefault: true
|
||||
@@ -0,0 +1,6 @@
|
||||
DocumentHash:
|
||||
- FileName: LGF_CalcCRC32Advanced_MCopy.scl
|
||||
Hash: 1qqS4TkbI0CoSZdszKz6k+3lkVQa0jWbmnNgukz1Iqg=
|
||||
LibraryMetaFileHash: KkCWyXRn3OXenxTY0Y4Iwgskl07io9/EARfgdrNs/mE=
|
||||
LibraryVersion:
|
||||
Guid: 31658ecf-f5da-4a76-a463-cd1e98d4aa4e
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -0,0 +1,6 @@
|
||||
LibraryType:
|
||||
Guid: 0062fd19-6682-49cc-834f-95307dbd2d72
|
||||
LibraryVersion:
|
||||
VersionNumber: 0.0.7
|
||||
Author: e.yueksel
|
||||
IsDefault: true
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -0,0 +1,6 @@
|
||||
DocumentHash:
|
||||
- FileName: FC_DateAsString.scl
|
||||
Hash: sxW9MGlJNzQwHlUucUIrXWLqFFj9XVJTFDBvIpZg2Qs=
|
||||
LibraryMetaFileHash: wzQfhgpRB7r0PHMXGTocBFU9yvk1Vr0feBlk7pR9Mcs=
|
||||
LibraryVersion:
|
||||
Guid: 4adee4de-c703-4794-9700-da57684c5c9f
|
||||
@@ -0,0 +1,38 @@
|
||||
FUNCTION "FC_DateAsString" : String
|
||||
{ S7_Optimized_Access := 'TRUE' }
|
||||
VERSION : 0.1
|
||||
VAR_TEMP
|
||||
tInt : Int;
|
||||
tDTL {InstructionName := 'DTL'; LibVersion := '1.0'} : DTL;
|
||||
sTmp : String[5];
|
||||
END_VAR
|
||||
|
||||
|
||||
BEGIN
|
||||
// Format: '21-05-12'
|
||||
|
||||
#tInt := RD_LOC_T(#tDTL);
|
||||
|
||||
#sTmp := UINT_TO_STRING(#tDTL.YEAR);
|
||||
#FC_DateAsString[1] := #sTmp[4];
|
||||
#FC_DateAsString[2] := #sTmp[5];
|
||||
#FC_DateAsString[3] := '-';
|
||||
#sTmp := USINT_TO_STRING(#tDTL.MONTH);
|
||||
IF #tDTL.MONTH <= 9 THEN
|
||||
#FC_DateAsString[4] := '0';
|
||||
#FC_DateAsString[5] := #sTmp[2];
|
||||
ELSE
|
||||
#FC_DateAsString[4] := #sTmp[2];
|
||||
#FC_DateAsString[5] := #sTmp[3];
|
||||
END_IF;
|
||||
#FC_DateAsString[6] := '-';
|
||||
#sTmp := USINT_TO_STRING(#tDTL.DAY);
|
||||
IF #tDTL.DAY <= 9 THEN
|
||||
#FC_DateAsString[7] := '0';
|
||||
#FC_DateAsString[8] := #sTmp[2];
|
||||
ELSE
|
||||
#FC_DateAsString[7] := #sTmp[2];
|
||||
#FC_DateAsString[8] := #sTmp[3];
|
||||
END_IF;
|
||||
END_FUNCTION
|
||||
|
||||
@@ -0,0 +1,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
|
||||
@@ -0,0 +1,6 @@
|
||||
DocumentHash:
|
||||
- FileName: FC_Loglevel_to_String.scl
|
||||
Hash: 0nOn7U6FrudaUAoJ0lbC3MqMbfsVeEOSIk31dwrXw8U=
|
||||
LibraryMetaFileHash: pC45QV67Xh2HrolPKgzDv3+YCEc3tG189rMarPR4Ym8=
|
||||
LibraryVersion:
|
||||
Guid: 85d69f29-f857-4428-90a9-872b80e36573
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -0,0 +1,6 @@
|
||||
DocumentHash:
|
||||
- FileName: FC_TimeAsString.scl
|
||||
Hash: 3WJUl9RFht2vorDlH8QAIOs7AhSUh8JVzkcdrRKQwZo=
|
||||
LibraryMetaFileHash: 4RB0ELjNFkABN8RO9ZmmvbU+HNP4H+TccEh5oYuI2rI=
|
||||
LibraryVersion:
|
||||
Guid: 36b9f032-4747-42aa-b87f-9637f121af9c
|
||||
@@ -0,0 +1,83 @@
|
||||
FUNCTION "FC_TimeAsString" : String
|
||||
{ S7_Optimized_Access := 'TRUE' }
|
||||
VERSION : 0.1
|
||||
VAR_TEMP
|
||||
tInt : DInt;
|
||||
tDTL {InstructionName := 'DTL'; LibVersion := '1.0'} : DTL;
|
||||
sTmp : String[10];
|
||||
END_VAR
|
||||
|
||||
|
||||
BEGIN
|
||||
#tInt := RD_LOC_T(#tDTL);
|
||||
|
||||
#sTmp := UINT_TO_STRING(#tDTL.HOUR);
|
||||
IF #tDTL.HOUR < 10 THEN
|
||||
#FC_TimeAsString[1] := '0';
|
||||
#FC_TimeAsString[2] := #sTmp[2];
|
||||
ELSE
|
||||
#FC_TimeAsString[1] := #sTmp[2];
|
||||
#FC_TimeAsString[2] := #sTmp[3];
|
||||
END_IF;
|
||||
|
||||
#FC_TimeAsString[3] := ':';
|
||||
|
||||
#sTmp := USINT_TO_STRING(#tDTL.MINUTE);
|
||||
IF #tDTL.MINUTE < 10 THEN
|
||||
#FC_TimeAsString[4] := '0';
|
||||
#FC_TimeAsString[5] := #sTmp[2];
|
||||
ELSE
|
||||
#FC_TimeAsString[4] := #sTmp[2];
|
||||
#FC_TimeAsString[5] := #sTmp[3];
|
||||
END_IF;
|
||||
|
||||
#FC_TimeAsString[6] := ':';
|
||||
|
||||
#sTmp := USINT_TO_STRING(#tDTL.SECOND);
|
||||
IF #tDTL.SECOND < 10 THEN
|
||||
#FC_TimeAsString[7] := '0';
|
||||
#FC_TimeAsString[8] := #sTmp[2];
|
||||
ELSE
|
||||
#FC_TimeAsString[7] := #sTmp[2];
|
||||
#FC_TimeAsString[8] := #sTmp[3];
|
||||
END_IF;
|
||||
|
||||
#FC_TimeAsString[9] := ',';
|
||||
|
||||
#sTmp := UDINT_TO_STRING(#tDTL.NANOSECOND);
|
||||
IF #tDTL.NANOSECOND < 1000000 THEN
|
||||
#FC_TimeAsString[10] := '0';
|
||||
#FC_TimeAsString[11] := '0';
|
||||
#FC_TimeAsString[12] := '0';
|
||||
ELSIF #tDTL.NANOSECOND < 10000000 THEN
|
||||
#FC_TimeAsString[10] := '0';
|
||||
#FC_TimeAsString[11] := '0';
|
||||
#FC_TimeAsString[12] := #sTmp[2];
|
||||
ELSIF #tDTL.NANOSECOND < 100000000 THEN
|
||||
#FC_TimeAsString[10] := '0';
|
||||
#FC_TimeAsString[11] := #sTmp[2];
|
||||
#FC_TimeAsString[12] := #sTmp[3];
|
||||
ELSE
|
||||
#FC_TimeAsString[10] := #sTmp[2];
|
||||
#FC_TimeAsString[11] := #sTmp[3];
|
||||
#FC_TimeAsString[12] := #sTmp[4];
|
||||
END_IF;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
END_FUNCTION
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
LibraryType:
|
||||
Guid: 7462bbc8-2811-4b0d-bdf1-031a6aa286ee
|
||||
LibraryVersion:
|
||||
VersionNumber: 0.0.6
|
||||
Author: e.yueksel
|
||||
IsDefault: true
|
||||
Comment:
|
||||
de-DE: Inkonsistenz bereinigen
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
+8
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
+10
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
@@ -0,0 +1,6 @@
|
||||
DocumentHash:
|
||||
- FileName: UDT_TelegramData.xml
|
||||
Hash: onl5A2ZBXD1Osb9HpyJYM94U0gKjCtdo5NXjCUPG6d4=
|
||||
LibraryMetaFileHash: Oe4DDTrGKgyFYBb5byBV2S5tlyI6GYHDaPGbe9u0en4=
|
||||
LibraryVersion:
|
||||
Guid: 98b089a9-4b8e-4a6f-8a92-5ae5a1509c03
|
||||
@@ -0,0 +1,62 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Document>
|
||||
<Engineering version="V20" />
|
||||
<SW.Types.PlcStruct ID="0">
|
||||
<AttributeList>
|
||||
<Interface><Sections xmlns="http://www.siemens.com/automation/Openness/SW/Interface/v5">
|
||||
<Section Name="None">
|
||||
<Member Name="sIDString" Datatype="String">
|
||||
<Comment>
|
||||
<MultiLanguageText Lang="de-DE">Wenn es eine Telegramm-ID gibt, wird sie hier angezeigt (not implemented)</MultiLanguageText>
|
||||
</Comment>
|
||||
</Member>
|
||||
<Member Name="nID" Datatype="DInt">
|
||||
<Comment>
|
||||
<MultiLanguageText Lang="de-DE">Telegramm-ID als Nummer, wenn diese in der Telegramm-Definition vorgesehen wurde (not implemented)</MultiLanguageText>
|
||||
</Comment>
|
||||
</Member>
|
||||
<Member Name="xCRC32ValidationResult" Datatype="Bool">
|
||||
<Comment>
|
||||
<MultiLanguageText Lang="de-DE">Wenn eine Validierung mit CRC32 im Telegramm implementiert ist, dann steht hier das Ergebnis (TRUE = erfolgreich, FALSE = nicht erfolgreich/ nicht definiert)</MultiLanguageText>
|
||||
</Comment>
|
||||
</Member>
|
||||
<Member Name="arDataString" Datatype="Array[1.."TELEGRAM_DATA_MAX"] of String["TELEGRAM_DATA_FIELD_MAX"]">
|
||||
<Comment>
|
||||
<MultiLanguageText Lang="de-DE">Die Telegrammdaten als Array of String. Jeder String entspricht einem Datenfeld.</MultiLanguageText>
|
||||
</Comment>
|
||||
</Member>
|
||||
<Member Name="nDataCount" Datatype="DInt">
|
||||
<Comment>
|
||||
<MultiLanguageText Lang="de-DE">Anzahl der Datenfelder. </MultiLanguageText>
|
||||
</Comment>
|
||||
<StartValue>1</StartValue>
|
||||
</Member>
|
||||
</Section>
|
||||
</Sections></Interface>
|
||||
<Name>UDT_TelegramData</Name>
|
||||
<Namespace />
|
||||
</AttributeList>
|
||||
<ObjectList>
|
||||
<MultilingualText ID="1" CompositionName="Comment">
|
||||
<ObjectList>
|
||||
<MultilingualTextItem ID="2" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>de-DE</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
</ObjectList>
|
||||
</MultilingualText>
|
||||
<MultilingualText ID="3" CompositionName="Title">
|
||||
<ObjectList>
|
||||
<MultilingualTextItem ID="4" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>de-DE</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
</ObjectList>
|
||||
</MultilingualText>
|
||||
</ObjectList>
|
||||
</SW.Types.PlcStruct>
|
||||
</Document>
|
||||
@@ -0,0 +1,6 @@
|
||||
LibraryType:
|
||||
Guid: 8ba5f026-f6a4-48b6-99af-dc7e461fdb45
|
||||
LibraryVersion:
|
||||
VersionNumber: 0.0.7
|
||||
Author: e.yueksel
|
||||
IsDefault: true
|
||||
@@ -0,0 +1,6 @@
|
||||
DocumentHash:
|
||||
- FileName: UDT_TelegramData_Send.xml
|
||||
Hash: BQpYkFSPgx9BESwMa3p6bcSG7B5zPwgblsfSmxuhoMM=
|
||||
LibraryMetaFileHash: cHNawuU7EPzVTRSwJgxUEYciiM7gvcd4ltOMZa0wIIg=
|
||||
LibraryVersion:
|
||||
Guid: 03564d6e-8226-4e22-a3ea-f92edd06e200
|
||||
@@ -0,0 +1,86 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Document>
|
||||
<Engineering version="V20" />
|
||||
<SW.Types.PlcStruct ID="0">
|
||||
<AttributeList>
|
||||
<Interface><Sections xmlns="http://www.siemens.com/automation/Openness/SW/Interface/v5">
|
||||
<Section Name="None">
|
||||
<Member Name="sIDString" Datatype="String">
|
||||
<Comment>
|
||||
<MultiLanguageText Lang="de-DE">Wenn es eine Telegramm-ID gibt, wird sie hier angezeigt (not implemented)</MultiLanguageText>
|
||||
</Comment>
|
||||
</Member>
|
||||
<Member Name="nID" Datatype="DInt">
|
||||
<Comment>
|
||||
<MultiLanguageText Lang="de-DE">Telegramm-ID als Nummer, wenn diese in der Telegramm-Definition vorgesehen wurde (not implemented)</MultiLanguageText>
|
||||
</Comment>
|
||||
</Member>
|
||||
<Member Name="xCRC32ValidationResult" Datatype="Bool">
|
||||
<Comment>
|
||||
<MultiLanguageText Lang="de-DE">Wenn eine Validierung mit CRC32 im Telegramm implementiert ist, dann steht hier das Ergebnis (TRUE = erfolgreich, FALSE = nicht erfolgreich/ nicht definiert)</MultiLanguageText>
|
||||
</Comment>
|
||||
</Member>
|
||||
<Member Name="arDataString" Datatype="Array[1.."TELEGRAM_SEND_DATA_MAX"] of String["TELEGRAM_DATA_FIELD_MAX"]">
|
||||
<Comment>
|
||||
<MultiLanguageText Lang="de-DE">Die Telegrammdaten als Array of String. Jeder String entspricht einem Datenfeld.</MultiLanguageText>
|
||||
</Comment>
|
||||
</Member>
|
||||
<Member Name="nDataCount" Datatype="DInt">
|
||||
<Comment>
|
||||
<MultiLanguageText Lang="de-DE">Anzahl der Datenfelder. </MultiLanguageText>
|
||||
</Comment>
|
||||
<StartValue>1</StartValue>
|
||||
</Member>
|
||||
</Section>
|
||||
</Sections></Interface>
|
||||
<Name>UDT_TelegramData_Send</Name>
|
||||
<Namespace />
|
||||
</AttributeList>
|
||||
<ObjectList>
|
||||
<MultilingualText ID="1" CompositionName="Comment">
|
||||
<ObjectList>
|
||||
<MultilingualTextItem ID="2" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>de-DE</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="3" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>en-US</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="4" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>cs-CZ</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
</ObjectList>
|
||||
</MultilingualText>
|
||||
<MultilingualText ID="5" CompositionName="Title">
|
||||
<ObjectList>
|
||||
<MultilingualTextItem ID="6" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>de-DE</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="7" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>en-US</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
<MultilingualTextItem ID="8" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>cs-CZ</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
</ObjectList>
|
||||
</MultilingualText>
|
||||
</ObjectList>
|
||||
</SW.Types.PlcStruct>
|
||||
</Document>
|
||||
@@ -0,0 +1,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
|
||||
@@ -0,0 +1,6 @@
|
||||
DocumentHash:
|
||||
- FileName: UDT_TelegramDefinition.xml
|
||||
Hash: 0cV/CYkCUk207NJBfTvndbGASucn+Kzead/vMTVLarM=
|
||||
LibraryMetaFileHash: TDtZpXRWGqg0j67MMPtliOMgW6X9H+XAL8n1wjhMMGs=
|
||||
LibraryVersion:
|
||||
Guid: 2d1cc429-2c73-4e6c-80c3-aba5ed21dc9a
|
||||
@@ -0,0 +1,101 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Document>
|
||||
<Engineering version="V20" />
|
||||
<SW.Types.PlcStruct ID="0">
|
||||
<AttributeList>
|
||||
<Interface><Sections xmlns="http://www.siemens.com/automation/Openness/SW/Interface/v5">
|
||||
<Section Name="None">
|
||||
<Member Name="sStartMarker" Datatype="String["TELEGRAM_MARKER_MAX"]">
|
||||
<Comment>
|
||||
<MultiLanguageText Lang="de-DE">Start marker / Start pattern of the telegram </MultiLanguageText>
|
||||
</Comment>
|
||||
</Member>
|
||||
<Member Name="nStartMarkerLen" Datatype="UDInt">
|
||||
<Comment>
|
||||
<MultiLanguageText Lang="de-DE">Length of the start marker</MultiLanguageText>
|
||||
</Comment>
|
||||
</Member>
|
||||
<Member Name="sEndMarker" Datatype="String["TELEGRAM_MARKER_MAX"]">
|
||||
<Comment>
|
||||
<MultiLanguageText Lang="de-DE">End marker / End pattern of the telegram</MultiLanguageText>
|
||||
</Comment>
|
||||
</Member>
|
||||
<Member Name="nEndMarkerLen" Datatype="UDInt">
|
||||
<Comment>
|
||||
<MultiLanguageText Lang="de-DE">Length of the end marker</MultiLanguageText>
|
||||
</Comment>
|
||||
</Member>
|
||||
<Member Name="sStartMarkerSend" Datatype="String["TELEGRAM_MARKER_MAX"]">
|
||||
<Comment>
|
||||
<MultiLanguageText Lang="de-DE">Start marker / Start pattern of the telegram (for sending)</MultiLanguageText>
|
||||
</Comment>
|
||||
</Member>
|
||||
<Member Name="nStartMarkerLenSend" Datatype="UDInt">
|
||||
<Comment>
|
||||
<MultiLanguageText Lang="de-DE">Length of the start marker (for sending)</MultiLanguageText>
|
||||
</Comment>
|
||||
</Member>
|
||||
<Member Name="sEndMarkerSend" Datatype="String["TELEGRAM_MARKER_MAX"]">
|
||||
<Comment>
|
||||
<MultiLanguageText Lang="de-DE">End marker / End pattern of the telegram (for sending)</MultiLanguageText>
|
||||
</Comment>
|
||||
</Member>
|
||||
<Member Name="nEndMarkerLenSend" Datatype="UDInt">
|
||||
<Comment>
|
||||
<MultiLanguageText Lang="de-DE">Length of the end marker (for sending)</MultiLanguageText>
|
||||
</Comment>
|
||||
</Member>
|
||||
<Member Name="bSeparatorByte" Datatype="Byte">
|
||||
<Comment>
|
||||
<MultiLanguageText Lang="de-DE">The byte, used for separation of telegram content</MultiLanguageText>
|
||||
</Comment>
|
||||
</Member>
|
||||
<Member Name="nLength" Datatype="UDInt">
|
||||
<Comment>
|
||||
<MultiLanguageText Lang="de-DE">The length of the telegram including start and end byte or zero to ignore the setting (fixed telegram length)</MultiLanguageText>
|
||||
</Comment>
|
||||
</Member>
|
||||
<Member Name="nTelegramIDDataField" Datatype="UDInt">
|
||||
<Comment>
|
||||
<MultiLanguageText Lang="de-DE">The number of the data field that contains the telegram ID or zero to ignore the setting (Not implemented)</MultiLanguageText>
|
||||
</Comment>
|
||||
</Member>
|
||||
<Member Name="xTelegramIDIsNumber" Datatype="Bool">
|
||||
<Comment>
|
||||
<MultiLanguageText Lang="de-DE">Indicates whether the telegram ID is a number. When this parameter is set to TRUE, the ID string will be converted automatically (Not implemented)</MultiLanguageText>
|
||||
</Comment>
|
||||
</Member>
|
||||
<Member Name="nCRC32ValidationDataField" Datatype="UDInt">
|
||||
<Comment>
|
||||
<MultiLanguageText Lang="de-DE">The number of the data field that contains the CRC32-Checksum or zero to ignore the setting</MultiLanguageText>
|
||||
</Comment>
|
||||
</Member>
|
||||
</Section>
|
||||
</Sections></Interface>
|
||||
<Name>UDT_TelegramDefinition</Name>
|
||||
<Namespace />
|
||||
</AttributeList>
|
||||
<ObjectList>
|
||||
<MultilingualText ID="1" CompositionName="Comment">
|
||||
<ObjectList>
|
||||
<MultilingualTextItem ID="2" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>de-DE</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
</ObjectList>
|
||||
</MultilingualText>
|
||||
<MultilingualText ID="3" CompositionName="Title">
|
||||
<ObjectList>
|
||||
<MultilingualTextItem ID="4" CompositionName="Items">
|
||||
<AttributeList>
|
||||
<Culture>de-DE</Culture>
|
||||
<Text />
|
||||
</AttributeList>
|
||||
</MultilingualTextItem>
|
||||
</ObjectList>
|
||||
</MultilingualText>
|
||||
</ObjectList>
|
||||
</SW.Types.PlcStruct>
|
||||
</Document>
|
||||
Reference in New Issue
Block a user