Added precharge mode

This commit is contained in:
Matthias Heisig
2025-06-04 19:37:25 +02:00
parent f12063e294
commit 38f44128d1
9 changed files with 451 additions and 277 deletions

View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1" ProductVersion="3.1.4026.12">
<DUT Name="E_STRING_OPERATING_MODE" Id="{d4bc8f87-c493-46b8-95d6-71556c8b0aab}">
<Declaration><![CDATA[{attribute 'qualified_only'}
{attribute 'strict'}
{attribute 'to_string'}
TYPE E_STRING_OPERATING_MODE :
(
AUTOMATIC := 0,
SAFETY_CHECK := 1,
PRECHARGE := 2,
BALANCING := 3
);
END_TYPE
]]></Declaration>
</DUT>
</TcPlcObject>

View File

@@ -57,6 +57,9 @@
<Compile Include="DUTs\E_COMPONENT_STATUS.TcDUT">
<SubType>Code</SubType>
</Compile>
<Compile Include="DUTs\E_STRING_OPERATING_MODE.TcDUT">
<SubType>Code</SubType>
</Compile>
<Compile Include="DUTs\Modbus\ErrorWarningRegisters\ST_DWORD_UNIT_ERROR_BITMAP.TcDUT">
<SubType>Code</SubType>
</Compile>
@@ -248,8 +251,8 @@
<ProjectExtensions>
<PlcProjectOptions>
<XmlArchive>
<Data>
<o xml:space="preserve" t="OptionKey">
<Data>
<o xml:space="preserve" t="OptionKey">
<v n="Name">"&lt;ProjectRoot&gt;"</v>
<d n="SubKeys" t="Hashtable" ckt="String" cvt="OptionKey">
<v>{192FAD59-8248-4824-A8DE-9177C94C195A}</v>
@@ -2631,16 +2634,16 @@
</d>
<d n="Values" t="Hashtable" />
</o>
</Data>
<TypeList>
<Type n="Boolean">System.Boolean</Type>
<Type n="Hashtable">System.Collections.Hashtable</Type>
<Type n="Int32">System.Int32</Type>
<Type n="OptionKey">{54dd0eac-a6d8-46f2-8c27-2f43c7e49861}</Type>
<Type n="String">System.String</Type>
<Type n="UInt32">System.UInt32</Type>
</TypeList>
</XmlArchive>
</Data>
<TypeList>
<Type n="Boolean">System.Boolean</Type>
<Type n="Hashtable">System.Collections.Hashtable</Type>
<Type n="Int32">System.Int32</Type>
<Type n="OptionKey">{54dd0eac-a6d8-46f2-8c27-2f43c7e49861}</Type>
<Type n="String">System.String</Type>
<Type n="UInt32">System.UInt32</Type>
</TypeList>
</XmlArchive>
</PlcProjectOptions>
</ProjectExtensions>
</Project>

File diff suppressed because one or more lines are too long

View File

