Last changes before SAT

This commit is contained in:
Matthias Heisig
2025-10-14 16:19:19 +02:00
parent eaaa2371e8
commit 2d65d0b3db
28 changed files with 630 additions and 352 deletions

View File

@@ -13,7 +13,8 @@ TYPE E_BMS_CONTROL_MODE :
BALANCING := 6,
CYCLING := 7,
PRECHARGE := 8,
DH := 9
DH := 9,
SEMI_AUTO := 10
);
END_TYPE
]]></Declaration>

View File

@@ -9,7 +9,8 @@ TYPE E_STRING_OPERATING_MODE :
AUTOMATIC := 0,
SAFETY_CHECK := 1,
PRECHARGE := 2,
BALANCING := 3
BALANCING := 3,
SEMI_AUTO := 4
);
END_TYPE
]]></Declaration>

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1" ProductVersion="3.1.4026.12">
<DUT Name="ST_SEMI_AUTO_MODULE_ENABLE" Id="{0a50ad4d-d929-43a2-84d3-8240a20f96f0}">
<Declaration><![CDATA[TYPE ST_SEMI_AUTO_MODULE_ENABLE :
STRUCT
// Manual enable unit 1
xSemiAutoEnableUnit1 : BOOL;
// Manual enable unit 2
xSemiAutoEnableUnit2 : BOOL;
// Manual enable unit 3
xSemiAutoEnableUnit3 : BOOL;
// Manual enable unit 4
xSemiAutoEnableUnit4 : BOOL;
END_STRUCT
END_TYPE
]]></Declaration>
</DUT>
</TcPlcObject>

View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1" ProductVersion="3.1.4026.12">
<DUT Name="ST_SEMI_AUTO_STRING_ENABLE" Id="{a3d678f9-e2d7-4e4a-b890-810149befa04}">
<Declaration><![CDATA[TYPE ST_SEMI_AUTO_STRING_ENABLE :
STRUCT
// Modul 1
stSemiAutoModul1 : ST_SEMI_AUTO_MODULE_ENABLE;
// Modul 2
stSemiAutoModul2 : ST_SEMI_AUTO_MODULE_ENABLE;
// Modul 3
stSemiAutoModul3 : ST_SEMI_AUTO_MODULE_ENABLE;
END_STRUCT
END_TYPE
]]></Declaration>
</DUT>
</TcPlcObject>

View File

