Added multi string handling and balancing
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<TcPlcObject Version="1.1.0.1" ProductVersion="3.1.4024.12">
|
<TcPlcObject Version="1.1.0.1" ProductVersion="3.1.4026.8">
|
||||||
<DUT Name="E_BMS_CONTROL_MODE" Id="{ab000a04-c252-420d-ac1e-2bf611fa911a}">
|
<DUT Name="E_BMS_CONTROL_MODE" Id="{ab000a04-c252-420d-ac1e-2bf611fa911a}">
|
||||||
<Declaration><![CDATA[{attribute 'qualified_only'}
|
<Declaration><![CDATA[{attribute 'qualified_only'}
|
||||||
{attribute 'strict'}
|
{attribute 'strict'}
|
||||||
@@ -10,7 +10,9 @@ TYPE E_BMS_CONTROL_MODE :
|
|||||||
SAFETY_CHECK := 3,
|
SAFETY_CHECK := 3,
|
||||||
CAPACITY_TEST := 4,
|
CAPACITY_TEST := 4,
|
||||||
MANUAL := 5,
|
MANUAL := 5,
|
||||||
BALANCING := 6
|
BALANCING := 6,
|
||||||
|
CYCLING := 7,
|
||||||
|
PRECHARGE := 8
|
||||||
);
|
);
|
||||||
END_TYPE
|
END_TYPE
|
||||||
]]></Declaration>
|
]]></Declaration>
|
||||||
|
|||||||
@@ -2,6 +2,12 @@
|
|||||||
<TcPlcObject Version="1.1.0.1" ProductVersion="3.1.4026.8">
|
<TcPlcObject Version="1.1.0.1" ProductVersion="3.1.4026.8">
|
||||||
<GVL Name="GVL_CONFIG" Id="{0773bf51-0237-454d-a970-cfd896054edb}">
|
<GVL Name="GVL_CONFIG" Id="{0773bf51-0237-454d-a970-cfd896054edb}">
|
||||||
<Declaration><![CDATA[{attribute 'qualified_only'}
|
<Declaration><![CDATA[{attribute 'qualified_only'}
|
||||||
|
VAR_GLOBAL CONSTANT
|
||||||
|
// ===========================
|
||||||
|
// Number of active strings
|
||||||
|
// ===========================
|
||||||
|
uiNumberOfStrings : UINT := 2;
|
||||||
|
END_VAR
|
||||||
VAR_GLOBAL PERSISTENT
|
VAR_GLOBAL PERSISTENT
|
||||||
// ===========================
|
// ===========================
|
||||||
// Unit hardware config
|
// Unit hardware config
|
||||||
@@ -242,8 +248,8 @@ VAR_GLOBAL PERSISTENT
|
|||||||
rPumpNegolytOnPower : REAL := 65.0;
|
rPumpNegolytOnPower : REAL := 65.0;
|
||||||
|
|
||||||
// Pump discharge segment without inverter power (%)
|
// Pump discharge segment without inverter power (%)
|
||||||
rPumpPosolytDisChrgPower : REAL := 35.0;
|
rPumpPosolytDisChrgPower : REAL := 45.0;
|
||||||
rPumpNegolytDisChrgPower : REAL := 35.0;
|
rPumpNegolytDisChrgPower : REAL := 45.0;
|
||||||
|
|
||||||
// Unit voltage pumps shutoff threshold (Volt)
|
// Unit voltage pumps shutoff threshold (Volt)
|
||||||
rPumpshutoffThreshold : REAL := 15.0;
|
rPumpshutoffThreshold : REAL := 15.0;
|
||||||
@@ -252,7 +258,7 @@ VAR_GLOBAL PERSISTENT
|
|||||||
rMinimumUnitVoltage : REAL := 55.0;
|
rMinimumUnitVoltage : REAL := 55.0;
|
||||||
|
|
||||||
// Maximum unit voltage for fully charged (Volt)
|
// Maximum unit voltage for fully charged (Volt)
|
||||||
rMaximumUnitVoltage : REAL := 79.0;
|
rMaximumUnitVoltage : REAL := 79.5;
|
||||||
|
|
||||||
// Delta value to minimum unit voltage for shutdown discharge (Volt)
|
// Delta value to minimum unit voltage for shutdown discharge (Volt)
|
||||||
rDeltaUnitVoltageShutdownDischarge : REAL := 5.0;
|
rDeltaUnitVoltageShutdownDischarge : REAL := 5.0;
|
||||||
@@ -270,11 +276,11 @@ VAR_GLOBAL PERSISTENT
|
|||||||
|
|
||||||
// Maximum allowed charging power (Watt) per String
|
// Maximum allowed charging power (Watt) per String
|
||||||
// 24.000 W -> 2.000 W per Unit
|
// 24.000 W -> 2.000 W per Unit
|
||||||
diMaxStringChargingPower : DINT := -24_000;
|
diMaxStringChargingPower : DINT := -50_000;
|
||||||
|
|
||||||
// Maximum allowed discharging power (Watt) per String
|
// Maximum allowed discharging power (Watt) per String
|
||||||
// 24.000 W -> 2.000 W per Unit
|
// 24.000 W -> 2.000 W per Unit
|
||||||
diMaxStringDischargePower : DINT := 24_000;
|
diMaxStringDischargePower : DINT := 50_000;
|
||||||
|
|
||||||
// Inverter ip address for string 1
|
// Inverter ip address for string 1
|
||||||
sInverterIpString1 : STRING := '192.168.42.10';
|
sInverterIpString1 : STRING := '192.168.42.10';
|
||||||
|
|||||||
@@ -111,6 +111,9 @@
|
|||||||
<Compile Include="POUs\FB_Module.TcPOU">
|
<Compile Include="POUs\FB_Module.TcPOU">
|
||||||
<SubType>Code</SubType>
|
<SubType>Code</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
|
<Compile Include="POUs\FB_PowerMeter.TcPOU">
|
||||||
|
<SubType>Code</SubType>
|
||||||
|
</Compile>
|
||||||
<Compile Include="POUs\FB_Safety.TcPOU">
|
<Compile Include="POUs\FB_Safety.TcPOU">
|
||||||
<SubType>Code</SubType>
|
<SubType>Code</SubType>
|
||||||
</Compile>
|
</Compile>
|
||||||
@@ -2604,7 +2607,7 @@
|
|||||||
<Type n="String">System.String</Type>
|
<Type n="String">System.String</Type>
|
||||||
<Type n="UInt32">System.UInt32</Type>
|
<Type n="UInt32">System.UInt32</Type>
|
||||||
</TypeList>
|
</TypeList>
|
||||||
</XmlArchive>
|
</XmlArchive>
|
||||||
</PlcProjectOptions>
|
</PlcProjectOptions>
|
||||||
</ProjectExtensions>
|
</ProjectExtensions>
|
||||||
</Project>
|
</Project>
|
||||||
406
PLC/PLC.tmc
406
PLC/PLC.tmc
File diff suppressed because one or more lines are too long
51
PLC/POUs/FB_PowerMeter.TcPOU
Normal file
51
PLC/POUs/FB_PowerMeter.TcPOU
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<TcPlcObject Version="1.1.0.1" ProductVersion="3.1.4026.8">
|
||||||
|
<POU Name="FB_PowerMeter" Id="{9d4159f4-2d3f-4522-a770-c038a26d9d77}" SpecialFunc="None">
|
||||||
|
<Declaration><![CDATA[FUNCTION_BLOCK FB_PowerMeter
|
||||||
|
VAR_INPUT
|
||||||
|
xResetEnergyCounter : BOOL;
|
||||||
|
END_VAR
|
||||||
|
VAR_OUTPUT
|
||||||
|
END_VAR
|
||||||
|
VAR
|
||||||
|
_fbReadRegs : FB_MBReadInputRegs;
|
||||||
|
_fbWriteRegs : FB_MBWriteRegs;
|
||||||
|
|
||||||
|
_fbREResetEnergyCounter : R_TRIG;
|
||||||
|
_xResetEnergyCounter : BOOL;
|
||||||
|
|
||||||
|
_iState : INT := 0;
|
||||||
|
END_VAR
|
||||||
|
]]></Declaration>
|
||||||
|
<Implementation>
|
||||||
|
<ST><![CDATA[_fbREResetEnergyCounter(CLK := xResetEnergyCounter);
|
||||||
|
|
||||||
|
IF _fbREResetEnergyCounter.Q THEN
|
||||||
|
_xResetEnergyCounter := TRUE;
|
||||||
|
END_IF
|
||||||
|
|
||||||
|
CASE _iState OF
|
||||||
|
0: // Idle
|
||||||
|
IF _xResetEnergyCounter THEN
|
||||||
|
_xResetEnergyCounter := FALSE;
|
||||||
|
_iState := 10;
|
||||||
|
END_IF
|
||||||
|
|
||||||
|
10: // Reset energy counters
|
||||||
|
_fbWriteRegs(
|
||||||
|
sIPAddr:= '192.168.42.80',
|
||||||
|
nTCPPort:= 502,
|
||||||
|
nUnitID:= 16#FF ,
|
||||||
|
nQuantity:= ,
|
||||||
|
nMBAddr:= 16#0600,
|
||||||
|
cbLength:= ,
|
||||||
|
pSrcAddr:= ,
|
||||||
|
bExecute:= ,
|
||||||
|
tTimeout:= ,
|
||||||
|
bBusy=> ,
|
||||||
|
bError=> ,
|
||||||
|
nErrId=> );
|
||||||
|
END_CASE]]></ST>
|
||||||
|
</Implementation>
|
||||||
|
</POU>
|
||||||
|
</TcPlcObject>
|
||||||
@@ -140,6 +140,9 @@ VAR
|
|||||||
// Isolatio alarm
|
// Isolatio alarm
|
||||||
_fbIsolationAlarm : FB_TcAlarm;
|
_fbIsolationAlarm : FB_TcAlarm;
|
||||||
|
|
||||||
|
// Safety interlock reset timeout
|
||||||
|
_fbSafetyIntlkTimeoutAlarm : FB_TcAlarm;
|
||||||
|
|
||||||
// Shutdown discharge stopped messages
|
// Shutdown discharge stopped messages
|
||||||
_fbSDDCLevel : FB_TcMessage;
|
_fbSDDCLevel : FB_TcMessage;
|
||||||
_fbSDUnitThreshold : FB_TcMessage;
|
_fbSDUnitThreshold : FB_TcMessage;
|
||||||
@@ -598,6 +601,9 @@ CASE _iState OF
|
|||||||
xCloseDCCB := TRUE;
|
xCloseDCCB := TRUE;
|
||||||
xError := TRUE;
|
xError := TRUE;
|
||||||
xReady := FALSE;
|
xReady := FALSE;
|
||||||
|
IF (NOT _fbSafetyIntlkTimeoutAlarm.bRaised) THEN
|
||||||
|
_fbSafetyIntlkTimeoutAlarm.Raise(0);
|
||||||
|
END_IF
|
||||||
_iState := 1000;
|
_iState := 1000;
|
||||||
END_IF
|
END_IF
|
||||||
|
|
||||||
@@ -688,6 +694,14 @@ CASE _iState OF
|
|||||||
_rPowerInverterInternal := rPowerInverter;
|
_rPowerInverterInternal := rPowerInverter;
|
||||||
END_IF
|
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
|
// Shutdown
|
||||||
IF (NOT xEnable) THEN
|
IF (NOT xEnable) THEN
|
||||||
_xEnable := FALSE;
|
_xEnable := FALSE;
|
||||||
@@ -815,7 +829,7 @@ END_CASE
|
|||||||
// Copy inverter data to SCADA interface
|
// Copy inverter data to SCADA interface
|
||||||
stHMIInterface.stInverterData := stInverterData;
|
stHMIInterface.stInverterData := stInverterData;
|
||||||
|
|
||||||
IF _xAllModulesReady AND _xBalanceOk AND (_iState = 30) THEN
|
IF _xAllModulesReady AND _xBalanceOk AND ((_iState = 30) OR (_iState = 29)) THEN
|
||||||
xReady := TRUE;
|
xReady := TRUE;
|
||||||
ELSE
|
ELSE
|
||||||
xReady := FALSE;
|
xReady := FALSE;
|
||||||
@@ -824,7 +838,15 @@ END_IF
|
|||||||
// Reset inverter startup timeout alarm
|
// Reset inverter startup timeout alarm
|
||||||
IF _fbInverterStartupTimeoutAlarm.bRaised AND xConfirmAlarms THEN
|
IF _fbInverterStartupTimeoutAlarm.bRaised AND xConfirmAlarms THEN
|
||||||
_fbInverterStartupTimeoutAlarm.Clear(0, TRUE);
|
_fbInverterStartupTimeoutAlarm.Clear(0, TRUE);
|
||||||
END_IF]]></ST>
|
END_IF
|
||||||
|
|
||||||
|
// Reset safetyinterlock timeout alarm
|
||||||
|
IF _fbSafetyIntlkTimeoutAlarm.bRaised AND xConfirmAlarms THEN
|
||||||
|
_fbInverterStartupTimeoutAlarm.Clear(0, TRUE);
|
||||||
|
END_IF
|
||||||
|
|
||||||
|
// Copy status to hmi interface
|
||||||
|
stHMIInterface.eStatus := eStatus;]]></ST>
|
||||||
</Implementation>
|
</Implementation>
|
||||||
<Method Name="FB_init" Id="{9e8494eb-1b40-4be9-91c8-810ecbdf7f0c}">
|
<Method Name="FB_init" Id="{9e8494eb-1b40-4be9-91c8-810ecbdf7f0c}">
|
||||||
<Declaration><![CDATA[METHOD FB_init : BOOL
|
<Declaration><![CDATA[METHOD FB_init : BOOL
|
||||||
@@ -867,6 +889,10 @@ _fbSCSConnLost.CreateEx(stEventEntry := TC_EVENTS.General.CommError, bWithConfir
|
|||||||
_sTemp := CONCAT(_sName, ' SCS');
|
_sTemp := CONCAT(_sName, ' SCS');
|
||||||
_fbSCSConnLost.ipArguments.Clear().AddString(_sTemp);
|
_fbSCSConnLost.ipArguments.Clear().AddString(_sTemp);
|
||||||
|
|
||||||
|
// Safety interlock reset timeout alarm
|
||||||
|
_fbSafetyIntlkTimeoutAlarm.CreateEx(stEventEntry := TC_EVENTS.BMSEvents.SafetyIntlkTimeout, bWithConfirmation := TRUE, 0);
|
||||||
|
_fbSafetyIntlkTimeoutAlarm.ipArguments.Clear().AddString(_sName);
|
||||||
|
|
||||||
// Shutdown discharge messages
|
// Shutdown discharge messages
|
||||||
_fbSDDCLevel.CreateEx(TC_EVENTS.BMSEvents.SDDCVoltage, 0);
|
_fbSDDCLevel.CreateEx(TC_EVENTS.BMSEvents.SDDCVoltage, 0);
|
||||||
_fbSDDCLevel.ipArguments.Clear().AddString(_sName);
|
_fbSDDCLevel.ipArguments.Clear().AddString(_sName);
|
||||||
@@ -906,7 +932,8 @@ _fbInverter.Name := _sName;
|
|||||||
|
|
||||||
// Create alarm messages
|
// Create alarm messages
|
||||||
_fbModulesOutOfBalanceAlarm.ipArguments.Clear().AddString(_sName);
|
_fbModulesOutOfBalanceAlarm.ipArguments.Clear().AddString(_sName);
|
||||||
_fbSafetyInterlocksNotOkAlarm.ipArguments.Clear().AddString(_sName);]]></ST>
|
_fbSafetyInterlocksNotOkAlarm.ipArguments.Clear().AddString(_sName);
|
||||||
|
_fbSafetyIntlkTimeoutAlarm.ipArguments.Clear().AddString(_sName);]]></ST>
|
||||||
</Implementation>
|
</Implementation>
|
||||||
</Set>
|
</Set>
|
||||||
</Property>
|
</Property>
|
||||||
|
|||||||
@@ -237,11 +237,14 @@ END_VAR
|
|||||||
_fbNegolytPumpInlet.Name := CONCAT(_sName, ' - Negolyt segment inlet');
|
_fbNegolytPumpInlet.Name := CONCAT(_sName, ' - Negolyt segment inlet');
|
||||||
stHMIInterface.stNS21.sName := 'Negolyt segment inlet';
|
stHMIInterface.stNS21.sName := 'Negolyt segment inlet';
|
||||||
|
|
||||||
_fbPressurePosolytSegmentInlet.Name := CONCAT(_sName, ' - Posolyt Segment Inlet');
|
_fbPressurePosolytSegmentInlet.Name := CONCAT(_sName, ' - Pressure Posolyt Segment Inlet');
|
||||||
_fbPressurePosolytTankInlet.Name := CONCAT(_sName, ' - Posolyt Tank inlet');
|
_fbPressurePosolytTankInlet.Name := CONCAT(_sName, ' - Pressure Posolyt Tank inlet');
|
||||||
|
|
||||||
_fbPressureNegolytSegmentInlet.Name := CONCAT(_sName, ' - Negolyt Segment Inlet');
|
_fbPressureNegolytSegmentInlet.Name := CONCAT(_sName, ' - Pressure Negolyt Segment Inlet');
|
||||||
_fbPressureNegolytTankInlet.Name := CONCAT(_sName, ' - Negolyt Tank Inlet');
|
_fbPressureNegolytTankInlet.Name := CONCAT(_sName, ' - Pressure Negolyt Tank Inlet');
|
||||||
|
|
||||||
|
_fbTempSensorPosolyt.Name := CONCAT(_sName, ' - Temperature Posolyt Tank Inlet');
|
||||||
|
_fbTempSensorNegolyt.Name := CONCAT(_sName, ' - Temperature Negolyt Tank Inlet');
|
||||||
|
|
||||||
_fbVoltageSegment.Name := CONCAT(_sName, ' - Voltage');
|
_fbVoltageSegment.Name := CONCAT(_sName, ' - Voltage');
|
||||||
|
|
||||||
|
|||||||
@@ -134,6 +134,21 @@ VAR
|
|||||||
|
|
||||||
_fbStringReadyTimeout : TON;
|
_fbStringReadyTimeout : TON;
|
||||||
|
|
||||||
|
// Sum of voltage of all active strings
|
||||||
|
_rStringsSumVoltage : REAL;
|
||||||
|
_arPowerString : ARRAY[0..(GVL_CONFIG.uiNumberOfStrings-1)] OF REAL;
|
||||||
|
|
||||||
|
_ui : UINT := 0;
|
||||||
|
_xStringsReady : BOOL;
|
||||||
|
_xStringsErrorActive : BOOL;
|
||||||
|
_xStringsInSchutdownDischargeMode : BOOL;
|
||||||
|
_xStringsShutdownDischargeAllowed : BOOL;
|
||||||
|
_xStringsAllInAutomaticMode : BOOL;
|
||||||
|
_xStringsOff : BOOL;
|
||||||
|
|
||||||
|
_rMaxCurrentInverterDCVoltage : REAL;
|
||||||
|
_rMinCurrentInverterDCVoltage : REAL;
|
||||||
|
|
||||||
_fbModbusRead : FB_MBReadRegs;
|
_fbModbusRead : FB_MBReadRegs;
|
||||||
_wLength : WORD := 49;
|
_wLength : WORD := 49;
|
||||||
xDebugTest : BOOL;
|
xDebugTest : BOOL;
|
||||||
@@ -286,15 +301,15 @@ _tonStartupDelay(IN := TRUE);
|
|||||||
// Call string 1
|
// Call string 1
|
||||||
_afbStrings[0](
|
_afbStrings[0](
|
||||||
stStringModuleVoltageConfig := GVL_CONFIG.stString1VoltageConfig,
|
stStringModuleVoltageConfig := GVL_CONFIG.stString1VoltageConfig,
|
||||||
xEnable := _xEnableString, //AND GVL_CONFIG.xDummy,
|
xEnable := _xEnableString,
|
||||||
xStartBalancing := _xStartBalancing, // AND GVL_CONFIG.xDummy,
|
xStartBalancing := _xStartBalancing,
|
||||||
sInverterIP := GVL_CONFIG.sInverterIpString1,
|
sInverterIP := GVL_CONFIG.sInverterIpString1,
|
||||||
rPowerInverter := _rPowerInverter,
|
rPowerInverter := _arPowerString[0],
|
||||||
xInSafetyCheckMode := _xInSafetyCheckMode,
|
xInSafetyCheckMode := _xInSafetyCheckMode,
|
||||||
stHMIInterface:= GVL_SCADA.stHMIInterface[0],
|
stHMIInterface:= GVL_SCADA.stHMIInterface[0],
|
||||||
xEmergencyStopOk:= _xEmergencyStopOk,
|
xEmergencyStopOk:= _xEmergencyStopOk,
|
||||||
xReleaseErrors:= _xReleaseErrors AND _tonStartupDelay.Q AND _xEtherCatString1Ok,
|
xReleaseErrors:= _xReleaseErrors AND _tonStartupDelay.Q AND _xEtherCatString1Ok,
|
||||||
xReleaseLimitErrors:= _xReleaseLimitsErrors AND _tonStartupDelay.Q,
|
xReleaseLimitErrors:= _xReleaseLimitsErrors AND _tonStartupDelay.Q AND _xEtherCatString1Ok,
|
||||||
xReleaseManualMode := _xReleaseManualMode,
|
xReleaseManualMode := _xReleaseManualMode,
|
||||||
xConfirmAlarms:= _xConfirmAlarms,
|
xConfirmAlarms:= _xConfirmAlarms,
|
||||||
xAllToManualMode := _xAllComponentsToManualMode,
|
xAllToManualMode := _xAllComponentsToManualMode,
|
||||||
@@ -310,11 +325,11 @@ _afbStrings[1](
|
|||||||
xEnable := _xEnableString,
|
xEnable := _xEnableString,
|
||||||
xStartBalancing := _xStartBalancing,
|
xStartBalancing := _xStartBalancing,
|
||||||
sInverterIP := GVL_CONFIG.sInverterIpString2,
|
sInverterIP := GVL_CONFIG.sInverterIpString2,
|
||||||
rPowerInverter := _rPowerInverter,
|
rPowerInverter := _arPowerString[1],
|
||||||
xInSafetyCheckMode := _xInSafetyCheckMode,
|
xInSafetyCheckMode := _xInSafetyCheckMode,
|
||||||
stHMIInterface:= GVL_SCADA.stHMIInterface[1],
|
stHMIInterface:= GVL_SCADA.stHMIInterface[1],
|
||||||
xEmergencyStopOk:= _xEmergencyStopOk,
|
xEmergencyStopOk:= _xEmergencyStopOk,
|
||||||
xReleaseErrors:= _xReleaseErrors AND _tonStartupDelay.Q AND _xEtherCatString2Ok AND FALSE,
|
xReleaseErrors:= _xReleaseErrors AND _tonStartupDelay.Q AND _xEtherCatString2Ok,
|
||||||
xReleaseLimitErrors:= _xReleaseLimitsErrors AND _tonStartupDelay.Q AND _xEtherCatString2Ok,
|
xReleaseLimitErrors:= _xReleaseLimitsErrors AND _tonStartupDelay.Q AND _xEtherCatString2Ok,
|
||||||
xReleaseManualMode := _xReleaseManualMode,
|
xReleaseManualMode := _xReleaseManualMode,
|
||||||
xConfirmAlarms:= _xConfirmAlarms,
|
xConfirmAlarms:= _xConfirmAlarms,
|
||||||
@@ -325,12 +340,85 @@ IF _afbStrings[1].xError THEN
|
|||||||
_xErrorActive := TRUE;
|
_xErrorActive := TRUE;
|
||||||
END_IF
|
END_IF
|
||||||
|
|
||||||
|
// ===============================
|
||||||
|
// Get global string status information
|
||||||
|
// ===============================
|
||||||
|
_xStringsReady := TRUE;
|
||||||
|
_xStringsErrorActive := FALSE;
|
||||||
|
_xStringsInSchutdownDischargeMode := FALSE;
|
||||||
|
_xStringsShutdownDischargeAllowed := TRUE;
|
||||||
|
_xStringsAllInAutomaticMode := TRUE;
|
||||||
|
_xStringsOff := TRUE;
|
||||||
|
_rMaxCurrentInverterDCVoltage := 0.0;
|
||||||
|
_rMinCurrentInverterDCVoltage := 10_000;
|
||||||
|
_rHighestSegmentVoltage := 0.0;
|
||||||
|
_rSmallestSegmentVoltage := 1_000.0;
|
||||||
|
|
||||||
|
FOR _ui := 0 TO (GVL_CONFIG.uiNumberOfStrings-1) DO
|
||||||
|
// Check ready state
|
||||||
|
IF (NOT _afbStrings[_ui].xReady) THEN
|
||||||
|
_xStringsReady := FALSE;
|
||||||
|
END_IF
|
||||||
|
|
||||||
|
// Check error state
|
||||||
|
IF _afbStrings[_ui].xError THEN
|
||||||
|
_xStringsErrorActive := TRUE;
|
||||||
|
END_IF
|
||||||
|
|
||||||
|
// Check for shutdown discharge mode
|
||||||
|
IF _afbStrings[_ui].xInShutdownDischargeMode THEN
|
||||||
|
_xStringsInSchutdownDischargeMode := TRUE;
|
||||||
|
END_IF
|
||||||
|
|
||||||
|
// Check for shutdown discharge allowed
|
||||||
|
IF (NOT _afbStrings[_ui].xShutdownDischargeAllowed) THEN
|
||||||
|
_xStringsShutdownDischargeAllowed := FALSE;
|
||||||
|
END_IF
|
||||||
|
|
||||||
|
// Check for all in automatic mode
|
||||||
|
IF (NOT _afbStrings[_ui].xAllModulesInAutoMode) THEN
|
||||||
|
_xStringsAllInAutomaticMode := FALSE;
|
||||||
|
END_IF
|
||||||
|
|
||||||
|
// Check for all strings off
|
||||||
|
IF (NOT _afbStrings[_ui].xOff) THEN
|
||||||
|
_xStringsOff := FALSE;
|
||||||
|
END_IF
|
||||||
|
|
||||||
|
// Check for max dc voltage
|
||||||
|
IF _rMaxCurrentInverterDCVoltage < _afbStrings[_ui].stInverterData.rActDCVoltage THEN
|
||||||
|
_rMaxCurrentInverterDCVoltage := _afbStrings[_ui].stInverterData.rActDCVoltage;
|
||||||
|
END_IF
|
||||||
|
|
||||||
|
// Check for min DC voltage
|
||||||
|
IF _rMinCurrentInverterDCVoltage > _afbStrings[_ui].stInverterData.rActDCVoltage THEN
|
||||||
|
_rMinCurrentInverterDCVoltage := _afbStrings[_ui].stInverterData.rActDCVoltage;
|
||||||
|
END_IF
|
||||||
|
|
||||||
|
// Calculate highest segment voltage
|
||||||
|
IF _rSmallestSegmentVoltage > _afbStrings[_ui].rSmallestSegmentVoltage THEN
|
||||||
|
_rSmallestSegmentVoltage := _afbStrings[_ui].rSmallestSegmentVoltage;
|
||||||
|
END_IF
|
||||||
|
|
||||||
|
// Calculate lowest segment voltage
|
||||||
|
IF _rHighestSegmentVoltage < _afbStrings[_ui].rHighestSegmentVoltage THEN
|
||||||
|
_rHighestSegmentVoltage := _afbStrings[_ui].rHighestSegmentVoltage;
|
||||||
|
END_IF
|
||||||
|
END_FOR
|
||||||
|
|
||||||
|
// ===============================
|
||||||
|
// Calculate sum power for string balancing
|
||||||
|
// ===============================
|
||||||
|
_rStringsSumVoltage := _afbStrings[0].rCurrentVoltage + _afbStrings[1].rCurrentVoltage;
|
||||||
|
|
||||||
|
|
||||||
// ===============================
|
// ===============================
|
||||||
// Hardware reset button part 2
|
// Hardware reset button part 2
|
||||||
// ===============================
|
// ===============================
|
||||||
_xShowErrorOnButton := _xErrorActive;
|
_xShowErrorOnButton := _xErrorActive;
|
||||||
|
|
||||||
// HMI Feedback
|
// HMI Feedback
|
||||||
|
(*
|
||||||
GVL_SCADA.stHMIInterface[0].rVoltage := _afbStrings[0].rCurrentVoltage;
|
GVL_SCADA.stHMIInterface[0].rVoltage := _afbStrings[0].rCurrentVoltage;
|
||||||
IF _afbStrings[0].eStatus = E_COMPONENT_STATUS.ON THEN
|
IF _afbStrings[0].eStatus = E_COMPONENT_STATUS.ON THEN
|
||||||
IF _iState = 30 AND _rPowerInverter > 0 THEN
|
IF _iState = 30 AND _rPowerInverter > 0 THEN
|
||||||
@@ -343,6 +431,7 @@ IF _afbStrings[0].eStatus = E_COMPONENT_STATUS.ON THEN
|
|||||||
ELSE
|
ELSE
|
||||||
GVL_SCADA.stHMIInterface[0].eStatus :=_afbStrings[0].eStatus;
|
GVL_SCADA.stHMIInterface[0].eStatus :=_afbStrings[0].eStatus;
|
||||||
END_IF
|
END_IF
|
||||||
|
*)
|
||||||
|
|
||||||
// ===============================
|
// ===============================
|
||||||
// Read modbus request count
|
// Read modbus request count
|
||||||
@@ -381,25 +470,25 @@ _fbModbusRead(
|
|||||||
// Copy data to modbus registers
|
// Copy data to modbus registers
|
||||||
// ===============================
|
// ===============================
|
||||||
// Modbus current inverter values
|
// Modbus current inverter values
|
||||||
GVL_MODBUS.stModbusEMSComm.stModbusReg11.diCurrentActivePower := REAL_TO_DINT(_afbStrings[_uiDebugCurrentString].stInverterData.rActACPower);
|
GVL_MODBUS.stModbusEMSComm.stModbusReg11.diCurrentActivePower := 0;
|
||||||
GVL_MODBUS.stModbusEMSComm.stModbusReg11.diCurrentReactivePower := REAL_TO_DINT(_afbStrings[_uiDebugCurrentString].stInverterData.rActReactivePower);
|
GVL_MODBUS.stModbusEMSComm.stModbusReg11.diCurrentReactivePower := 0;
|
||||||
GVL_MODBUS.stModbusEMSComm.stModbusReg11.diTotalACCurrentPhase1 := REAL_TO_DINT(_afbStrings[_uiDebugCurrentString].stInverterData.rActtACPhaseACurrent);
|
GVL_MODBUS.stModbusEMSComm.stModbusReg11.diTotalACCurrentPhase1 := 0;
|
||||||
GVL_MODBUS.stModbusEMSComm.stModbusReg11.diTotalACCurrentPhase2 := REAL_TO_DINT(_afbStrings[_uiDebugCurrentString].stInverterData.rActtACPhaseBCurrent);
|
GVL_MODBUS.stModbusEMSComm.stModbusReg11.diTotalACCurrentPhase2 := 0;
|
||||||
GVL_MODBUS.stModbusEMSComm.stModbusReg11.diTotalACCurrentPhase3 := REAL_TO_DINT(_afbStrings[_uiDebugCurrentString].stInverterData.rActtACPhaseCCurrent);
|
GVL_MODBUS.stModbusEMSComm.stModbusReg11.diTotalACCurrentPhase3 := 0;
|
||||||
|
FOR _ui := 0 TO (GVL_CONFIG.uiNumberOfStrings-1) DO
|
||||||
|
GVL_MODBUS.stModbusEMSComm.stModbusReg11.diCurrentActivePower := GVL_MODBUS.stModbusEMSComm.stModbusReg11.diCurrentActivePower + REAL_TO_DINT(_afbStrings[_ui].stInverterData.rActACPower);
|
||||||
|
GVL_MODBUS.stModbusEMSComm.stModbusReg11.diCurrentReactivePower := GVL_MODBUS.stModbusEMSComm.stModbusReg11.diCurrentReactivePower + REAL_TO_DINT(_afbStrings[_ui].stInverterData.rActReactivePower);
|
||||||
|
GVL_MODBUS.stModbusEMSComm.stModbusReg11.diTotalACCurrentPhase1 := GVL_MODBUS.stModbusEMSComm.stModbusReg11.diTotalACCurrentPhase1 + REAL_TO_DINT(_afbStrings[_ui].stInverterData.rActtACPhaseACurrent);
|
||||||
|
GVL_MODBUS.stModbusEMSComm.stModbusReg11.diTotalACCurrentPhase2 := GVL_MODBUS.stModbusEMSComm.stModbusReg11.diTotalACCurrentPhase2 + REAL_TO_DINT(_afbStrings[_ui].stInverterData.rActtACPhaseBCurrent);
|
||||||
|
GVL_MODBUS.stModbusEMSComm.stModbusReg11.diTotalACCurrentPhase3 := GVL_MODBUS.stModbusEMSComm.stModbusReg11.diTotalACCurrentPhase3 + REAL_TO_DINT(_afbStrings[_ui].stInverterData.rActtACPhaseCCurrent);
|
||||||
|
END_FOR
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Set Modbus mirror values
|
// Set Modbus mirror values
|
||||||
GVL_MODBUS.stModbusEMSComm.stModbusReg11.diSetpointActivePowerMirror := GVL_MODBUS.stModbusEMSComm.stModbusReg12.diSetpointActivePower;
|
GVL_MODBUS.stModbusEMSComm.stModbusReg11.diSetpointActivePowerMirror := GVL_MODBUS.stModbusEMSComm.stModbusReg12.diSetpointActivePower;
|
||||||
GVL_MODBUS.stModbusEMSComm.stModbusReg11.rSetpointCosPhiMirror := GVL_MODBUS.stModbusEMSComm.stModbusReg12.rSetpointCosPhi;
|
GVL_MODBUS.stModbusEMSComm.stModbusReg11.rSetpointCosPhiMirror := GVL_MODBUS.stModbusEMSComm.stModbusReg12.rSetpointCosPhi;
|
||||||
|
|
||||||
|
|
||||||
// ===============================
|
|
||||||
// Calculate highest and lowest
|
|
||||||
// segment voltage
|
|
||||||
// ===============================
|
|
||||||
_rSmallestSegmentVoltage := _afbStrings[_uiDebugCurrentString].rSmallestSegmentVoltage;
|
|
||||||
_rHighestSegmentVoltage := _afbStrings[_uiDebugCurrentString].rHighestSegmentVoltage;
|
|
||||||
|
|
||||||
// ===============================
|
// ===============================
|
||||||
// State machine
|
// State machine
|
||||||
// ===============================
|
// ===============================
|
||||||
@@ -464,6 +553,16 @@ CASE _eBMSControlMode OF
|
|||||||
_eBMSControlMode := GVL_SCADA.eRequestedControlMode;
|
_eBMSControlMode := GVL_SCADA.eRequestedControlMode;
|
||||||
END_IF
|
END_IF
|
||||||
SM_BALANCING();
|
SM_BALANCING();
|
||||||
|
|
||||||
|
E_BMS_CONTROL_MODE.CYCLING:
|
||||||
|
_xAllComponentsToManualMode := FALSE;
|
||||||
|
_xInSafetyCheckMode := FALSE;
|
||||||
|
_xReleaseManualMode := FALSE;
|
||||||
|
_rAutoPowerRequest := DINT_TO_REAL(GVL_MODBUS.stModbusEMSComm.stModbusReg12.diSetpointActivePower);
|
||||||
|
IF (GVL_SCADA.eRequestedControlMode <> _eBMSControlMode) AND (GVL_SCADA.xCanChangeControlMode) THEN
|
||||||
|
_eBMSControlMode := GVL_SCADA.eRequestedControlMode;
|
||||||
|
END_IF
|
||||||
|
SM_AUTO();
|
||||||
END_CASE
|
END_CASE
|
||||||
|
|
||||||
GVL_SCADA.xCanChangeControlMode := _xCanChangeMode;
|
GVL_SCADA.xCanChangeControlMode := _xCanChangeMode;
|
||||||
@@ -514,13 +613,13 @@ END_IF]]></ST>
|
|||||||
10: // Wait for string to be ready
|
10: // Wait for string to be ready
|
||||||
_fbStringReadyTimeout(IN := TRUE, PT := GVL_CONFIG.timStringReadyTimeout);
|
_fbStringReadyTimeout(IN := TRUE, PT := GVL_CONFIG.timStringReadyTimeout);
|
||||||
|
|
||||||
IF _afbStrings[_uiDebugCurrentString].xReady AND (NOT _afbStrings[_uiDebugCurrentString].xError) THEN
|
IF _xStringsReady AND (NOT _xStringsErrorActive) THEN
|
||||||
_fbStringReadyTimeout(IN := FALSE);
|
_fbStringReadyTimeout(IN := FALSE);
|
||||||
_rPowerInverter := 0.0;
|
_rPowerInverter := 0.0;
|
||||||
_iState := 30;
|
_iState := 30;
|
||||||
END_IF
|
END_IF
|
||||||
|
|
||||||
IF _afbStrings[_uiDebugCurrentString].xError OR _fbStringReadyTimeout.Q THEN
|
IF _xStringsErrorActive OR _fbStringReadyTimeout.Q THEN
|
||||||
_fbStringReadyTimeout(IN := FALSE);
|
_fbStringReadyTimeout(IN := FALSE);
|
||||||
_xEnableString := FALSE;
|
_xEnableString := FALSE;
|
||||||
GVL_SCADA.stAutomaticModeHMI.diSetpointAutomatic := 0;
|
GVL_SCADA.stAutomaticModeHMI.diSetpointAutomatic := 0;
|
||||||
@@ -528,6 +627,7 @@ END_IF]]></ST>
|
|||||||
_iState := 45;
|
_iState := 45;
|
||||||
END_IF
|
END_IF
|
||||||
|
|
||||||
|
|
||||||
IF (ABS(_rAutoPowerRequest) < DINT_TO_REAL(GVL_CONFIG.diMinimumAbsPowerForEnable)) THEN
|
IF (ABS(_rAutoPowerRequest) < DINT_TO_REAL(GVL_CONFIG.diMinimumAbsPowerForEnable)) THEN
|
||||||
_fbStringReadyTimeout(IN := FALSE);
|
_fbStringReadyTimeout(IN := FALSE);
|
||||||
_xEnableString := FALSE;
|
_xEnableString := FALSE;
|
||||||
@@ -574,7 +674,13 @@ END_IF]]></ST>
|
|||||||
END_IF
|
END_IF
|
||||||
|
|
||||||
// Shutdown triggered by battery fully charged
|
// Shutdown triggered by battery fully charged
|
||||||
IF GVL_MODBUS.stModbusEMSComm.stModbusReg11.eChargeStatus = E_CHARGE_STATUS.CHARGING AND ((_afbStrings[_uiDebugCurrentString].stInverterData.rActDCVoltage >= GVL_CONFIG.rStringFullyChargedVoltage) OR _rHighestSegmentVoltage >= GVL_CONFIG.rMaximumUnitVoltage) THEN
|
IF GVL_MODBUS.stModbusEMSComm.stModbusReg11.eChargeStatus = E_CHARGE_STATUS.CHARGING AND ((_rMaxCurrentInverterDCVoltage >= GVL_CONFIG.rStringFullyChargedVoltage) OR _rHighestSegmentVoltage >= GVL_CONFIG.rMaximumUnitVoltage) THEN
|
||||||
|
|
||||||
|
IF (_eBMSControlMode = E_BMS_CONTROL_MODE.CYCLING) THEN
|
||||||
|
GVL_MODBUS.stModbusEMSComm.stModbusReg12.diSetpointActivePower := GVL_MODBUS.stModbusEMSComm.stModbusReg12.diSetpointActivePower * -1;
|
||||||
|
// Change of charge discharge should be handled in next cycle by sasme state
|
||||||
|
// GVL_MODBUS.stModbusEMSComm.stModbusReg11.eChargeStatus := E_CHARGE_STATUS.DISCHARGING;
|
||||||
|
ELSE
|
||||||
_tonBeginShutdown(In := FALSE);
|
_tonBeginShutdown(In := FALSE);
|
||||||
|
|
||||||
// Send message
|
// Send message
|
||||||
@@ -595,8 +701,15 @@ END_IF]]></ST>
|
|||||||
_iState := 35;
|
_iState := 35;
|
||||||
END_IF
|
END_IF
|
||||||
|
|
||||||
|
END_IF
|
||||||
|
|
||||||
// Shutdown triggered by battery empty
|
// Shutdown triggered by battery empty
|
||||||
IF GVL_MODBUS.stModbusEMSComm.stModbusReg11.eChargeStatus = E_CHARGE_STATUS.DISCHARGING AND ((_afbStrings[_uiDebugCurrentString].stInverterData.rActDCVoltage <= GVL_CONFIG.rStringEmptyVoltage) OR _rSmallestSegmentVoltage <= GVL_CONFIG.rMinimumUnitVoltage) THEN
|
IF GVL_MODBUS.stModbusEMSComm.stModbusReg11.eChargeStatus = E_CHARGE_STATUS.DISCHARGING AND ((_rMinCurrentInverterDCVoltage <= GVL_CONFIG.rStringEmptyVoltage) OR _rSmallestSegmentVoltage <= GVL_CONFIG.rMinimumUnitVoltage) THEN
|
||||||
|
IF (_eBMSControlMode = E_BMS_CONTROL_MODE.CYCLING) THEN
|
||||||
|
GVL_MODBUS.stModbusEMSComm.stModbusReg12.diSetpointActivePower := GVL_MODBUS.stModbusEMSComm.stModbusReg12.diSetpointActivePower * -1;
|
||||||
|
// Change of charge discharge should be handled in next cycle by sasme state
|
||||||
|
// GVL_MODBUS.stModbusEMSComm.stModbusReg11.eChargeStatus := E_CHARGE_STATUS.CHARGING;
|
||||||
|
ELSE
|
||||||
_tonBeginShutdown(In := FALSE);
|
_tonBeginShutdown(In := FALSE);
|
||||||
|
|
||||||
// Send Message
|
// Send Message
|
||||||
@@ -616,9 +729,10 @@ END_IF]]></ST>
|
|||||||
GVL_MODBUS.stModbusEMSComm.stModbusReg10.uiActiveParallelMembers := 0;
|
GVL_MODBUS.stModbusEMSComm.stModbusReg10.uiActiveParallelMembers := 0;
|
||||||
_iState := 35;
|
_iState := 35;
|
||||||
END_IF
|
END_IF
|
||||||
|
END_IF
|
||||||
|
|
||||||
// Check for errors
|
// Check for errors
|
||||||
IF _afbStrings[_uiDebugCurrentString].xError THEN
|
IF _xStringsErrorActive THEN
|
||||||
_xEnableString := FALSE;
|
_xEnableString := FALSE;
|
||||||
_tonBeginShutdown(In := FALSE);
|
_tonBeginShutdown(In := FALSE);
|
||||||
GVL_SCADA.stAutomaticModeHMI.diSetpointAutomatic := 0;
|
GVL_SCADA.stAutomaticModeHMI.diSetpointAutomatic := 0;
|
||||||
@@ -627,7 +741,7 @@ END_IF]]></ST>
|
|||||||
END_IF
|
END_IF
|
||||||
|
|
||||||
35: // Wait for string to be in shutdown discharge mode
|
35: // Wait for string to be in shutdown discharge mode
|
||||||
IF _afbStrings[_uiDebugCurrentString].xInShutdownDischargeMode THEN
|
IF _xStringsInSchutdownDischargeMode THEN
|
||||||
// Check if we are allowed to discharge during shutdown with inverter
|
// Check if we are allowed to discharge during shutdown with inverter
|
||||||
IF GVL_CONFIG.xShutdownDischargeWithInverter THEN
|
IF GVL_CONFIG.xShutdownDischargeWithInverter THEN
|
||||||
_iState := 40;
|
_iState := 40;
|
||||||
@@ -641,12 +755,12 @@ END_IF]]></ST>
|
|||||||
END_IF
|
END_IF
|
||||||
|
|
||||||
// Check for errors
|
// Check for errors
|
||||||
IF _afbStrings[_uiDebugCurrentString].xError THEN
|
IF _xStringsErrorActive THEN
|
||||||
_iState := 1000;
|
_iState := 1000;
|
||||||
END_IF
|
END_IF
|
||||||
|
|
||||||
40: // Wait for inverter discharge done
|
40: // Wait for inverter discharge done
|
||||||
IF _afbStrings[_uiDebugCurrentString].xShutdownDischargeAllowed THEN
|
IF _xStringsShutdownDischargeAllowed THEN
|
||||||
_rPowerInverter := GVL_CONFIG.rAbsShutdownDischargePower;
|
_rPowerInverter := GVL_CONFIG.rAbsShutdownDischargePower;
|
||||||
ELSE
|
ELSE
|
||||||
_rPowerInverter := 0.0;
|
_rPowerInverter := 0.0;
|
||||||
@@ -657,29 +771,30 @@ END_IF]]></ST>
|
|||||||
END_IF
|
END_IF
|
||||||
|
|
||||||
// Check for errors
|
// Check for errors
|
||||||
IF _afbStrings[_uiDebugCurrentString].xError THEN
|
IF _xStringsErrorActive THEN
|
||||||
_iState := 1000;
|
_iState := 1000;
|
||||||
END_IF
|
END_IF
|
||||||
|
|
||||||
// Restart if possible
|
// Restart if possible
|
||||||
IF (ABS(_rAutoPowerRequest) > DINT_TO_REAL(GVL_CONFIG.diMinimumAbsPowerForEnable)) AND (NOT _afbStrings[_uiDebugCurrentString].xError) AND _afbStrings[_uiDebugCurrentString].xAllModulesInAutoMode THEN
|
IF (ABS(_rAutoPowerRequest) > DINT_TO_REAL(GVL_CONFIG.diMinimumAbsPowerForEnable)) AND (NOT _xStringsErrorActive) AND _xStringsAllInAutomaticMode THEN
|
||||||
_iState := 5;
|
_iState := 5;
|
||||||
END_IF
|
END_IF
|
||||||
|
|
||||||
45: // Wait for shutdown of string to be done
|
45: // Wait for shutdown of string to be done
|
||||||
IF (NOT _afbStrings[_uiDebugCurrentString].xInShutdownDischargeMode) AND _afbStrings[_uiDebugCurrentString].xOff THEN
|
IF (NOT _xStringsInSchutdownDischargeMode) AND _xStringsOff THEN
|
||||||
GVL_MODBUS.stModbusEMSComm.stModbusReg11.eBatteryStatus := E_BATTERY_STATUS.OFF;
|
GVL_MODBUS.stModbusEMSComm.stModbusReg11.eBatteryStatus := E_BATTERY_STATUS.OFF;
|
||||||
GVL_MODBUS.stModbusEMSComm.stModbusReg11.eChargeStatus := E_CHARGE_STATUS.UNDEFINED;
|
GVL_MODBUS.stModbusEMSComm.stModbusReg11.eChargeStatus := E_CHARGE_STATUS.UNDEFINED;
|
||||||
_iState := 0;
|
_iState := 0;
|
||||||
END_IF
|
END_IF
|
||||||
|
|
||||||
// Restart if possible
|
// Restart if possible
|
||||||
IF (ABS(_rAutoPowerRequest) > DINT_TO_REAL(GVL_CONFIG.diMinimumAbsPowerForEnable)) AND (NOT _afbStrings[_uiDebugCurrentString].xError) AND _afbStrings[_uiDebugCurrentString].xAllModulesInAutoMode THEN
|
IF (ABS(_rAutoPowerRequest) > DINT_TO_REAL(GVL_CONFIG.diMinimumAbsPowerForEnable)) AND (NOT _xStringsErrorActive) AND _xStringsAllInAutomaticMode THEN
|
||||||
|
_xCanChangeMode := FALSE;
|
||||||
_iState := 5;
|
_iState := 5;
|
||||||
END_IF
|
END_IF
|
||||||
|
|
||||||
// Check for errors
|
// Check for errors
|
||||||
IF _afbStrings[_uiDebugCurrentString].xError THEN
|
IF _xStringsErrorActive THEN
|
||||||
_iState := 1000;
|
_iState := 1000;
|
||||||
END_IF
|
END_IF
|
||||||
|
|
||||||
@@ -691,7 +806,7 @@ END_IF]]></ST>
|
|||||||
_iState := 1010;
|
_iState := 1010;
|
||||||
|
|
||||||
1010: // Wait for reset from error state
|
1010: // Wait for reset from error state
|
||||||
IF (_rAutoPowerRequest = 0.0) AND (NOT _afbStrings[_uiDebugCurrentString].xError) AND _xConfirmAlarms THEN
|
IF (_rAutoPowerRequest = 0.0) AND (NOT _xStringsErrorActive) AND _xConfirmAlarms THEN
|
||||||
// Reset modbus error register
|
// Reset modbus error register
|
||||||
GVL_MODBUS.stModbusEMSComm.stModbusReg11.lwErrorBitmap := 0;
|
GVL_MODBUS.stModbusEMSComm.stModbusReg11.lwErrorBitmap := 0;
|
||||||
|
|
||||||
@@ -703,7 +818,28 @@ END_IF]]></ST>
|
|||||||
|
|
||||||
_xCanChangeMode := TRUE;
|
_xCanChangeMode := TRUE;
|
||||||
END_IF
|
END_IF
|
||||||
END_CASE]]></ST>
|
END_CASE
|
||||||
|
|
||||||
|
// Calculate string power balancing
|
||||||
|
IF _rStringsSumVoltage <> 0 THEN
|
||||||
|
FOR _ui := 0 TO (GVL_CONFIG.uiNumberOfStrings-1) DO
|
||||||
|
// Discharging
|
||||||
|
IF _rPowerInverter > 0 THEN
|
||||||
|
_arPowerString[_ui] := _rPowerInverter * (_afbStrings[_ui].rCurrentVoltage / _rStringsSumVoltage);
|
||||||
|
// Charging
|
||||||
|
ELSIF _rPowerInverter < 0 THEN
|
||||||
|
_arPowerString[_ui] := _rPowerInverter * (1.0 - (_afbStrings[_ui].rCurrentVoltage / _rStringsSumVoltage));
|
||||||
|
// Nothing
|
||||||
|
ELSE
|
||||||
|
_arPowerString[_ui] := 0.0;
|
||||||
|
END_IF
|
||||||
|
END_FOR
|
||||||
|
ELSE
|
||||||
|
FOR _ui := 0 TO (GVL_CONFIG.uiNumberOfStrings-1) DO
|
||||||
|
_arPowerString[_ui] := 0.0;
|
||||||
|
END_FOR
|
||||||
|
END_IF
|
||||||
|
]]></ST>
|
||||||
</Implementation>
|
</Implementation>
|
||||||
</Action>
|
</Action>
|
||||||
<Action Name="SM_BALANCING" Id="{f1f90032-de29-468d-899c-50bfb54e48e0}">
|
<Action Name="SM_BALANCING" Id="{f1f90032-de29-468d-899c-50bfb54e48e0}">
|
||||||
@@ -760,6 +896,11 @@ END_CASE]]></ST>
|
|||||||
<ST><![CDATA[_xCanChangeMode := TRUE;]]></ST>
|
<ST><![CDATA[_xCanChangeMode := TRUE;]]></ST>
|
||||||
</Implementation>
|
</Implementation>
|
||||||
</Action>
|
</Action>
|
||||||
|
<Action Name="SM_PRECHARGE" Id="{b84aedc8-0039-40a2-8abe-a166eca7bebc}">
|
||||||
|
<Implementation>
|
||||||
|
<ST><![CDATA[]]></ST>
|
||||||
|
</Implementation>
|
||||||
|
</Action>
|
||||||
<Action Name="SM_SAFETY_CHECK" Id="{6d8e5993-cf32-4980-9ea3-c1fbfa4b8601}">
|
<Action Name="SM_SAFETY_CHECK" Id="{6d8e5993-cf32-4980-9ea3-c1fbfa4b8601}">
|
||||||
<Implementation>
|
<Implementation>
|
||||||
<ST><![CDATA[// Start on start button pressed
|
<ST><![CDATA[// Start on start button pressed
|
||||||
@@ -796,6 +937,7 @@ CASE _iStateSafetyCheck OF
|
|||||||
IF NOT _xStartSafetyCheck THEN
|
IF NOT _xStartSafetyCheck THEN
|
||||||
_xEnableString := FALSE;
|
_xEnableString := FALSE;
|
||||||
_iStateSafetyCheck := 0;
|
_iStateSafetyCheck := 0;
|
||||||
|
_xCanChangeMode := TRUE;
|
||||||
END_IF
|
END_IF
|
||||||
|
|
||||||
// Check for errors
|
// Check for errors
|
||||||
|
|||||||
@@ -797,8 +797,8 @@ CASE _iState OF
|
|||||||
IF _tonPollingTimer.Q THEN
|
IF _tonPollingTimer.Q THEN
|
||||||
_tonPollingTimer(IN := FALSE);
|
_tonPollingTimer(IN := FALSE);
|
||||||
_iState := 70;
|
_iState := 70;
|
||||||
ELSIF ABS(rPower - _rOldPower) > 0.1 THEN
|
ELSIF (ABS(rPower - _rOldPower) > 0.1) THEN
|
||||||
_tonPollingTimer(IN := FALSE);
|
//_tonPollingTimer(IN := FALSE);
|
||||||
// If power has ben changed, goto set power limit mode
|
// If power has ben changed, goto set power limit mode
|
||||||
_iState := 40;
|
_iState := 40;
|
||||||
// Calculate power to write to register
|
// Calculate power to write to register
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<safetyApplicationLanguageDiagram Crc="518324452" dslVersion="1.4.0.0" Id="b1b6b4f5-2a37-4725-94da-4b4e0499132e" absoluteBounds="0, 0, 28.875, 23.125" name="TwinSAFE">
|
<safetyApplicationLanguageDiagram Crc="71004029" dslVersion="1.5.0.0" Id="b1b6b4f5-2a37-4725-94da-4b4e0499132e" absoluteBounds="0, 0, 28.875, 23.125" name="TwinSAFE">
|
||||||
<safetyApplicationMoniker name="/" />
|
<safetyApplicationMoniker name="/" />
|
||||||
<nestedChildShapes>
|
<nestedChildShapes>
|
||||||
<networkSwimLane Id="cdd3abf9-920f-4dee-bac6-a51b58482f55" absoluteBounds="0, 0, 28.875, 4.25">
|
<networkSwimLane Id="cdd3abf9-920f-4dee-bac6-a51b58482f55" absoluteBounds="0, 0, 28.875, 4.25">
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<MultiSetting Crc="1554816737" Version="1.2">
|
<MultiSetting Crc="227871081" Version="1.2">
|
||||||
<ProjectData>
|
<ProjectData>
|
||||||
<Id>1</Id>
|
<Id>1</Id>
|
||||||
<TargetSystem>
|
<TargetSystem>
|
||||||
@@ -214,6 +214,9 @@
|
|||||||
<SubType>EL2912</SubType>
|
<SubType>EL2912</SubType>
|
||||||
<ObjectId>50462856</ObjectId>
|
<ObjectId>50462856</ObjectId>
|
||||||
<SafeAddress>28</SafeAddress>
|
<SafeAddress>28</SafeAddress>
|
||||||
|
<Customizing>
|
||||||
|
<Group Id="87605930-f4c2-4c12-816d-f0103cb2103d" Value="3" />
|
||||||
|
</Customizing>
|
||||||
</TargetSystem>
|
</TargetSystem>
|
||||||
<SafetyAliasDevice>
|
<SafetyAliasDevice>
|
||||||
<SdsId>36</SdsId>
|
<SdsId>36</SdsId>
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<TargetSystemConfig Crc="960810402" Version="1.5">
|
<TargetSystemConfig Crc="2950660737" Version="1.5">
|
||||||
<TargetSystemType>HSafetyPLC</TargetSystemType>
|
<TargetSystemType>HSafetyPLC</TargetSystemType>
|
||||||
<TargetSystemSubType>EL2912</TargetSystemSubType>
|
<TargetSystemSubType>EL2912</TargetSystemSubType>
|
||||||
<IsExternalDevice>false</IsExternalDevice>
|
<IsExternalDevice>false</IsExternalDevice>
|
||||||
@@ -19,4 +19,7 @@
|
|||||||
<TakeOverSafetyAliasDeviceNamesInProcessImage>true</TakeOverSafetyAliasDeviceNamesInProcessImage>
|
<TakeOverSafetyAliasDeviceNamesInProcessImage>true</TakeOverSafetyAliasDeviceNamesInProcessImage>
|
||||||
<TakeOverStandardAliasDeviceNamesInProcessImage>true</TakeOverStandardAliasDeviceNamesInProcessImage>
|
<TakeOverStandardAliasDeviceNamesInProcessImage>true</TakeOverStandardAliasDeviceNamesInProcessImage>
|
||||||
<BackupRestore Needed="0" Activated="false" RestoreUserAdministration="false" />
|
<BackupRestore Needed="0" Activated="false" RestoreUserAdministration="false" />
|
||||||
|
<Customizing>
|
||||||
|
<Group Id="87605930-f4c2-4c12-816d-f0103cb2103d" Value="3" />
|
||||||
|
</Customizing>
|
||||||
</TargetSystemConfig>
|
</TargetSystemConfig>
|
||||||
@@ -269,7 +269,7 @@
|
|||||||
</System>
|
</System>
|
||||||
<Plc>
|
<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">
|
<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="{64C8C7AD-2D5C-17E5-766C-EEDB24034E45}" TmcPath="PLC\PLC.tmc">
|
<Instance Id="#x08502000" TcSmClass="TComPlcObjDef" KeepUnrestoredLinks="2" TmcHash="{8EE1E4A8-795F-0390-3BF7-7B289B0C6EAD}" TmcPath="PLC\PLC.tmc">
|
||||||
<Name>PLC Instance</Name>
|
<Name>PLC Instance</Name>
|
||||||
<CLSID ClassFactory="TcPlc30">{08500001-0000-0000-F000-000000000064}</CLSID>
|
<CLSID ClassFactory="TcPlc30">{08500001-0000-0000-F000-000000000064}</CLSID>
|
||||||
<Vars VarGrpType="2" AreaNo="1">
|
<Vars VarGrpType="2" AreaNo="1">
|
||||||
@@ -18018,7 +18018,7 @@ Bit1: Value smaller than Limit2]]></Comment>
|
|||||||
<Box Id="78" BoxType="9099" BoxFlags="#x00000020">
|
<Box Id="78" BoxType="9099" BoxFlags="#x00000020">
|
||||||
<Name>=STRNG01++BATMOD02-38K3 (EL5122)</Name>
|
<Name>=STRNG01++BATMOD02-38K3 (EL5122)</Name>
|
||||||
<ImageId>1009</ImageId>
|
<ImageId>1009</ImageId>
|
||||||
<EtherCAT SlaveType="2" PdiType="#x0405" MboxDataLinkLayer="true" StateMBoxPolling="true" CycleMBoxPollingTime="0" CoeType="39" FoeType="1" VendorId="#x00000002" ProductCode="#x14023052" RevisionNo="#x00110000" InfoDataAddr="true" TimeoutMailbox2="2000" CheckRevisionNoType="3" PortPhys="51" SdoUploadWithMaxLength="true" MaxSlotCount="256" MaxSlotGroupCount="1" SlotPdoIncrement="1" SlotIndexIncrement="16" Type="EL5122 2K. Inc. Encoder 5V (2xAB TTL)" Desc="EL5122" PortABoxInfo="#x0100004d">
|
<EtherCAT SlaveType="2" PdiType="#x0405" MboxDataLinkLayer="true" StateMBoxPolling="true" CycleMBoxPollingTime="0" CoeType="39" FoeType="1" VendorId="#x00000002" ProductCode="#x14023052" RevisionNo="#x00100000" InfoDataAddr="true" TimeoutMailbox2="2000" CheckRevisionNoType="3" PortPhys="51" SdoUploadWithMaxLength="true" MaxSlotCount="256" MaxSlotGroupCount="1" SlotPdoIncrement="1" SlotIndexIncrement="16" Type="EL5122 2K. Inc. Encoder 5V (2xAB TTL)" Desc="EL5122" PortABoxInfo="#x0100004d">
|
||||||
<SyncMan>001080002600010001000000800000018000001026010000</SyncMan>
|
<SyncMan>001080002600010001000000800000018000001026010000</SyncMan>
|
||||||
<SyncMan>001180002200010002000000800000018000001122010000</SyncMan>
|
<SyncMan>001180002200010002000000800000018000001122010000</SyncMan>
|
||||||
<SyncMan>00120c002400010003000000000000000c00001224010000</SyncMan>
|
<SyncMan>00120c002400010003000000000000000c00001224010000</SyncMan>
|
||||||
@@ -27369,6 +27369,8 @@ Bit1: Value bigger/equal Limit2]]></Comment>
|
|||||||
<DcMode>53796e6368726f6e00000000000000004672656552756e2f534d2d53796e6368726f6e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000</DcMode>
|
<DcMode>53796e6368726f6e00000000000000004672656552756e2f534d2d53796e6368726f6e00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000</DcMode>
|
||||||
<DcMode>4443000000000000000000000000000044432d53796e6368726f6e000000000000000000000000000000000000000000000000000000000050c30000000000070100000000000000000000000000000000000000000000000000000000000000</DcMode>
|
<DcMode>4443000000000000000000000000000044432d53796e6368726f6e000000000000000000000000000000000000000000000000000000000050c30000000000070100000000000000000000000000000000000000000000000000000000000000</DcMode>
|
||||||
<DcMode>4443494e00000000000000000000000044432d53796e6368726f6e2028696e707574206261736500000000000000000000000000c0f2fcff204e0000000000070100000000000000000001000000000000000000000000000000000000000000</DcMode>
|
<DcMode>4443494e00000000000000000000000044432d53796e6368726f6e2028696e707574206261736500000000000000000000000000c0f2fcff204e0000000000070100000000000000000001000000000000000000000000000000000000000000</DcMode>
|
||||||
|
<MBoxUserCmdData>020003000a00000007000000000000002300090300000000000000000000000020408001020000001d004164647265737300</MBoxUserCmdData>
|
||||||
|
<MBoxUserCmdData>020003000c0000000f000000000000002300090300000000000000000000000020408002040000000f7b0100436f6e6e656374696f6e204d6f646500</MBoxUserCmdData>
|
||||||
<Pdo Name="AI1" Index="#x1a00" Flags="#x0010" SyncMan="3">
|
<Pdo Name="AI1" Index="#x1a00" Flags="#x0010" SyncMan="3">
|
||||||
<ExcludePdo>#x1a01</ExcludePdo>
|
<ExcludePdo>#x1a01</ExcludePdo>
|
||||||
<Entry Name="Status__Underrange" Index="#x6000" Sub="#x01" Flags="#x00008020">
|
<Entry Name="Status__Underrange" Index="#x6000" Sub="#x01" Flags="#x00008020">
|
||||||
|
|||||||
@@ -66,7 +66,7 @@
|
|||||||
</Hides>
|
</Hides>
|
||||||
</DataType>
|
</DataType>
|
||||||
<DataType>
|
<DataType>
|
||||||
<Name GUID="{99721C04-AF32-4BF0-BB6B-A59D0F9957F2}">BMSEvents</Name>
|
<Name GUID="{4B5D56D2-4431-41C5-8F0A-06E1FC56151A}">BMSEvents</Name>
|
||||||
<DisplayName TxtId=""><![CDATA[String event class]]></DisplayName>
|
<DisplayName TxtId=""><![CDATA[String event class]]></DisplayName>
|
||||||
<EventId>
|
<EventId>
|
||||||
<Name Id="1">NotAllCompInAuto</Name>
|
<Name Id="1">NotAllCompInAuto</Name>
|
||||||
@@ -123,6 +123,11 @@
|
|||||||
<DisplayName TxtId=""><![CDATA[String {0}: EtherCAT communication error]]></DisplayName>
|
<DisplayName TxtId=""><![CDATA[String {0}: EtherCAT communication error]]></DisplayName>
|
||||||
<Severity>Error</Severity>
|
<Severity>Error</Severity>
|
||||||
</EventId>
|
</EventId>
|
||||||
|
<EventId>
|
||||||
|
<Name Id="12">SafetyIntlkTimeout</Name>
|
||||||
|
<DisplayName TxtId=""><![CDATA[{0}: Safetyinterlock reset timeout]]></DisplayName>
|
||||||
|
<Severity>Error</Severity>
|
||||||
|
</EventId>
|
||||||
<Hides>
|
<Hides>
|
||||||
<Hide GUID="{1D326C00-DF37-4B94-8E0D-C22524EB2E89}"/>
|
<Hide GUID="{1D326C00-DF37-4B94-8E0D-C22524EB2E89}"/>
|
||||||
<Hide GUID="{E7132508-795D-4A6C-AFB1-FED6C1DE44FD}"/>
|
<Hide GUID="{E7132508-795D-4A6C-AFB1-FED6C1DE44FD}"/>
|
||||||
@@ -142,6 +147,7 @@
|
|||||||
<Hide GUID="{BFBE5ACE-2C85-42F3-81C7-7085445C6CF6}"/>
|
<Hide GUID="{BFBE5ACE-2C85-42F3-81C7-7085445C6CF6}"/>
|
||||||
<Hide GUID="{E2F93DD0-9542-4F83-B1C1-7401F6E7E423}"/>
|
<Hide GUID="{E2F93DD0-9542-4F83-B1C1-7401F6E7E423}"/>
|
||||||
<Hide GUID="{F05A8F7C-1061-4AE4-AAAC-173C036FF4FC}"/>
|
<Hide GUID="{F05A8F7C-1061-4AE4-AAAC-173C036FF4FC}"/>
|
||||||
|
<Hide GUID="{99721C04-AF32-4BF0-BB6B-A59D0F9957F2}"/>
|
||||||
</Hides>
|
</Hides>
|
||||||
</DataType>
|
</DataType>
|
||||||
<DataType>
|
<DataType>
|
||||||
|
|||||||
Reference in New Issue
Block a user