diff --git a/PLC/GVLs/GVL_CONFIG.TcGVL b/PLC/GVLs/GVL_CONFIG.TcGVL index 8eee4d3..ea76357 100644 --- a/PLC/GVLs/GVL_CONFIG.TcGVL +++ b/PLC/GVLs/GVL_CONFIG.TcGVL @@ -10,6 +10,8 @@ VAR_GLOBAL CONSTANT uiNumberOfUnits : UINT := uiNumberOfStrings * 12; END_VAR VAR_GLOBAL PERSISTENT + axStringEnabled : ARRAY [0..uiNumberOfStrings-1] OF BOOL; + // =========================== // Unit hardware config // =========================== diff --git a/PLC/POUs/MAIN.TcPOU b/PLC/POUs/MAIN.TcPOU index 070924c..620fb46 100644 --- a/PLC/POUs/MAIN.TcPOU +++ b/PLC/POUs/MAIN.TcPOU @@ -156,6 +156,9 @@ VAR _fbPowerMeterPower : FB_PowerMeter; _fbPowerMeter24V : FB_PowerMeter; + // Number of activated strings (from configuration) + _uiNumberOfActiveStrings : UINT; + _xGetPowerMeterData : BOOL; END_VAR ]]> @@ -306,7 +309,7 @@ _tonStartupDelay(IN := TRUE); // Call string 1 _afbStrings[0]( - xEnable := _xEnableString, + xEnable := _xEnableString AND GVL_CONFIG.axStringEnabled[0], uiStringNumber := 0, xErrorShutdown := _xErrorShutdown, xStartBalancing := _xStartBalancing, @@ -335,7 +338,7 @@ GVL_MODBUS.stBMSErrorReg.wBMSWarningActive.stBitmap.bSafetyIntlkString1 := (NOT // Call string 2 _afbStrings[1]( - xEnable := _xEnableString, + xEnable := _xEnableString AND GVL_CONFIG.axStringEnabled[1], uiStringNumber := 1, xErrorShutdown := _xErrorShutdown, xStartBalancing := _xStartBalancing, @@ -380,8 +383,18 @@ _rMinCurrentInverterDCVoltage := 10_000; _rHighestSegmentVoltage := 0.0; _rSmallestSegmentVoltage := 1_000.0; _xStringsInAutoMode := TRUE; +_uiNumberOfActiveStrings := 0; +_rStringsSumVoltage := 0; FOR _ui := 0 TO (GVL_CONFIG.uiNumberOfStrings-1) DO + // Ignore deactivated strings + IF (NOT GVL_CONFIG.axStringEnabled[_ui]) THEN + CONTINUE; + END_IF + + // Count number of active strings + _uiNumberOfActiveStrings := _uiNumberOfActiveStrings + 1; + // Check ready state IF (NOT _afbStrings[_ui].xReady) THEN _xStringsReady := FALSE; @@ -437,6 +450,9 @@ FOR _ui := 0 TO (GVL_CONFIG.uiNumberOfStrings-1) DO _rHighestSegmentVoltage := _afbStrings[_ui].rHighestSegmentVoltage; END_IF + // Calculate sum voltage + _rStringsSumVoltage := _rStringsSumVoltage + _afbStrings[_ui].rCurrentVoltage; + // Get auto mode status IF NOT _afbStrings[_ui].xAllModulesInAutoMode THEN _xStringsInAutoMode := FALSE; @@ -446,7 +462,7 @@ END_FOR // =============================== // Calculate sum power for string balancing // =============================== -_rStringsSumVoltage := _afbStrings[0].rCurrentVoltage + _afbStrings[1].rCurrentVoltage; +// _rStringsSumVoltage := _afbStrings[0].rCurrentVoltage + _afbStrings[1].rCurrentVoltage; // =============================== @@ -928,20 +944,22 @@ _fbPowerMeter24V();]]> END_CASE // Calculate string power balancing -IF _rStringsSumVoltage <> 0 AND (GVL_CONFIG.uiNumberOfStrings <> 0) THEN +IF _rStringsSumVoltage <> 0 AND (_uiNumberOfActiveStrings <> 0) THEN FOR _ui := 0 TO (GVL_CONFIG.uiNumberOfStrings-1) DO - // Calculate delta u to middle voltage - _rDeltaUm := (_afbStrings[_ui].rCurrentVoltage * GVL_CONFIG.uiNumberOfStrings - _rStringsSumVoltage) / _rStringsSumVoltage; - - // Discharging - IF _rPowerInverter > 0 THEN - _arPowerString[_ui] := (_rPowerInverter / GVL_CONFIG.uiNumberOfStrings) * ( 1 + (_rDeltaUm * GVL_CONFIG.rBalancingFactor)); - // Charging - ELSIF _rPowerInverter < 0 THEN - _arPowerString[_ui] := (_rPowerInverter / GVL_CONFIG.uiNumberOfStrings) * ( 1 - (_rDeltaUm * GVL_CONFIG.rBalancingFactor)); - // Nothing - ELSE - _arPowerString[_ui] := 0.0; + IF GVL_CONFIG.axStringEnabled[_ui] THEN + // Calculate delta u to middle voltage + _rDeltaUm := (_afbStrings[_ui].rCurrentVoltage * _uiNumberOfActiveStrings - _rStringsSumVoltage) / _rStringsSumVoltage; + + // Discharging + IF _rPowerInverter > 0 THEN + _arPowerString[_ui] := (_rPowerInverter / _uiNumberOfActiveStrings) * ( 1 + (_rDeltaUm * GVL_CONFIG.rBalancingFactor)); + // Charging + ELSIF _rPowerInverter < 0 THEN + _arPowerString[_ui] := (_rPowerInverter / _uiNumberOfActiveStrings) * ( 1 - (_rDeltaUm * GVL_CONFIG.rBalancingFactor)); + // Nothing + ELSE + _arPowerString[_ui] := 0.0; + END_IF END_IF END_FOR ELSE