Minor bugfixes and future addons
This commit is contained in:
@@ -5,7 +5,6 @@
|
||||
VAR
|
||||
_xEmergencyStopOk AT %I* : BOOL;
|
||||
_xShowAckEmergencyStop AT %Q* : BOOL;
|
||||
_xString1DCSafetyOk AT %I* : BOOL;
|
||||
_xReleaseErrors : BOOL := TRUE;
|
||||
_xReleaseLimitsErrors : BOOL := TRUE;
|
||||
_xConfirmAlarms : BOOL;
|
||||
@@ -18,9 +17,12 @@ VAR
|
||||
_afbStrings : ARRAY[0..1] OF FB_String[('String 1'), ('String 2')];
|
||||
|
||||
// Variable to detect charge status change
|
||||
_eLastChargeStatus : E_CHARGE_STATUS;
|
||||
//_eLastChargeStatus : E_CHARGE_STATUS;
|
||||
// Variable to detect battery status change
|
||||
_eLastBatteryStatus : E_BATTERY_STATUS;
|
||||
//_eLastBatteryStatus : E_BATTERY_STATUS;
|
||||
|
||||
// Battery shutdown due to error
|
||||
_xErrorShutdown : BOOL := FALSE;
|
||||
|
||||
// State machine state
|
||||
_iState : INT;
|
||||
@@ -46,7 +48,7 @@ VAR
|
||||
_tonBeginShutdown : TON := (PT := T#30S);
|
||||
|
||||
// Not all strings in automatic mode
|
||||
_fbNoAutomaticModeAlarm : Fb_TcAlarm;
|
||||
_fbNoAutomaticModeAlarm : FB_TcAlarm;
|
||||
|
||||
// Emergency stop not ok alarm
|
||||
_fbEStopNotOk : FB_TcAlarm;
|
||||
@@ -73,11 +75,6 @@ VAR
|
||||
// Release manual mode
|
||||
_xReleaseManualMode : BOOL;
|
||||
|
||||
// Current internal set inverter power value
|
||||
_diInternalPowerSetpoint : DINT;
|
||||
|
||||
_diSetpointActivePower : DINT;
|
||||
|
||||
// Current BMS control mode (Auto local, Auto remote, etc...)
|
||||
// On restart star in manual mode (so the ems can not directly start the bms)
|
||||
_eBMSControlMode : E_BMS_CONTROL_MODE := E_BMS_CONTROL_MODE.AUTO_LOCAL;
|
||||
@@ -86,6 +83,7 @@ VAR
|
||||
_fbUPS : FB_S_UPS_BAPI;
|
||||
|
||||
// Safety
|
||||
{attribute 'analysis' := '-33'}
|
||||
xSafetyRun AT %Q* : BOOL := TRUE;
|
||||
xSafetyErrAck AT %Q* : BOOL;
|
||||
xSafetyResterTaster AT %I* : BOOL;
|
||||
@@ -126,8 +124,6 @@ VAR
|
||||
// DEBUG
|
||||
_xRestart : BOOL;
|
||||
|
||||
_xDebug : BOOL;
|
||||
|
||||
_ModbusDebugTest : ST_MODBUS_REG_11;
|
||||
|
||||
_fbStringReadyTimeout : TON;
|
||||
@@ -144,15 +140,21 @@ VAR
|
||||
_xStringsAllInAutomaticMode : BOOL;
|
||||
_xStringsOff : BOOL;
|
||||
_xStringsBalancingDone : BOOL;
|
||||
_xStringsInAutoMode : BOOL;
|
||||
|
||||
_rMaxCurrentInverterDCVoltage : REAL;
|
||||
_rMinCurrentInverterDCVoltage : REAL;
|
||||
|
||||
_fbModbusRead : FB_MBReadRegs;
|
||||
_wLength : WORD := 49;
|
||||
//_wLength : WORD := 49;
|
||||
xDebugTest : BOOL;
|
||||
_wDebug1 : WORD;
|
||||
_wDebug2 : WORD;
|
||||
|
||||
_fbPowerMeterPower : FB_PowerMeter;
|
||||
_fbPowerMeter24V : FB_PowerMeter;
|
||||
|
||||
_xGetPowerMeterData : BOOL;
|
||||
END_VAR
|
||||
]]></Declaration>
|
||||
<Implementation>
|
||||
@@ -172,6 +174,7 @@ END_IF
|
||||
|
||||
IF _xFirstCycle THEN
|
||||
_xFirstCycle := FALSE;
|
||||
_xGetPowerMeterData := TRUE;
|
||||
|
||||
_fbBatteryFullMessage.CreateEx(stEventEntry := TC_EVENTS.BMSEvents.BatteryFull, 0);
|
||||
_fbBatteryEmptyMessage.CreateEx(stEventEntry := TC_EVENTS.BMSEvents.BatteryEmpty, 0);
|
||||
@@ -299,8 +302,8 @@ _tonStartupDelay(IN := TRUE);
|
||||
|
||||
// Call string 1
|
||||
_afbStrings[0](
|
||||
stStringModuleVoltageConfig := GVL_CONFIG.stString1VoltageConfig,
|
||||
xEnable := _xEnableString,
|
||||
xErrorShutdown := _xErrorShutdown,
|
||||
xStartBalancing := _xStartBalancing,
|
||||
sInverterIP := GVL_CONFIG.sInverterIpString1,
|
||||
rPowerInverter := _arPowerString[0],
|
||||
@@ -320,8 +323,8 @@ END_IF
|
||||
|
||||
// Call string 2
|
||||
_afbStrings[1](
|
||||
stStringModuleVoltageConfig := GVL_CONFIG.stString2VoltageConfig,
|
||||
xEnable := _xEnableString,
|
||||
xErrorShutdown := _xErrorShutdown,
|
||||
xStartBalancing := _xStartBalancing,
|
||||
sInverterIP := GVL_CONFIG.sInverterIpString2,
|
||||
rPowerInverter := _arPowerString[1],
|
||||
@@ -353,6 +356,7 @@ _rMaxCurrentInverterDCVoltage := 0.0;
|
||||
_rMinCurrentInverterDCVoltage := 10_000;
|
||||
_rHighestSegmentVoltage := 0.0;
|
||||
_rSmallestSegmentVoltage := 1_000.0;
|
||||
_xStringsInAutoMode := TRUE;
|
||||
|
||||
FOR _ui := 0 TO (GVL_CONFIG.uiNumberOfStrings-1) DO
|
||||
// Check ready state
|
||||
@@ -409,6 +413,11 @@ FOR _ui := 0 TO (GVL_CONFIG.uiNumberOfStrings-1) DO
|
||||
IF _rHighestSegmentVoltage < _afbStrings[_ui].rHighestSegmentVoltage THEN
|
||||
_rHighestSegmentVoltage := _afbStrings[_ui].rHighestSegmentVoltage;
|
||||
END_IF
|
||||
|
||||
// Get auto mode status
|
||||
IF NOT _afbStrings[_ui].xAllModulesInAutoMode THEN
|
||||
_xStringsInAutoMode := FALSE;
|
||||
END_IF
|
||||
END_FOR
|
||||
|
||||
// ===============================
|
||||
@@ -489,7 +498,6 @@ FOR _ui := 0 TO (GVL_CONFIG.uiNumberOfStrings-1) DO
|
||||
END_FOR
|
||||
|
||||
|
||||
|
||||
// Set Modbus mirror values
|
||||
GVL_MODBUS.stModbusEMSComm.stModbusReg11.diSetpointActivePowerMirror := GVL_MODBUS.stModbusEMSComm.stModbusReg12.diSetpointActivePower;
|
||||
GVL_MODBUS.stModbusEMSComm.stModbusReg11.rSetpointCosPhiMirror := GVL_MODBUS.stModbusEMSComm.stModbusReg12.rSetpointCosPhi;
|
||||
@@ -563,7 +571,7 @@ CASE _eBMSControlMode OF
|
||||
_xAllComponentsToManualMode := FALSE;
|
||||
_xInSafetyCheckMode := FALSE;
|
||||
_xReleaseManualMode := FALSE;
|
||||
IF (_iState <> 30) OR _rAutoPowerRequest = 0.0 THEN
|
||||
IF (_iState <> 30) OR GVL_SCADA.stAutomaticModeHMI.diSetpointAutomatic = 0 THEN
|
||||
_rAutoPowerRequest := DINT_TO_REAL(GVL_SCADA.stAutomaticModeHMI.diSetpointAutomatic);
|
||||
END_IF
|
||||
IF (GVL_SCADA.eRequestedControlMode <> _eBMSControlMode) AND (GVL_SCADA.xCanChangeControlMode) THEN
|
||||
@@ -578,8 +586,36 @@ GVL_SCADA.eCurrentControlMode := _eBMSControlMode;
|
||||
// Calculate current battery dc power
|
||||
GVL_SCADA.diCurrentBatteryPower := REAL_TO_DINT(_afbStrings[0].stInverterData.rActDCPower + _afbStrings[1].stInverterData.rActDCPower);
|
||||
|
||||
// Read power values if commanded
|
||||
_fbPowerMeterPower(
|
||||
xGetEnergyCounters:= _xGetPowerMeterData,
|
||||
sIpAddress:= '192.168.42.75',
|
||||
lrEnergyFromGrid=> GVL_SCADA.lrChargedPowerValueWH,
|
||||
lrEnergyIntoGrid=> GVL_SCADA.lrDischargedPowerValueWH,
|
||||
xBusy=> ,
|
||||
xError=> );
|
||||
|
||||
_fbPowerMeter24V(
|
||||
xGetEnergyCounters:= _xGetPowerMeterData,
|
||||
sIpAddress:= '192.168.42.80',
|
||||
lrEnergyFromGrid=> GVL_SCADA.lrLastCycleUtilityPowerValueWh,
|
||||
lrEnergyIntoGrid=> ,
|
||||
xBusy=> ,
|
||||
xError=> );
|
||||
|
||||
IF _xGetPowerMeterData THEN
|
||||
_xGetPowerMeterData := FALSE;
|
||||
END_IF
|
||||
|
||||
|
||||
// Call safety fb
|
||||
_fbSafety();
|
||||
|
||||
// Check if all modules are in auto mode
|
||||
IF _xStringsInAutoMode AND _fbNoAutomaticModeAlarm.bRaised THEN
|
||||
_fbNoAutomaticModeAlarm.Clear(0, TRUE);
|
||||
END_IF
|
||||
|
||||
// Reset automatic buttons
|
||||
IF GVL_SCADA.stAutomaticModeHMI.stStartAutoButton.xRequest THEN
|
||||
GVL_SCADA.stAutomaticModeHMI.stStartAutoButton.xRequest := FALSE;
|
||||
@@ -591,16 +627,24 @@ END_IF
|
||||
// Reset alarm confirmation
|
||||
IF _xConfirmAlarms OR _rtHardwareResetButton.Q THEN
|
||||
_xConfirmAlarms := FALSE;
|
||||
END_IF]]></ST>
|
||||
END_IF
|
||||
|
||||
_fbPowerMeter24V();]]></ST>
|
||||
</Implementation>
|
||||
<Action Name="SM_AUTO" Id="{b5166e16-4fea-442b-9560-02c156f9a9ad}">
|
||||
<Implementation>
|
||||
<ST><![CDATA[CASE _iState OF
|
||||
0: // Idle
|
||||
// Check for all in auto mode
|
||||
IF (NOT _xStringsInAutoMode) AND (NOT _fbNoAutomaticModeAlarm.bRaised) THEN
|
||||
_fbNoAutomaticModeAlarm.Raise(0);
|
||||
END_IF
|
||||
|
||||
// Wait for power command
|
||||
IF (ABS(_rAutoPowerRequest) > DINT_TO_REAL(GVL_CONFIG.diMinimumAbsPowerForEnable)) AND (NOT _xStringsErrorActive) AND _xStringsAllInAutomaticMode THEN
|
||||
_iState := 5;
|
||||
_xCanChangeMode := FALSE;
|
||||
_xErrorShutdown := FALSE;
|
||||
END_IF
|
||||
|
||||
5: // Check if power command is within limits
|
||||
@@ -621,8 +665,12 @@ END_IF]]></ST>
|
||||
_fbStringReadyTimeout(IN := TRUE, PT := GVL_CONFIG.timStringReadyTimeout);
|
||||
|
||||
IF _xStringsReady AND (NOT _xStringsErrorActive) THEN
|
||||
_xGetPowerMeterData := TRUE;
|
||||
_fbStringReadyTimeout(IN := FALSE);
|
||||
_rPowerInverter := 0.0;
|
||||
// Set active parallel members (modbus)
|
||||
GVL_MODBUS.stModbusEMSComm.stModbusReg10.uiActiveParallelMembers := GVL_CONFIG.uiNumberOfStrings;
|
||||
GVL_MODBUS.stModbusEMSComm.stModbusReg11.eBatteryStatus := E_BATTERY_STATUS.ACTIVE;
|
||||
_iState := 30;
|
||||
END_IF
|
||||
|
||||
@@ -656,10 +704,13 @@ END_IF]]></ST>
|
||||
|
||||
// Set battery status
|
||||
IF _rAutoPowerRequest > 0 THEN
|
||||
GVL_SCADA.eCycleStatus := E_CYCLE_STATUS.DISCHARGE_STARTED;
|
||||
GVL_MODBUS.stModbusEMSComm.stModbusReg11.eChargeStatus := E_CHARGE_STATUS.DISCHARGING;
|
||||
ELSIF _rAutoPowerRequest < 0 THEN
|
||||
GVL_SCADA.eCycleStatus := E_CYCLE_STATUS.CHARGE_STARTED;
|
||||
GVL_MODBUS.stModbusEMSComm.stModbusReg11.eChargeStatus := E_CHARGE_STATUS.CHARGING;
|
||||
ELSE
|
||||
GVL_SCADA.eCycleStatus := E_CYCLE_STATUS.OFF;
|
||||
GVL_MODBUS.stModbusEMSComm.stModbusReg11.eChargeStatus := E_CHARGE_STATUS.UNDEFINED;
|
||||
END_IF
|
||||
|
||||
@@ -670,6 +721,12 @@ END_IF]]></ST>
|
||||
IF _tonBeginShutdown.Q THEN
|
||||
_tonBeginShutdown(In := FALSE);
|
||||
|
||||
IF _rPowerInverter < 0 THEN
|
||||
GVL_SCADA.eCycleStatus := E_CYCLE_STATUS.CHARGE_ENDED;
|
||||
ELSIF _rPowerInverter > 0 THEN
|
||||
GVL_SCADA.eCycleStatus := E_CYCLE_STATUS.DISCHARGE_ENDED;
|
||||
END_IF
|
||||
|
||||
// Set inverter to zero power
|
||||
_rPowerInverter := 0.0;
|
||||
|
||||
@@ -682,11 +739,11 @@ END_IF]]></ST>
|
||||
|
||||
// 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
|
||||
|
||||
_xGetPowerMeterData := TRUE;
|
||||
IF (_eBMSControlMode = E_BMS_CONTROL_MODE.CYCLING) THEN
|
||||
GVL_SCADA.eCycleStatus := E_CYCLE_STATUS.DISCHARGE_STARTED;
|
||||
_rAutoPowerRequest := _rAutoPowerRequest * -1;
|
||||
// Change of charge discharge should be handled in next cycle by same state
|
||||
// GVL_MODBUS.stModbusEMSComm.stModbusReg11.eChargeStatus := E_CHARGE_STATUS.DISCHARGING;
|
||||
GVL_SCADA.stAutomaticModeHMI.diSetpointAutomatic := REAL_TO_DINT(_rAutoPowerRequest);
|
||||
ELSE
|
||||
_tonBeginShutdown(In := FALSE);
|
||||
|
||||
@@ -712,10 +769,11 @@ END_IF]]></ST>
|
||||
|
||||
// Shutdown triggered by battery empty
|
||||
IF GVL_MODBUS.stModbusEMSComm.stModbusReg11.eChargeStatus = E_CHARGE_STATUS.DISCHARGING AND ((_rMinCurrentInverterDCVoltage <= GVL_CONFIG.rStringEmptyVoltage) OR _rSmallestSegmentVoltage <= GVL_CONFIG.rMinimumUnitVoltage) THEN
|
||||
_xGetPowerMeterData := TRUE;
|
||||
IF (_eBMSControlMode = E_BMS_CONTROL_MODE.CYCLING) THEN
|
||||
GVL_SCADA.eCycleStatus := E_CYCLE_STATUS.CHARGE_STARTED;
|
||||
_rAutoPowerRequest := _rAutoPowerRequest * -1;
|
||||
// Change of charge discharge should be handled in next cycle by same state
|
||||
// GVL_MODBUS.stModbusEMSComm.stModbusReg11.eChargeStatus := E_CHARGE_STATUS.CHARGING;
|
||||
GVL_SCADA.stAutomaticModeHMI.diSetpointAutomatic := REAL_TO_DINT(_rAutoPowerRequest);
|
||||
ELSE
|
||||
_tonBeginShutdown(In := FALSE);
|
||||
|
||||
@@ -741,6 +799,7 @@ END_IF]]></ST>
|
||||
// Check for errors
|
||||
IF _xStringsErrorActive THEN
|
||||
_xEnableString := FALSE;
|
||||
_xErrorShutdown := TRUE;
|
||||
_tonBeginShutdown(In := FALSE);
|
||||
GVL_SCADA.stAutomaticModeHMI.diSetpointAutomatic := 0;
|
||||
_xCanChangeMode := TRUE;
|
||||
@@ -757,12 +816,15 @@ END_IF]]></ST>
|
||||
_xEnableString := FALSE;
|
||||
GVL_SCADA.stAutomaticModeHMI.diSetpointAutomatic := 0;
|
||||
_xCanChangeMode := TRUE;
|
||||
GVL_MODBUS.stModbusEMSComm.stModbusReg10.uiActiveParallelMembers := 0;
|
||||
GVL_MODBUS.stModbusEMSComm.stModbusReg11.eBatteryStatus := E_BATTERY_STATUS.OFF;
|
||||
_iState := 45;
|
||||
END_IF
|
||||
END_IF
|
||||
|
||||
// Check for errors
|
||||
IF _xStringsErrorActive THEN
|
||||
_xErrorShutdown := TRUE;
|
||||
_iState := 1000;
|
||||
END_IF
|
||||
|
||||
@@ -770,6 +832,8 @@ END_IF]]></ST>
|
||||
IF _xStringsShutdownDischargeAllowed THEN
|
||||
_rPowerInverter := GVL_CONFIG.rAbsShutdownDischargePower;
|
||||
ELSE
|
||||
_xGetPowerMeterData := TRUE;
|
||||
GVL_MODBUS.stModbusEMSComm.stModbusReg10.uiActiveParallelMembers := 0;
|
||||
_rPowerInverter := 0.0;
|
||||
GVL_SCADA.stAutomaticModeHMI.diSetpointAutomatic := 0;
|
||||
_xEnableString := FALSE;
|
||||
@@ -779,6 +843,7 @@ END_IF]]></ST>
|
||||
|
||||
// Check for errors
|
||||
IF _xStringsErrorActive THEN
|
||||
_xErrorShutdown := TRUE;
|
||||
_iState := 1000;
|
||||
END_IF
|
||||
|
||||
@@ -791,6 +856,7 @@ END_IF]]></ST>
|
||||
IF (NOT _xStringsInSchutdownDischargeMode) AND _xStringsOff THEN
|
||||
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;
|
||||
_iState := 0;
|
||||
END_IF
|
||||
|
||||
@@ -802,11 +868,13 @@ END_IF]]></ST>
|
||||
|
||||
// Check for errors
|
||||
IF _xStringsErrorActive THEN
|
||||
_xErrorShutdown := TRUE;
|
||||
_iState := 1000;
|
||||
END_IF
|
||||
|
||||
|
||||
1000: // Error state
|
||||
GVL_MODBUS.stModbusEMSComm.stModbusReg10.uiActiveParallelMembers := 0;
|
||||
_xEnableString := FALSE;
|
||||
_rPowerInverter := 0.0;
|
||||
GVL_MODBUS.stModbusEMSComm.stModbusReg11.eBatteryStatus := E_BATTERY_STATUS.ERROR;
|
||||
@@ -820,6 +888,9 @@ END_IF]]></ST>
|
||||
// Reset modbus error flag
|
||||
GVL_MODBUS.stModbusEMSComm.stModbusReg11.eBatteryStatus := E_BATTERY_STATUS.OFF;
|
||||
|
||||
// Reset error shutdown flag
|
||||
_xErrorShutdown := FALSE;
|
||||
|
||||
// Goto init state
|
||||
_iState := 0;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user