@@ -19,6 +19,9 @@ VAR_INPUT
// Module in safety check mode
xInSafetyCheckMode : BOOL;
// String operation mode
eStringOperatingMode : E_STRING_OPERATING_MODE;
// All safetyinterlocks are ok
xSafetyIntlksOk : BOOL;
@@ -227,6 +230,7 @@ END_IF
_fbUnit1(
xEnable := xEnable,
xStartBalancing := xStartBalancing,
eStringOperatingMode := eStringOperatingMode,
xInverterEnabled := xInverterEnabled,
xInSafetyCheckMode := xInSafetyCheckMode,
stUnitConfig:= GVL_CONFIG.stUnitConfig,
@@ -266,6 +270,7 @@ END_IF
_fbUnit2(
xEnable := xEnable,
xStartBalancing := xStartBalancing,
eStringOperatingMode := eStringOperatingMode,
xInverterEnabled := xInverterEnabled,
xInSafetyCheckMode := xInSafetyCheckMode,
stUnitConfig:= GVL_CONFIG.stUnitConfig,
@@ -305,6 +310,7 @@ END_IF
_fbUnit3(
xEnable := xEnable,
xStartBalancing := xStartBalancing,
eStringOperatingMode := eStringOperatingMode,
xInverterEnabled := xInverterEnabled,
xInSafetyCheckMode := xInSafetyCheckMode,
stUnitConfig:= GVL_CONFIG.stUnitConfig,
@@ -344,6 +350,7 @@ END_IF
_fbUnit4(
xEnable := xEnable,
xStartBalancing := xStartBalancing,
eStringOperatingMode := eStringOperatingMode,
xInverterEnabled := xInverterEnabled,
xInSafetyCheckMode := xInSafetyCheckMode,
stUnitConfig:= GVL_CONFIG.stUnitConfig,

View File

@@ -18,6 +18,9 @@ VAR_INPUT
// String in safety check mode
xInSafetyCheckMode : BOOL;
// Operating mode of string
eOperationMode : E_STRING_OPERATING_MODE;
// Requested inverter power
rPowerInverter : REAL;
@@ -266,6 +269,7 @@ _fbModule1(
uiFirstUnitIndex := uiStringNumber * 12,
rCurrent := stHMIInterface.rCurrent,
xStartBalancing := _xStartBalancing,
eStringOperatingMode := eOperationMode,
xInverterEnabled := _fbInverter.xActive,
xInSafetyCheckMode := xInSafetyCheckMode,
xEmergencyStopOk:= xEmergencyStopOk,
@@ -286,6 +290,7 @@ _fbModule2(
uiFirstUnitIndex := uiStringNumber * 12 + 4,
rCurrent := stHMIInterface.rCurrent,
xStartBalancing := _xStartBalancing,
eStringOperatingMode := eOperationMode,
xInverterEnabled := _fbInverter.xActive,
xInSafetyCheckMode := xInSafetyCheckMode,
xEmergencyStopOk:= xEmergencyStopOk,
@@ -306,6 +311,7 @@ _fbModule3(
uiFirstUnitIndex := uiStringNumber * 12 + 8,
rCurrent := stHMIInterface.rCurrent,
xStartBalancing := _xStartBalancing,
eStringOperatingMode := eOperationMode,
xInverterEnabled := _fbInverter.xActive,
xInSafetyCheckMode := xInSafetyCheckMode,
xEmergencyStopOk:= xEmergencyStopOk,
@@ -399,22 +405,28 @@ HandleErrors();
CASE _iState OF
0: // Idle
// Start in normal mode
IF xEnable AND (NOT xStartBalancing) AND xAllModulesInAutoMode AND xRepairSwitchOk AND (NOT _xErrorInternal) THEN
IF xEnable AND xAllModulesInAutoMode AND xRepairSwitchOk AND (NOT _xErrorInternal) THEN
_xEnable := TRUE;
//eStatus := E_COMPONENT_STATUS.STARTING;
IF xInSafetyCheckMode THEN
_iState := 1;
ELSE
_iState := 5;
END_IF
END_IF
// Start in balancing mode
IF (NOT xEnable) AND xStartBalancing AND xAllModulesInAutoMode AND (NOT _xErrorInternal) THEN
_xStartBalancing := TRUE;
_xReleaseLimitErrorsInternal := FALSE;
//eStatus := E_COMPONENT_STATUS.STARTING;
_iState := 7;
CASE eOperationMode OF
// Automatic mode (local or remote)
E_STRING_OPERATING_MODE.AUTOMATIC:
_iState := 5;
// Balancing mode
E_STRING_OPERATING_MODE.BALANCING:
_xStartBalancing := TRUE;
_xReleaseLimitErrorsInternal := FALSE;
_iState := 7;
// Safety check mode
E_STRING_OPERATING_MODE.SAFETY_CHECK:
_iState := 1;
// Precharge mode
E_STRING_OPERATING_MODE.PRECHARGE:
_iState := 1;
END_CASE
END_IF
IF _xErrorInternal THEN
@@ -442,16 +454,13 @@ CASE _iState OF
5: // Wait for all modules to be ready in normal mode
IF _xAllModulesReady AND _xBalanceOk THEN
xResetSafetyDCCB := TRUE;
IF (NOT xInSafetyCheckMode) THEN
_xReleaseLimitErrorsInternal := TRUE;
END_IF
_xReleaseLimitErrorsInternal := TRUE;
_tonResetPulseLength.IN := TRUE;
_iState := 10;
END_IF
IF (NOT xEnable) THEN
_xEnable := FALSE;
//eStatus := E_COMPONENT_STATUS.OFF;
_iState := 0;
END_IF
@@ -497,7 +506,6 @@ CASE _iState OF
_tonSafetyOkTimeout.IN := FALSE;
xResetSafetyDCCB := FALSE;
_xEnable := FALSE;
//eStatus := E_COMPONENT_STATUS.SHUTDOWN;
_iState := 40;
END_IF
@@ -521,18 +529,32 @@ CASE _iState OF
IF (NOT xDCCBOpen) THEN
_xReleaseSafetyIntlkErrors := TRUE;
_tonErrorDCCBNotClosed.IN := FALSE;
_rPowerInverterInternal := rPowerInverter;
//_rPowerInverterInternal := 0.0;
IF xInSafetyCheckMode THEN
_rPowerInverterInternal := 0.0;
_xEnableInverter := TRUE;
// _iState := 29;
_iState := 21;
//eStatus := E_COMPONENT_STATUS.ON;
ELSE
_iState := 21;
END_IF
CASE eOperationMode OF
E_STRING_OPERATING_MODE.AUTOMATIC:
_rPowerInverterInternal := rPowerInverter;
_xEnableInverter := TRUE;
_iState := 21;
E_STRING_OPERATING_MODE.SAFETY_CHECK:
_rPowerInverterInternal := 0.0;
_xEnableInverter := TRUE;
_iState := 21;
E_STRING_OPERATING_MODE.PRECHARGE:
_rPowerInverterInternal := 0.0;
_xEnableInverter := FALSE;
_iState := 29;
// Balancing mode should never reach this point!
// Its just here for testing
E_STRING_OPERATING_MODE.BALANCING:
_rPowerInverterInternal := 0.0;
_xEnableInverter := FALSE;
_iState := 50;
END_CASE
END_IF
IF _tonErrorDCCBNotClosed.Q THEN
_xEnable := FALSE;
xCloseDCCB := FALSE;
@@ -564,12 +586,12 @@ CASE _iState OF
22: // Wait for inverter to be ready
_tonInverterStartupTimeout(IN := TRUE);
IF _fbInverter.xActive AND (NOT _fbInverter.xError) THEN
IF xInSafetyCheckMode THEN
_iState := 29;
ELSE
_iState := 30;
END_IF
//eStatus := E_COMPONENT_STATUS.ON;
CASE eOperationMode OF
E_STRING_OPERATING_MODE.SAFETY_CHECK:
_iState := 29;
ELSE
_iState := 30;
END_CASE
xReady := TRUE;
_tonInverterStartupTimeout(IN := FALSE);
END_IF
@@ -578,7 +600,6 @@ CASE _iState OF
_xEnableInverter := FALSE;
_rPowerInverterInternal := 0.0;
_xEnable := FALSE;
//eStatus := E_COMPONENT_STATUS.SHUTDOWN;
_iState := 31;
_tonInverterStartupTimeout(IN := FALSE);
END_IF
@@ -603,7 +624,6 @@ CASE _iState OF
IF (NOT xEnable) THEN
_xEnable := FALSE;
_xReleaseLimitErrorsInternal := FALSE;
//eStatus := E_COMPONENT_STATUS.SHUTDOWN;
_iState := 31;
END_IF
@@ -627,28 +647,16 @@ CASE _iState OF
_rPowerInverterInternal := rPowerInverter;
END_IF
(*
IF _rPowerInverterInternal > 0.0 THEN
eStatus := E_COMPONENT_STATUS.DISCHARGING;
ELSIF _rPowerInverterInternal < 0.0 THEN
eStatus := E_COMPONENT_STATUS.CHARGING;
ELSE
eStatus := E_COMPONENT_STATUS.ON;
END_IF
*)
// Shutdown
IF (NOT xEnable) THEN
_xEnable := FALSE;
_xReleaseLimitErrorsInternal := FALSE;
IF GVL_CONFIG.xShutdownDischargeWithInverter THEN
_rPowerInverterInternal := GVL_CONFIG.rAbsShutdownDischargePower;
//eStatus := E_COMPONENT_STATUS.SHUTDOWN;
_iState := 31;
ELSE
_rPowerInverterInternal := 0.0;
_xEnableInverter := FALSE;
//eStatus := E_COMPONENT_STATUS.SHUTDOWN;
_iState := 40;
END_IF

View File

@@ -9,9 +9,6 @@ VAR_INPUT
// HMI interface
stHMIInterface : REFERENCE TO ST_UNIT_HMI_INTERFACE;
// Components shortage workaround
// xVoltageSensorIs1500V : BOOL;
// Start unit
xEnable : BOOL;
@@ -21,6 +18,9 @@ VAR_INPUT
// Unit in safety check mode
xInSafetyCheckMode : BOOL;
// String operation mode
eStringOperatingMode : E_STRING_OPERATING_MODE;
// Emergency stop ok
xEmergencyStopOk : BOOL;
@@ -1027,7 +1027,32 @@ CASE _iState OF
31: // Check if voltage limit can be reached
_tonVoltageCheckTimeput(IN := TRUE);
IF (NOT _xErrorActive) AND (NOT _xWarningActive) THEN
CASE eStringOperatingMode OF
E_STRING_OPERATING_MODE.SAFETY_CHECK:
_xEnableVoltageLimitChecks := TRUE;
_tonVoltageCheckTimeput(IN := FALSE);
xReady := TRUE;
stHMIInterface.eStatus := E_COMPONENT_STATUS.ON;
_iState := 35;
E_STRING_OPERATING_MODE.PRECHARGE:
_tonVoltageCheckTimeput(IN := FALSE);
_xEnableVoltageLimitChecks := FALSE;
xReady := TRUE;
stHMIInterface.eStatus := E_COMPONENT_STATUS.ON;
_iState := 35;
ELSE
IF (_fbVoltageSegment.rScaledValue >= GVL_CONFIG.rMinimumUnitVoltage) THEN
_xEnableVoltageLimitChecks := TRUE;
xReady := TRUE;
_iState := 35;
END_IF
END_CASE
END_IF
// Check for minimum unit voltage
(*
IF ((_fbVoltageSegment.rScaledValue >= GVL_CONFIG.rMinimumUnitVoltage) OR xInSafetyCheckMode) AND (NOT _xErrorActive) AND (NOT _xWarningActive) THEN
_tonVoltageCheckTimeput(IN := FALSE);
xReady := TRUE;
@@ -1042,9 +1067,10 @@ CASE _iState OF
stHMIInterface.eStatus := E_COMPONENT_STATUS.ON;
_iState := 35;
END_IF
END_IF
*)
// Voltage check timeout
IF _tonVoltageCheckTimeput.Q OR _xErrorActive THEN
_tonVoltageCheckTimeput(IN := FALSE);
xError := TRUE;
@@ -1260,8 +1286,6 @@ CASE _iState OF
_fbPosolytValveTankOutlet.ReqAutomaticClose();
_rSetpointNegolytPumpInlet := GVL_CONFIG.rPumpNegolytDisChrgPower;
_rSetpointPosolytPumpInlet := GVL_CONFIG.rPumpPosolytDisChrgPower;
//_fbPosolytPumpInlet.ReqAutomaticStop();
//_fbNegolytPumpInlet.ReqAutomaticStop();
_xEnableVoltageLimitChecks := FALSE;
xShutdownDischargeAllowed := FALSE;
xInShutdownDischargeMode := FALSE;

View File

@@ -28,10 +28,14 @@ VAR
_iState : INT;
_iStateSafetyCheck : INT;
_iStateBalancing : INT;
_iStatePrecharge : INT;
// Start safety check mode
_xStartSafetyCheck : BOOL;
// Start precharge mode
_xStartPrecharge : BOOL;
// Auto remote and auto local power request
_rAutoPowerRequest : REAL;
@@ -144,6 +148,8 @@ VAR
_xStringsBalancingDone : BOOL;
_xStringsInAutoMode : BOOL;
_eStringOpMode : E_STRING_OPERATING_MODE;
_rMaxCurrentInverterDCVoltage : REAL;
_rMinCurrentInverterDCVoltage : REAL;
@@ -314,6 +320,7 @@ _tonStartupDelay(IN := TRUE);
_afbStrings[0](
xEnable := _xEnableString AND GVL_CONFIG.axStringEnabled[0],
uiStringNumber := 0,
eOperationMode := _eStringOpMode,
xErrorShutdown := _xErrorShutdown,
xStartBalancing := _xStartBalancing,
sInverterIP := GVL_CONFIG.sInverterIpString1,
@@ -343,6 +350,7 @@ GVL_MODBUS.stBMSErrorReg.wBMSWarningActive.stBitmap.bSafetyIntlkString1 := (NOT
_afbStrings[1](
xEnable := _xEnableString AND GVL_CONFIG.axStringEnabled[1],
uiStringNumber := 1,
eOperationMode := _eStringOpMode,
xErrorShutdown := _xErrorShutdown,
xStartBalancing := _xStartBalancing,
sInverterIP := GVL_CONFIG.sInverterIpString2,
@@ -549,6 +557,7 @@ GVL_MODBUS.stModbusEMSComm.stModbusReg11.rSetpointCosPhiMirror := GVL_MODBUS.stM
// ===============================
CASE _eBMSControlMode OF
E_BMS_CONTROL_MODE.AUTO_REMOTE:
_eStringOpMode := E_STRING_OPERATING_MODE.AUTOMATIC;
_xAllComponentsToManualMode := FALSE;
_xInSafetyCheckMode := FALSE;
_xReleaseManualMode := FALSE;
@@ -559,6 +568,7 @@ CASE _eBMSControlMode OF
SM_AUTO();
E_BMS_CONTROL_MODE.AUTO_LOCAL:
_eStringOpMode := E_STRING_OPERATING_MODE.AUTOMATIC;
_xAllComponentsToManualMode := FALSE;
_xInSafetyCheckMode := FALSE;
_xReleaseManualMode := FALSE;
@@ -570,6 +580,7 @@ CASE _eBMSControlMode OF
SM_AUTO();
E_BMS_CONTROL_MODE.MANUAL:
_eStringOpMode := E_STRING_OPERATING_MODE.AUTOMATIC;
_xAllComponentsToManualMode := TRUE;
_xInSafetyCheckMode := FALSE;
_xReleaseManualMode := TRUE;
@@ -580,6 +591,7 @@ CASE _eBMSControlMode OF
SM_MANUAL();
E_BMS_CONTROL_MODE.SAFETY_CHECK:
_eStringOpMode := E_STRING_OPERATING_MODE.SAFETY_CHECK;
_xAllComponentsToManualMode := FALSE;
_xInSafetyCheckMode := TRUE;
_xReleaseManualMode := FALSE;
@@ -590,6 +602,7 @@ CASE _eBMSControlMode OF
SM_SAFETY_CHECK();
E_BMS_CONTROL_MODE.CAPACITY_TEST:
_eStringOpMode := E_STRING_OPERATING_MODE.AUTOMATIC;
_xAllComponentsToManualMode := FALSE;
_xInSafetyCheckMode := FALSE;
_xReleaseManualMode := FALSE;
@@ -600,6 +613,7 @@ CASE _eBMSControlMode OF
SM_CAPACITY_TEST();
E_BMS_CONTROL_MODE.BALANCING:
_eStringOpMode := E_STRING_OPERATING_MODE.BALANCING;
_xAllComponentsToManualMode := FALSE;
_xInSafetyCheckMode := FALSE;
_xReleaseManualMode := FALSE;
@@ -610,6 +624,7 @@ CASE _eBMSControlMode OF
SM_BALANCING();
E_BMS_CONTROL_MODE.CYCLING:
_eStringOpMode := E_STRING_OPERATING_MODE.AUTOMATIC;
_xAllComponentsToManualMode := FALSE;
_xInSafetyCheckMode := FALSE;
_xReleaseManualMode := FALSE;
@@ -621,6 +636,17 @@ CASE _eBMSControlMode OF
END_IF
SM_AUTO();
GVL_SCADA.stAutomaticModeHMI.diSetpointAutomatic := REAL_TO_DINT(_rAutoPowerRequest);
E_BMS_CONTROL_MODE.PRECHARGE:
_eStringOpMode := E_STRING_OPERATING_MODE.PRECHARGE;
_xAllComponentsToManualMode := FALSE;
_xInSafetyCheckMode := FALSE;
_xReleaseManualMode := FALSE;
GVL_MODBUS.stModbusEMSComm.stModbusReg11.eBatteryStatus := E_BATTERY_STATUS.MAINTENANCE;
IF (GVL_SCADA.eRequestedControlMode <> _eBMSControlMode) AND (GVL_SCADA.xCanChangeControlMode) THEN
_eBMSControlMode := GVL_SCADA.eRequestedControlMode;
END_IF
SM_PRECHARGE();
END_CASE
GVL_SCADA.xCanChangeControlMode := _xCanChangeMode;
@@ -1045,7 +1071,95 @@ END_CASE]]></ST>
</Action>
<Action Name="SM_PRECHARGE" Id="{b84aedc8-0039-40a2-8abe-a166eca7bebc}">
<Implementation>
<ST><![CDATA[]]></ST>
<ST><![CDATA[// Start on start button pressed
IF GVL_SCADA.stAutomaticModeHMI.stStartAutoButton.xRequest THEN
// Only start if everything is ok
IF _xStringsAllInAutomaticMode AND (NOT _xStringsErrorActive) THEN
_xStartPrecharge := TRUE;
END_IF
END_IF
// Sto pif stop button pressed
IF GVL_SCADA.stAutomaticModeHMI.stStopAutoButton.xRequest THEN
_xStartPrecharge := FALSE;
END_IF
// State machine
CASE _iStatePrecharge OF
0: // Idle
// Wait for start command
IF _xStartPrecharge AND _xStringsAllInAutomaticMode THEN
_xEnableString := TRUE;
_iStatePrecharge := 10;
_rPowerInverter := 0.0;
_xCanChangeMode := FALSE;
END_IF
10: // Wait for string to be ready
IF _xStringsReady AND (NOT _xStringsErrorActive) THEN
_iStatePrecharge := 30;
END_IF
// Shutdown
IF NOT _xStartPrecharge THEN
_xEnableString := FALSE;
_iStatePrecharge := 0;
_xCanChangeMode := TRUE;
END_IF
// Check for errors
IF _xStringsErrorActive THEN
_iStatePrecharge := 1000;
END_IF
30: // String enabled and dc circuit breaker closed
// Check if the battery should still be active
IF (NOT _xStartPrecharge) THEN
// Start string shutdown
_xEnableString := FALSE;
GVL_MODBUS.stModbusEMSComm.stModbusReg11.eChargeStatus := E_CHARGE_STATUS.UNDEFINED;
GVL_MODBUS.stModbusEMSComm.stModbusReg10.uiActiveParallelMembers := 0;
_iStatePrecharge := 45;
_xCanChangeMode := TRUE;
END_IF
// Check for errors
IF _xStringsErrorActive THEN
_xEnableString := FALSE;
_iStatePrecharge := 1000;
END_IF
45: // Wait for shutdown of string to be done
IF _xStringsOff THEN
_iStatePrecharge := 0;
END_IF
IF _xStartPrecharge THEN
_iStatePrecharge := 0;
END_IF
// Check for errors
IF _xStringsErrorActive THEN
_xEnableString := FALSE;
_iStatePrecharge := 1000;
END_IF
1000: // Error state
_xEnableString := FALSE;
_rPowerInverter := 0.0;
_xCanChangeMode := TRUE;
_xStartPrecharge := FALSE;
_iStatePrecharge := 1010;
1010: // Wait for reset from error state
IF (NOT _xStringsErrorActive) AND (NOT _xStartPrecharge) THEN
// Goto init state
_iStatePrecharge := 0;
_xCanChangeMode := TRUE;
END_IF
END_CASE]]></ST>
</Implementation>
</Action>
<Action Name="SM_SAFETY_CHECK" Id="{6d8e5993-cf32-4980-9ea3-c1fbfa4b8601}">

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<MultiSetting Crc="3276432870" Version="1.2">
<MultiSetting Crc="3644276170" Version="1.2">
<ProjectData>
<Id>1</Id>
<TargetSystem>
@@ -154,6 +154,9 @@
<SubType>EL2912</SubType>
<ObjectId>50462856</ObjectId>
<SafeAddress>28</SafeAddress>
<Customizing>
<Group Id="87605930-f4c2-4c12-816d-f0103cb2103d" Value="2" />
</Customizing>
</TargetSystem>
<SafetyAliasDevice>
<SdsId>36</SdsId>

View File

@@ -269,7 +269,7 @@
</System>
<Plc>
<Project GUID="{9AE64910-5EB2-4866-93FD-EFE059C38C36}" Name="PLC" PrjFilePath="PLC\PLC.plcproj" TmcFilePath="PLC\PLC.tmc" ReloadTmc="true" AmsPort="851" FileArchiveSettings="#x000e" CopyTmcToTarget="true" CopyTpyToTarget="false" SymbolicMapping="true">
<Instance Id="#x08502000" TcSmClass="TComPlcObjDef" KeepUnrestoredLinks="2" TmcHash="{0016C578-B572-1C3C-7D3E-E67B9CAFCEBF}" TmcPath="PLC\PLC.tmc">
<Instance Id="#x08502000" TcSmClass="TComPlcObjDef" KeepUnrestoredLinks="2" TmcHash="{6897FEAD-F22A-6122-B58E-0696201C9577}" TmcPath="PLC\PLC.tmc">
<Name>PLC Instance</Name>
<CLSID ClassFactory="TcPlc30">{08500001-0000-0000-F000-000000000064}</CLSID>
<Vars VarGrpType="2" AreaNo="1">