@@ -1,5 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1" ProductVersion="3.1.4026.8">
<TcPlcObject Version="1.1.0.1" ProductVersion="3.1.4026.12">
<DUT Name="ST_UNIT_HMI_INTERFACE" Id="{a46d51f7-c17c-44e4-be59-edb877b3b5dc}">
<Declaration><![CDATA[TYPE ST_UNIT_HMI_INTERFACE :
STRUCT
@@ -65,6 +65,11 @@ STRUCT
eStatus : E_COMPONENT_STATUS;
// Semi auto enable
// ====================================
stButtonSemiAutoEnable : ST_HMI_CONTROL_BUTTON;
stButtonSemiAutoDisable : ST_HMI_CONTROL_BUTTON;
// Aknowledge all alarms button
// ===================================
//stButtonAckAlarms : ST_HMI_CONTROL_BUTTON;

View File

@@ -13,15 +13,21 @@ VAR_GLOBAL
stAckAlarmsButton : ST_HMI_CONTROL_BUTTON := (xRelease := TRUE);
// HMI interface to control the battery throught the HMI
{attribute 'OPC.UA.DA' := '1'}
stAutomaticModeHMI : ST_AUTO_HMI_INTERFACE;
// Requested control mode by HMI
{attribute 'OPC.UA.DA' := '1'}
eRequestedControlMode : E_BMS_CONTROL_MODE;
// Current control mode
{attribute 'OPC.UA.DA' := '1'}
{attribute 'OPC.UA.DA.Access' := '1'}
eCurrentControlMode : E_BMS_CONTROL_MODE;
// Can change current control mode
{attribute 'OPC.UA.DA' := '1'}
{attribute 'OPC.UA.DA.Access' := '1'}
xCanChangeControlMode : BOOL;
// Current battery power

View File

@@ -113,6 +113,12 @@
<Compile Include="DUTs\Modbus\ST_EMS_MODBUS_INTERFACE.TcDUT">
<SubType>Code</SubType>
</Compile>
<Compile Include="DUTs\SEMI_AUTO\ST_SEMI_AUTO_MODULE_ENABLE.TcDUT">
<SubType>Code</SubType>
</Compile>
<Compile Include="DUTs\SEMI_AUTO\ST_SEMI_AUTO_STRING_ENABLE.TcDUT">
<SubType>Code</SubType>
</Compile>
<Compile Include="DUTs\ST_AUTO_HMI_INTERFACE.TcDUT">
<SubType>Code</SubType>
</Compile>
@@ -225,6 +231,7 @@
<Folder Include="DUTs\Modbus" />
<Folder Include="DUTs\Modbus\HoldingRegisters" />
<Folder Include="DUTs\Modbus\ErrorWarningRegisters" />
<Folder Include="DUTs\SEMI_AUTO" />
<Folder Include="GVLs" />
<Folder Include="POUs\Utility" />
<Folder Include="POUs\Sunspec" />
@@ -286,8 +293,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>
@@ -2669,16 +2676,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

@@ -11,13 +11,12 @@ VAR_INPUT
refuStringErrorsModbus : REFERENCE TO U_BMS_ERROR_REGISTER;
END_VAR
VAR_OUTPUT
xErrorLatched : BOOL;
END_VAR
VAR
_latchedVoltages : BOOL;
_latchedPressures : BOOL;
_latechedTemperatures : BOOL;
_xErrorLatched : BOOL;
_latchedTemperatures : BOOL;
END_VAR
]]></Declaration>
<Implementation>
@@ -25,25 +24,25 @@ END_VAR
xReset := FALSE;
_latchedVoltages := FALSE;
_latchedPressures := FALSE;
_latechedTemperatures := FALSE;
_xErrorLatched := FALSE;
_latchedTemperatures := FALSE;
xErrorLatched := FALSE;
END_IF
IF (NOT xVoltagesInRange) AND NOT _xErrorLatched THEN
IF (NOT xVoltagesInRange) AND NOT xErrorLatched THEN
_latchedVoltages := TRUE;
_xErrorLatched := TRUE;
xErrorLatched := TRUE;
refuStringErrorsModbus.stBitmap.bSafetyErrorVoltage := 1;
END_IF
IF (NOT xPressureInRange) AND NOT _xErrorLatched THEN
IF (NOT xPressureInRange) AND NOT xErrorLatched THEN
_latchedPressures := TRUE;
_xErrorLatched := TRUE;
xErrorLatched := TRUE;
refuStringErrorsModbus.stBitmap.bSafetyErrorPressure := 1;
END_IF
IF (NOT xTemperaturesInRange) AND NOT _xErrorLatched THEN
_latechedTemperatures := TRUE;
_xErrorLatched := TRUE;
IF (NOT xTemperaturesInRange) AND NOT xErrorLatched THEN
_latchedTemperatures := TRUE;
xErrorLatched := TRUE;
refuStringErrorsModbus.stBitmap.bSafetyErrorTemperature := 1;
END_IF]]></ST>
</Implementation>

View File

