Added possibility to charge with cv
This commit is contained in:
@@ -289,7 +289,18 @@ VAR_GLOBAL PERSISTENT
|
|||||||
rBalancingFactor : REAL := 20.0;
|
rBalancingFactor : REAL := 20.0;
|
||||||
|
|
||||||
// Timeout heartbeat from EMS
|
// Timeout heartbeat from EMS
|
||||||
timEMSHeartbeatTimeout : TIME := t#5s;
|
timEMSHeartbeatTimeout : TIME := T#5S;
|
||||||
|
|
||||||
|
// Flag if charging should be done with cv phase at end
|
||||||
|
xCVCharging : BOOL := FALSE;
|
||||||
|
|
||||||
|
// Controller parameters for cv charging
|
||||||
|
rCVKp : REAL := 0.0;
|
||||||
|
// In ms
|
||||||
|
rCVTn : REAL := 0.0;
|
||||||
|
|
||||||
|
// Minimum current for cv charging in Amps
|
||||||
|
rMinCVCurrentForFull : REAL := -5.0;
|
||||||
|
|
||||||
// Dummy to deactivate functions
|
// Dummy to deactivate functions
|
||||||
{attribute 'analysis' := '-33'}
|
{attribute 'analysis' := '-33'}
|
||||||
|
|||||||
@@ -389,7 +389,7 @@ xOff := _fbModule1.xOff AND _fbModule2.xOff AND _fbModule3.xOff;
|
|||||||
_fbInverter(
|
_fbInverter(
|
||||||
sInverterIPAddr:= sInverterIP,
|
sInverterIPAddr:= sInverterIP,
|
||||||
xEnable:= _xEnableInverter AND xEmergencyStopOk,
|
xEnable:= _xEnableInverter AND xEmergencyStopOk,
|
||||||
xReleasePower := xReleaseInverterPower,
|
xReleasePower := xReleaseInverterPower AND _xEnableInverter,
|
||||||
rPower:= _rPowerInverterInternal,
|
rPower:= _rPowerInverterInternal,
|
||||||
xReset:= xConfirmAlarms,
|
xReset:= xConfirmAlarms,
|
||||||
rMaxBattPower:= DINT_TO_REAL(GVL_CONFIG.diMaxStringDischargePower),
|
rMaxBattPower:= DINT_TO_REAL(GVL_CONFIG.diMaxStringDischargePower),
|
||||||
|
|||||||
@@ -210,6 +210,12 @@ VAR
|
|||||||
|
|
||||||
_xGetPowerMeterData : BOOL;
|
_xGetPowerMeterData : BOOL;
|
||||||
|
|
||||||
|
_fbPIControl : FB_PI;
|
||||||
|
_fbLimit : FB_Limit;
|
||||||
|
_xCVChargingLatched : BOOL;
|
||||||
|
_rCVSetpoint : REAL;
|
||||||
|
_xStringsFullCV : BOOL;
|
||||||
|
|
||||||
_rPowerDH : REAL;
|
_rPowerDH : REAL;
|
||||||
_xDHActive : BOOL;
|
_xDHActive : BOOL;
|
||||||
_fbTONDHCycleTime : TON := (PT := T#15M);
|
_fbTONDHCycleTime : TON := (PT := T#15M);
|
||||||
@@ -1087,7 +1093,7 @@ _fbTowerLight(
|
|||||||
|
|
||||||
IF _xStringsErrorActive OR _fbStringReadyTimeout.Q THEN
|
IF _xStringsErrorActive OR _fbStringReadyTimeout.Q THEN
|
||||||
_fbStringReadyTimeout(IN := FALSE);
|
_fbStringReadyTimeout(IN := FALSE);
|
||||||
_xStringNotReadyInTime := TRUE;
|
_xStringNotReadyInTime := _fbStringReadyTimeout.Q;
|
||||||
_xEnableString := FALSE;
|
_xEnableString := FALSE;
|
||||||
GVL_SCADA.stAutomaticModeHMI.diSetpointAutomatic := 0;
|
GVL_SCADA.stAutomaticModeHMI.diSetpointAutomatic := 0;
|
||||||
_xCanChangeMode := TRUE;
|
_xCanChangeMode := TRUE;
|
||||||
@@ -1148,11 +1154,54 @@ _fbTowerLight(
|
|||||||
_xEnableString := FALSE;
|
_xEnableString := FALSE;
|
||||||
GVL_MODBUS.stModbusEMSComm.stModbusReg11.eChargeStatus := E_CHARGE_STATUS.DISCHARGING;
|
GVL_MODBUS.stModbusEMSComm.stModbusReg11.eChargeStatus := E_CHARGE_STATUS.DISCHARGING;
|
||||||
GVL_MODBUS.stModbusEMSComm.stModbusReg10.uiActiveParallelMembers := 0;
|
GVL_MODBUS.stModbusEMSComm.stModbusReg10.uiActiveParallelMembers := 0;
|
||||||
|
_xCVChargingLatched := FALSE;
|
||||||
|
_fbPIControl.Reset();
|
||||||
_iState := 35;
|
_iState := 35;
|
||||||
END_IF
|
END_IF
|
||||||
|
|
||||||
|
// Charge with constant Voltage at charging end
|
||||||
|
IF GVL_CONFIG.xCVCharging AND (_rAutoPowerRequest < 0.0) AND (_rHighestSegmentVoltage >= (GVL_CONFIG.rMaximumUnitVoltage)) THEN
|
||||||
|
_xCVChargingLatched := TRUE;
|
||||||
|
END_IF
|
||||||
|
|
||||||
|
// Delatch if charging power requested is lower than cv power
|
||||||
|
//IF _xCVChargingLatched AND (_rAutoPowerRequest > _rPowerInverter) THEN
|
||||||
|
// _xCVChargingLatched := FALSE;
|
||||||
|
//END_IF
|
||||||
|
|
||||||
|
IF _xCVChargingLatched THEN
|
||||||
|
// Reglerfreigabe
|
||||||
|
_rCVSetpoint := GVL_CONFIG.rMaximumUnitVoltage;
|
||||||
|
ELSE
|
||||||
|
// Nachführbetrieb
|
||||||
|
_rCVSetpoint := _rHighestSegmentVoltage;
|
||||||
|
END_IF
|
||||||
|
|
||||||
|
_fbPIControl(
|
||||||
|
rSP:= _rCVSetpoint,
|
||||||
|
rPV:= _rHighestSegmentVoltage,
|
||||||
|
rKp:= GVL_CONFIG.rCVKp,
|
||||||
|
rTn:= GVL_CONFIG.rCVTn,
|
||||||
|
xSaturated:= _fbLimit.xClamped);
|
||||||
|
|
||||||
|
_rPowerInverter := _rAutoPowerRequest - _fbPIControl.rMV;
|
||||||
|
|
||||||
|
_fbLimit(
|
||||||
|
rIn := _rPowerInverter,
|
||||||
|
rMin := _rMinPower,
|
||||||
|
rMax := _rMaxPower,
|
||||||
|
rOut => _rPowerInverter);
|
||||||
|
|
||||||
|
IF ((GVL_SCADA.stHMIInterface[0].stInverterData.rActDCCurrent > GVL_CONFIG.rMinCVCurrentForFull) AND GVL_CONFIG.axStringEnabled[0]) OR ((GVL_SCADA.stHMIInterface[1].stInverterData.rActDCCurrent > GVL_CONFIG.rMinCVCurrentForFull) AND GVL_CONFIG.axStringEnabled[1]) THEN
|
||||||
|
_xStringsFullCV := TRUE;
|
||||||
|
ELSE
|
||||||
|
_xStringsFullCV := FALSE;
|
||||||
|
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 ((_rMaxCurrentInverterDCVoltage >= 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 AND (NOT _xCVChargingLatched)) OR _xStringsFullCV) THEN
|
||||||
|
//OR (_xCVChargingLatched AND ((ABS(GVL_SCADA.stHMIInterface[0].rCurrent) < 8.0) OR (ABS(GVL_SCADA.stHMIInterface[0].rCurrent) < 8.0)))
|
||||||
_xGetPowerMeterData := TRUE;
|
_xGetPowerMeterData := TRUE;
|
||||||
IF (_eBMSControlMode = E_BMS_CONTROL_MODE.CYCLING) THEN
|
IF (_eBMSControlMode = E_BMS_CONTROL_MODE.CYCLING) THEN
|
||||||
GVL_SCADA.eCycleStatus := E_CYCLE_STATUS.DISCHARGE_STARTED;
|
GVL_SCADA.eCycleStatus := E_CYCLE_STATUS.DISCHARGE_STARTED;
|
||||||
@@ -1176,9 +1225,10 @@ _fbTowerLight(
|
|||||||
// Change battery status
|
// Change battery status
|
||||||
GVL_MODBUS.stModbusEMSComm.stModbusReg11.eChargeStatus := E_CHARGE_STATUS.FULL;
|
GVL_MODBUS.stModbusEMSComm.stModbusReg11.eChargeStatus := E_CHARGE_STATUS.FULL;
|
||||||
GVL_MODBUS.stModbusEMSComm.stModbusReg10.uiActiveParallelMembers := 0;
|
GVL_MODBUS.stModbusEMSComm.stModbusReg10.uiActiveParallelMembers := 0;
|
||||||
|
_xCVChargingLatched := FALSE;
|
||||||
|
_fbPIControl.Reset();
|
||||||
_iState := 35;
|
_iState := 35;
|
||||||
END_IF
|
END_IF
|
||||||
|
|
||||||
END_IF
|
END_IF
|
||||||
|
|
||||||
// Shutdown triggered by battery empty
|
// Shutdown triggered by battery empty
|
||||||
@@ -1206,6 +1256,8 @@ _fbTowerLight(
|
|||||||
// Change battery status
|
// Change battery status
|
||||||
GVL_MODBUS.stModbusEMSComm.stModbusReg11.eChargeStatus := E_CHARGE_STATUS.EMPTY;
|
GVL_MODBUS.stModbusEMSComm.stModbusReg11.eChargeStatus := E_CHARGE_STATUS.EMPTY;
|
||||||
GVL_MODBUS.stModbusEMSComm.stModbusReg10.uiActiveParallelMembers := 0;
|
GVL_MODBUS.stModbusEMSComm.stModbusReg10.uiActiveParallelMembers := 0;
|
||||||
|
_xCVChargingLatched := FALSE;
|
||||||
|
_fbPIControl.Reset();
|
||||||
_iState := 35;
|
_iState := 35;
|
||||||
END_IF
|
END_IF
|
||||||
END_IF
|
END_IF
|
||||||
@@ -1218,6 +1270,8 @@ _fbTowerLight(
|
|||||||
_tonBeginShutdown(In := FALSE);
|
_tonBeginShutdown(In := FALSE);
|
||||||
GVL_SCADA.stAutomaticModeHMI.diSetpointAutomatic := 0;
|
GVL_SCADA.stAutomaticModeHMI.diSetpointAutomatic := 0;
|
||||||
_xCanChangeMode := TRUE;
|
_xCanChangeMode := TRUE;
|
||||||
|
_xCVChargingLatched := FALSE;
|
||||||
|
_fbPIControl.Reset();
|
||||||
_iState := 45;
|
_iState := 45;
|
||||||
END_IF
|
END_IF
|
||||||
|
|
||||||
|
|||||||
30
PLC/POUs/Utility/Controller/FB_Limit.TcPOU
Normal file
30
PLC/POUs/Utility/Controller/FB_Limit.TcPOU
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<TcPlcObject Version="1.1.0.1" ProductVersion="3.1.4026.12">
|
||||||
|
<POU Name="FB_Limit" Id="{d4518907-6b63-4dbf-8339-7e925234f00a}" SpecialFunc="None">
|
||||||
|
<Declaration><![CDATA[FUNCTION_BLOCK FB_Limit
|
||||||
|
VAR_INPUT
|
||||||
|
rIn : REAL;
|
||||||
|
rMin : REAL;
|
||||||
|
rMax : REAL;
|
||||||
|
END_VAR
|
||||||
|
VAR_OUTPUT
|
||||||
|
rOut : REAL;
|
||||||
|
xClamped : BOOL;
|
||||||
|
END_VAR
|
||||||
|
VAR
|
||||||
|
END_VAR
|
||||||
|
]]></Declaration>
|
||||||
|
<Implementation>
|
||||||
|
<ST><![CDATA[IF rIn > rMax THEN
|
||||||
|
rOut := rMax;
|
||||||
|
xClamped := TRUE;
|
||||||
|
ELSIF rIn < rMin THEN
|
||||||
|
rOut := rMin;
|
||||||
|
xClamped := TRUE;
|
||||||
|
ELSE
|
||||||
|
rOut := rIn;
|
||||||
|
xClamped := FALSE;
|
||||||
|
END_IF]]></ST>
|
||||||
|
</Implementation>
|
||||||
|
</POU>
|
||||||
|
</TcPlcObject>
|
||||||
68
PLC/POUs/Utility/Controller/FB_PI.TcPOU
Normal file
68
PLC/POUs/Utility/Controller/FB_PI.TcPOU
Normal file
@@ -0,0 +1,68 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<TcPlcObject Version="1.1.0.1" ProductVersion="3.1.4026.12">
|
||||||
|
<POU Name="FB_PI" Id="{8fe95419-3a89-4668-8d22-4f91ef3ca204}" SpecialFunc="None">
|
||||||
|
<Declaration><![CDATA[FUNCTION_BLOCK FB_PI
|
||||||
|
VAR_INPUT
|
||||||
|
rSP : REAL;
|
||||||
|
rPV : REAL;
|
||||||
|
rKp : REAL;
|
||||||
|
rTn : REAL;
|
||||||
|
|
||||||
|
xSaturated : BOOL := FALSE;
|
||||||
|
END_VAR
|
||||||
|
VAR_OUTPUT
|
||||||
|
rMV : REAL;
|
||||||
|
END_VAR
|
||||||
|
VAR
|
||||||
|
|
||||||
|
_rError : REAL := 0.0;
|
||||||
|
_rIntegral : REAL := 0.0;
|
||||||
|
_rProportinal : REAL := 0.0;
|
||||||
|
|
||||||
|
_fbGetCurTaskIdx : GETCURTASKINDEX;
|
||||||
|
_rT : REAL;
|
||||||
|
END_VAR
|
||||||
|
]]></Declaration>
|
||||||
|
<Implementation>
|
||||||
|
<ST><![CDATA[// Calculate error
|
||||||
|
_rError := rSP - rPV;
|
||||||
|
|
||||||
|
// Calculate proportinal part
|
||||||
|
_rProportinal := rKp * _rError;
|
||||||
|
|
||||||
|
// Calculate controller output
|
||||||
|
rMV := _rProportinal + _rIntegral;
|
||||||
|
|
||||||
|
// Stop integrator if saturated
|
||||||
|
IF (NOT xSaturated) AND (rTn <> 0) THEN
|
||||||
|
_rIntegral := _rIntegral + (rKp * _rT / rTn) * _rError;
|
||||||
|
END_IF
|
||||||
|
|
||||||
|
// Reset integral with deactivated integral time
|
||||||
|
IF (rTn = 0.0) AND (_rIntegral <> 0) THEN
|
||||||
|
_rIntegral := 0.0;
|
||||||
|
END_IF]]></ST>
|
||||||
|
</Implementation>
|
||||||
|
<Method Name="FB_init" Id="{58ddb3c6-73d3-470a-927d-f677bf66bbfe}">
|
||||||
|
<Declaration><![CDATA[//FB_Init ist immer implizit verfügbar und wird primär für die Initialisierung verwendet.
|
||||||
|
//Der Rückgabewert wird nicht ausgewertet. Für gezielte Einflussnahme können Sie
|
||||||
|
//die Methoden explizit deklarieren und darin mit dem Standard-Initialisierungscode
|
||||||
|
//zusätzlichen Code bereitstellen. Sie können den Rückgabewert auswerten.
|
||||||
|
METHOD FB_Init: BOOL
|
||||||
|
VAR_INPUT
|
||||||
|
bInitRetains: BOOL; // TRUE: Die Retain-Variablen werden initialisiert (Reset warm / Reset kalt)
|
||||||
|
bInCopyCode: BOOL; // TRUE: Die Instanz wird danach in den Kopiercode kopiert (Online-Change)
|
||||||
|
END_VAR]]></Declaration>
|
||||||
|
<Implementation>
|
||||||
|
<ST><![CDATA[// Get current task time
|
||||||
|
_fbGetCurTaskIdx();
|
||||||
|
_rT := UDINT_TO_LREAL(TwinCAT_SystemInfoVarList._TASKInfo[_fbGetCurTaskIdx.index].CycleTime) * 10E-5;]]></ST>
|
||||||
|
</Implementation>
|
||||||
|
</Method>
|
||||||
|
<Action Name="Reset" Id="{4227580c-e163-4250-9575-dd60ff3083af}">
|
||||||
|
<Implementation>
|
||||||
|
<ST><![CDATA[_rIntegral := 0.0;]]></ST>
|
||||||
|
</Implementation>
|
||||||
|
</Action>
|
||||||
|
</POU>
|
||||||
|
</TcPlcObject>
|
||||||
Reference in New Issue
Block a user