@@ -69,7 +69,11 @@ VAR_OUTPUT
// Safety communication error
{attribute 'analysis' := '-33'}
xSafetyComError AT %I* : BOOL;
xSafetyComError : BOOL;
xLocalComError AT %I* : BOOL;
xTempComError AT %I* : BOOL;
xPressureComError AT %I* : BOOL;
xVoltageComError AT %I* : BOOL;
// All safetyinterlocks from safety plc are ok
xSafetyIntlksOk AT %I* : BOOL;
@@ -253,6 +257,8 @@ xAllModulesInAutoMode := TRUE;
_fbSafetyResetImpulseGen();
xSafetyComError := xLocalComError OR xTempComError OR xPressureComError OR xVoltageComError;
// ===============================
// DC current measurement
// ===============================

View File

@@ -226,6 +226,10 @@ VAR
// Pumps ready
_xPumpsReady : BOOL;
_xSemiAutoEnabled : BOOL;
_xEnableInternal : BOOL;
// Indicate if it ise the first cycle
xFirstCycle : BOOL := TRUE;
END_VAR
@@ -263,6 +267,8 @@ END_VAR
xFirstCycle := FALSE;
END_IF
_xEnableInternal := xEnable OR _xSemiAutoEnabled;
// Manual mode trigger
_tonManualMode(IN := (xAllToManualMode AND xReleaseManualMode), PT := T#10S);
@@ -283,6 +289,33 @@ IF _rtrigSwitchToAutoMode.Q THEN
_fbNegolytPumpInlet.ReqAutomaticMode();
END_IF
// Check semi auto mode buttons
IF stHMIInterface.stButtonSemiAutoEnable.xRequest AND (eStringOperatingMode = E_STRING_OPERATING_MODE.SEMI_AUTO) THEN
stHMIInterface.stButtonSemiAutoEnable.xRequest := FALSE;
_xSemiAutoEnabled := TRUE;
END_IF
IF stHMIInterface.stButtonSemiAutoDisable.xRequest THEN
stHMIInterface.stButtonSemiAutoDisable.xRequest := FALSE;
_xSemiAutoEnabled := FALSE;
END_IF
IF (eStringOperatingMode <> E_STRING_OPERATING_MODE.SEMI_AUTO) AND _xSemiAutoEnabled THEN
_xSemiAutoEnabled := FALSE;
END_IF
stHMIInterface.stButtonSemiAutoEnable.xRelease := (eStringOperatingMode = E_STRING_OPERATING_MODE.SEMI_AUTO) AND (NOT _xSemiAutoEnabled);
stHMIInterface.stButtonSemiAutoDisable.xRelease := (eStringOperatingMode = E_STRING_OPERATING_MODE.SEMI_AUTO) AND _xSemiAutoEnabled;
IF _xSemiAutoEnabled THEN
stHMIInterface.stButtonSemiAutoEnable.eFeedback := E_HMI_BUTTON_FEEDBACK.ACTIVE;
stHMIInterface.stButtonSemiAutoDisable.eFeedback := E_HMI_BUTTON_FEEDBACK.NONE;
ELSE
stHMIInterface.stButtonSemiAutoEnable.eFeedback := E_HMI_BUTTON_FEEDBACK.NONE;
stHMIInterface.stButtonSemiAutoDisable.eFeedback := E_HMI_BUTTON_FEEDBACK.ACTIVE;
END_IF
// Reset MCB logic
_tofResetMCB(IN := xConfirmAlarms);
xResetMCB := _tofResetMCB.Q;
@@ -945,7 +978,7 @@ _fbNegolytPumpInlet.Name := CONCAT(_sName, ' - Negolyt segment inlet');]]></ST>
CASE _iState OF
0: // Off
// Start in enable
IF xEnable AND (NOT xStartBalancing) AND _xAllComponentsInAutomatic AND (NOT _xErrorActive) THEN
IF _xEnableInternal AND (NOT xStartBalancing) AND _xAllComponentsInAutomatic AND (NOT _xErrorActive) THEN
_xReleaseManualMode := FALSE;
_timUnitStartupWaitTime := GVL_CONFIG.timUnitStartupTime;
_iState := 10;
@@ -954,7 +987,7 @@ CASE _iState OF
END_IF
// Start in balancing mode
IF (NOT xEnable) AND xStartBalancing AND _xAllComponentsInAutomatic AND (NOT _xErrorActive) THEN
IF (NOT _xEnableInternal) AND xStartBalancing AND _xAllComponentsInAutomatic AND (NOT _xErrorActive) THEN
_xReleaseManualMode := FALSE;
xBalancingDone := FALSE;
_timUnitStartupWaitTime := GVL_CONFIG.timUnitBalancingStartupTime;
@@ -987,7 +1020,7 @@ CASE _iState OF
END_IF
// If enable signal is lost
IF ((NOT xEnable) AND (NOT xStartBalancing)) THEN
IF ((NOT _xEnableInternal) AND (NOT xStartBalancing)) THEN
stHMIInterface.eStatus := E_COMPONENT_STATUS.SHUTDOWN;
_iState := 40;
END_IF
@@ -998,7 +1031,7 @@ CASE _iState OF
_iState := 1000;
END_IF
IF (NOT xEnable) AND NOT xStartBalancing THEN
IF (NOT _xEnableInternal) AND NOT xStartBalancing THEN
_iState := 51;
END_IF
@@ -1006,18 +1039,18 @@ CASE _iState OF
_tonStartupCheck(In := TRUE, PT := _timUnitStartupWaitTime);
// After some time, check if all values are ok
IF _tonStartupCheck.Q THEN
IF _tonStartupCheck.Q THEN // OR ((_fbVoltageSegment.rScaledValue > 70.0) AND (NOT xStartBalancing))
_tonStartupCheck(In := FALSE);
IF xEnable AND (NOT xStartBalancing) THEN
IF _xEnableInternal AND (NOT xStartBalancing) THEN
_iState := 31;
ELSIF (NOT xEnable) AND xStartBalancing THEN
ELSIF (NOT _xEnableInternal) AND xStartBalancing THEN
xReady := TRUE;
_iState := 69;
END_IF
END_IF
// If enable signal is lost, goto shutdown
IF (NOT xEnable) AND (NOT xStartBalancing) THEN
IF (NOT _xEnableInternal) AND (NOT xStartBalancing) THEN
stHMIInterface.eStatus := E_COMPONENT_STATUS.SHUTDOWN;
_iState := 40;
END_IF
@@ -1065,7 +1098,7 @@ CASE _iState OF
END_IF
// Continue on normal startup path
IF xEnable THEN
IF _xEnableInternal THEN
stHMIInterface.eStatus := E_COMPONENT_STATUS.ON;
_iState := 35;
END_IF
@@ -1080,7 +1113,7 @@ CASE _iState OF
END_IF
// If enable signal is lost, goto shutdown
IF (NOT xEnable) THEN
IF (NOT _xEnableInternal) THEN
_iState := 40;
END_IF
@@ -1088,7 +1121,7 @@ CASE _iState OF
_rSetpointNegolytPumpInlet := GVL_CONFIG.rPumpNegolytOnPower;
_rSetpointPosolytPumpInlet := GVL_CONFIG.rPumpPosolytOnPower;
IF (NOT xEnable) THEN
IF (NOT _xEnableInternal) THEN
stHMIInterface.eStatus := E_COMPONENT_STATUS.SHUTDOWN;
_iState := 40;
END_IF
@@ -1099,10 +1132,13 @@ CASE _iState OF
END_IF
40: // Close all valves
_fbNegolytValveTankOutlet.ReqAutomaticClose();
_fbPosolytValveTankOutlet.ReqAutomaticClose();
xReady := FALSE;
_iState := 45;
IF (NOT _fbNegolytValveTankOutlet.xError) AND (NOT _fbPosolytValveTankOutlet.xError) THEN
_fbNegolytValveTankOutlet.ReqAutomaticClose();
_fbPosolytValveTankOutlet.ReqAutomaticClose();
_iState := 45;
END_IF
45: // Wait for valves to be closed
IF _fbNegolytValveTankOutlet.IsClosed AND _fbPosolytValveTankOutlet.IsClosed THEN
@@ -1123,7 +1159,7 @@ CASE _iState OF
END_IF
// Check for restart condition
IF xEnable AND (NOT _xErrorActive) THEN
IF _xEnableInternal AND (NOT _xErrorActive) THEN
_iState := 0;
END_IF
@@ -1140,7 +1176,7 @@ CASE _iState OF
END_IF
// Check for restart condition
IF (xEnable OR xStartBalancing) AND (NOT _xErrorActive) THEN
IF (_xEnableInternal OR xStartBalancing) AND (NOT _xErrorActive) THEN
xShutdownDischargeAllowed := FALSE;
xInShutdownDischargeMode := FALSE;
_iState := 0;
@@ -1161,7 +1197,7 @@ CASE _iState OF
END_IF
// Check for restart condition
IF xEnable AND (NOT _xErrorActive) THEN
IF _xEnableInternal AND (NOT _xErrorActive) THEN
xShutdownDischargeAllowed := FALSE;
xInShutdownDischargeMode := FALSE;
_iState := 0;
@@ -1194,7 +1230,7 @@ CASE _iState OF
END_IF
// Check for restart condition
IF xEnable AND (NOT _xErrorActive) THEN
IF _xEnableInternal AND (NOT _xErrorActive) THEN
stHMIInterface.eStatus := E_COMPONENT_STATUS.OFF;
_iState := 0;
END_IF
@@ -1277,11 +1313,11 @@ CASE _iState OF
END_IF
// Check for restart condition
IF (NOT xEnable) AND xError THEN
IF (NOT _xEnableInternal) AND xError THEN
xError := FALSE;
END_IF
IF (NOT xError) AND (xEnable OR xStartBalancing) THEN
IF (NOT xError) AND (_xEnableInternal OR xStartBalancing) THEN
_iState := 0;
END_IF
@@ -1306,7 +1342,7 @@ CASE _iState OF
1001: // Alarm active
// Only allow reset when enable is deactivated to avoid an
// automatic restart of the unit
IF (NOT _xErrorActive) AND (NOT xEnable) AND (NOT xStartBalancing) AND _xPumpsReady AND xConfirmAlarms THEN
IF (NOT _xErrorActive) AND (NOT _xEnableInternal) AND (NOT xStartBalancing) AND _xPumpsReady AND xConfirmAlarms THEN
xError := FALSE;
IF (_fbVoltageSegment.rScaledValue >= GVL_CONFIG.rPumpshutoffThreshold) THEN
_iState := 1002;

View File

@@ -172,12 +172,15 @@ VAR
_arPowerString : ARRAY[0..(GVL_CONFIG.uiNumberOfStrings-1)] OF REAL;
// Temperature sensor SCS String 1
{attribute 'OPC.UA.DA' := '0'}
_fbTempCabinetSCSString1 : FB_AnalogInput('String 1 - SCS - T1_Cabinet');
// Temperature sensor SCS String 1
{attribute 'OPC.UA.DA' := '0'}
_fbTempCabinetSCSString2 : FB_AnalogInput('String 2 - SCS - T1_Cabinet');
// Temperature sensor BMS cabinet
{attribute 'OPC.UA.DA' := '0'}
_fbTempCabinetBMS : FB_AnalogInput('BMS - T1_Cabinet');
_ui : UINT := 0;
@@ -234,6 +237,10 @@ END_VAR
_xFirstCycle := FALSE;
_xGetPowerMeterData := TRUE;
_fbPIControl.FB_Init(FALSE, FALSE);
_fbPT1CVAntiAliasFilter.FB_Init(false, false);
_fbBatteryFullMessage.CreateEx(stEventEntry := TC_EVENTS.BMSEvents.BatteryFull, 0);
_fbBatteryEmptyMessage.CreateEx(stEventEntry := TC_EVENTS.BMSEvents.BatteryEmpty, 0);
@@ -978,6 +985,13 @@ CASE _eBMSControlMode OF
END_IF
SM_AUTO();
GVL_SCADA.stAutomaticModeHMI.diSetpointAutomatic := REAL_TO_DINT(_rAutoPowerRequest);
E_BMS_CONTROL_MODE.SEMI_AUTO:
_eStringOpMode := E_STRING_OPERATING_MODE.SEMI_AUTO;
IF (GVL_SCADA.eRequestedControlMode <> E_BMS_CONTROL_MODE.SEMI_AUTO) THEN
_eBMSControlMode := GVL_SCADA.eRequestedControlMode;
END_IF
END_CASE
GVL_SCADA.xCanChangeControlMode := _xCanChangeMode;
@@ -1013,7 +1027,7 @@ GVL_MODBUS.stBMSErrorReg.wBMSErrorActive.stBitmap.bError := _xErrorActive OR _xE
// Call safety fb
_fbSafety(refuStringErrorsModbus := GVL_MODBUS.stBMSErrorReg.wBMSErrorActive);
_fbSafety(refuStringErrorsModbus := GVL_MODBUS.stBMSErrorReg.wBMSErrorActive, xReset := _xConfirmAlarms);
// Check if all modules are in auto mode
IF _xStringsInAutoMode AND _fbNoAutomaticModeAlarm.bRaised THEN
@@ -1347,8 +1361,8 @@ _fbTowerLight(
END_IF
45: // Wait for shutdown of string to be done
_xCanChangeMode := TRUE;
IF (NOT _xStringsInSchutdownDischargeMode) AND _xStringsOff THEN
_xCanChangeMode := TRUE;
GVL_MODBUS.stModbusEMSComm.stModbusReg11.eBatteryStatus := E_BATTERY_STATUS.OFF;
GVL_MODBUS.stModbusEMSComm.stModbusReg11.eChargeStatus := E_CHARGE_STATUS.UNDEFINED;
GVL_SCADA.eCycleStatus := E_CYCLE_STATUS.OFF;

View File

@@ -716,7 +716,7 @@ CASE _iStateCyclicData OF
_iStateCyclicData := 61;
// If there was no error and the converter has no error continue
IF (NOT _fbReadACValues.bError) THEN
stCurrentValues.rActACCurrent := LREAL_TO_REAL(WORD_TO_INT(_awCurrentACValues[0]) * EXPT(10,WORD_TO_INT(_awCurrentACValues[4])));
stCurrentValues.rActACCurrent := LREAL_TO_REAL(WORD_TO_INT(_awCurrentACValues[0]) * EXPT(10,WORD_TO_INT(_awCurrentACValues[4])))*0.33333333;
stCurrentValues.rActtACPhaseACurrent := LREAL_TO_REAL(WORD_TO_INT(_awCurrentACValues[1]) * EXPT(10,WORD_TO_INT(_awCurrentACValues[4])));
stCurrentValues.rActtACPhaseBCurrent := LREAL_TO_REAL(WORD_TO_INT(_awCurrentACValues[2]) * EXPT(10,WORD_TO_INT(_awCurrentACValues[4])));
stCurrentValues.rActtACPhaseCCurrent := LREAL_TO_REAL(WORD_TO_INT(_awCurrentACValues[3]) * EXPT(10,WORD_TO_INT(_awCurrentACValues[4])));

View File

@@ -18,7 +18,7 @@ END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[// Calculate output
rOutput := _rOutputLast + (rInput - _rOutputLast) * (_rT / (TIME_TO_LREAL(timT) + _rT));
rOutput := LREAL_TO_REAL(_rOutputLast + (rInput - _rOutputLast) * (_rT / (TIME_TO_LREAL(timT) + _rT)));
// Save last output
_rOutputLast := rOutput;]]></ST>