IBN changes
added sync units for cabinet temperature, changes in modbus interface to EMS (1.0.4 and 1.0.5), added error counter to modbus communication, lot of changes to kaco (faults, consecutive errors, bms error messages), isolation error ledge, allowed startbalancing when on shutdown, tower light integration
This commit is contained in:
@@ -82,7 +82,7 @@ VAR
|
||||
_fbReadACValues : FB_MBReadRegs;
|
||||
|
||||
// Time for polling for current dc values and check for inverter error
|
||||
_timPollingDelay : TIME := T#500MS;
|
||||
_timPollingDelay : TIME := T#1S;
|
||||
|
||||
// Time for setting the current power
|
||||
_timSetPowerDelay : TIME := T#250MS;
|
||||
@@ -101,6 +101,12 @@ VAR
|
||||
// Inverter alarm
|
||||
_fbErrorInverterAlarm : FB_TcAlarm;
|
||||
|
||||
// Error when reading cyclic data
|
||||
_fbCyclicDataAlarm : FB_TcAlarm;
|
||||
|
||||
// Error when reading heartbeat
|
||||
_fbHeartBeatAlarm : FB_TcAlarm;
|
||||
|
||||
// Flag if battery limits have been set
|
||||
_xBatteryLimitsSet : BOOL := FALSE;
|
||||
|
||||
@@ -143,12 +149,48 @@ VAR
|
||||
// Current PCU state and alarm messages
|
||||
_stPCUState : ST_KACU_PCU;
|
||||
|
||||
// Current PCU cabinet temperature
|
||||
_iCabTemp : INT;
|
||||
|
||||
// Current PCU state and alarm messages
|
||||
_stPCUStateDebug : ST_KACU_PCU;
|
||||
|
||||
// Current PCU state and alarm messages
|
||||
_stPCUStateDebug2 : ST_KACU_PCU;
|
||||
|
||||
_iCurrentErrorCountHB : UDINT := 0; // Error count since last successfull read on writeRequestedState
|
||||
_iErrorCountHB : UDINT := 0; // Total error count on writeRequestedState
|
||||
_iErrorIDHB : UDINT := 0; // Error ID on writeRequestedState
|
||||
_iCurrentErrorCountWRS : UDINT := 0; // Error count since last successfull read on writeRequestedState
|
||||
_iErrorCountWRS : UDINT := 0; // Total error count on writeRequestedState
|
||||
_iErrorIDWRS : UDINT := 0; // Error ID on writeRequestedState
|
||||
_iCurrentErrorCountWPC : UDINT := 0; // Error count since last successfull read on writePowerCommand
|
||||
_iErrorCountWPC : UDINT := 0; // Total error count on writePowerCommand
|
||||
_iErrorIDWPC : UDINT := 0; // Error ID on writePowerCommand
|
||||
_iCurrentErrorCountRCS : UDINT := 0; // Error count since last successfull read on readCurrentState
|
||||
_iErrorCountRCS : UDINT := 0; // Total error count on readCurrentState
|
||||
_iErrorIDRCS : UDINT := 0; // Error ID on readCurrentState
|
||||
_iCurrentErrorCountRPCUS : UDINT := 0; // Error count since last successfull read on readPCUState
|
||||
_iErrorCountRPCUS : UDINT := 0; // Total error count on readPCUState
|
||||
_iErrorIDRPCUS : UDINT := 0; // Error ID on readPCUState
|
||||
_iErrorCountRDCV : UDINT := 0; // Total error count on readDCValues
|
||||
_iErrorIDRDCV : UDINT := 0; // Error ID on readDCValues
|
||||
_iErrorCountRACV : UDINT := 0; // Total error count on readACValues
|
||||
_iErrorIDRACV : UDINT := 0; // Error ID on readACValues
|
||||
_xResetCounter : BOOL := FALSE; // Reset error counter
|
||||
|
||||
// Error during cyclic reading
|
||||
_xErrorCyclicData : BOOL;
|
||||
_xErrorCyclicDataLedge : BOOL; // cyclic data ledge
|
||||
|
||||
_xHeartBeatNOK : BOOL; // heartbeat error ledge
|
||||
|
||||
// Internal inverter error
|
||||
_xErrorInverter : BOOL;
|
||||
|
||||
// Inverterfault (introduced by NA-Schutz)
|
||||
_xFaultInverter : BOOL;
|
||||
|
||||
// Inverter name for alarm message
|
||||
_sName : STRING;
|
||||
END_VAR
|
||||
@@ -331,7 +373,7 @@ CASE _iState OF
|
||||
|
||||
// Dont set inverter into off state when an internal error occured
|
||||
// because this will reset the error message
|
||||
IF _xErrorInverter THEN
|
||||
IF _xErrorInverter OR _xErrorCyclicData OR (NOT xHeartbeatOk) THEN
|
||||
_iWSetPct := 0;
|
||||
_iState := 1000;
|
||||
END_IF
|
||||
@@ -341,9 +383,12 @@ CASE _iState OF
|
||||
_iState := 1001;
|
||||
|
||||
1001: // Error state, wait for reset
|
||||
IF xReset AND (NOT xEnable) AND (NOT _xErrorCyclicData) AND (NOT _xErrorInverter) THEN
|
||||
IF xReset AND (NOT xEnable) AND (NOT _xErrorInverter) AND (NOT _xErrorCyclicData) AND xHeartbeatOk THEN
|
||||
_eRequestedState := OFF;
|
||||
xError := FALSE;
|
||||
_xFaultInverter := FALSE;
|
||||
_xErrorCyclicDataLedge := FALSE;
|
||||
_xHeartBeatNOK := FALSE;
|
||||
_iState := 0;
|
||||
END_IF
|
||||
|
||||
@@ -382,18 +427,44 @@ END_VAR]]></Declaration>
|
||||
|
||||
// Create inverter main alarm
|
||||
_fbErrorInverterAlarm.CreateEx(stEventEntry := TC_EVENTS.Inverter.InverterError, bWithConfirmation := TRUE, 0);
|
||||
_fbErrorInverterAlarm.ipArguments.Clear().AddString(_sName);]]></ST>
|
||||
_fbErrorInverterAlarm.ipArguments.Clear().AddString(_sName);
|
||||
|
||||
// Create inverter heartbeat alarm
|
||||
_fbHeartBeatAlarm.CreateEx(stEventEntry := TC_EVENTS.Inverter.InverterHeartbeatError, bWithConfirmation := TRUE, 0);
|
||||
_fbHeartBeatAlarm.ipArguments.Clear().AddString(_sName);
|
||||
|
||||
// Create inverter cyclic data alarm
|
||||
_fbCyclicDataAlarm.CreateEx(stEventEntry := TC_EVENTS.Inverter.InverterCyclicError, bWithConfirmation := TRUE, 0);
|
||||
_fbCyclicDataAlarm.ipArguments.Clear().AddString(_sName);]]></ST>
|
||||
</Implementation>
|
||||
</Method>
|
||||
<Action Name="HandleCyclicData" Id="{4343583a-b80a-437e-8fc8-9963ab894fbc}">
|
||||
<Implementation>
|
||||
<ST><![CDATA[// Reset error flags on reset command
|
||||
IF _xErrorCyclicData AND xReset THEN
|
||||
_xErrorCyclicData := FALSE;
|
||||
<ST><![CDATA[IF _xResetCounter THEN
|
||||
_xResetCounter := FALSE;
|
||||
_iCurrentErrorCountHB := 0;
|
||||
_iErrorCountHB := 0;
|
||||
_iErrorIDHB := 0;
|
||||
_iCurrentErrorCountWRS := 0;
|
||||
_iErrorCountWRS := 0;
|
||||
_iErrorIDWRS := 0;
|
||||
_iCurrentErrorCountWPC := 0;
|
||||
_iErrorCountWPC := 0;
|
||||
_iErrorIDWPC := 0;
|
||||
_iCurrentErrorCountRCS := 0;
|
||||
_iErrorCountRCS := 0;
|
||||
_iErrorIDRCS := 0;
|
||||
_iCurrentErrorCountRPCUS := 0;
|
||||
_iErrorCountRPCUS := 0;
|
||||
_iErrorIDRPCUS := 0;
|
||||
_iErrorCountRDCV := 0;
|
||||
_iErrorIDRDCV := 0;
|
||||
_iErrorCountRACV := 0;
|
||||
_iErrorIDRACV := 0;
|
||||
END_IF
|
||||
|
||||
// Fetch cyclic data with polling timer
|
||||
_tonPollingTimer(IN := TRUE);
|
||||
_tonPollingTimer(IN := TRUE, PT := _timPollingDelay);
|
||||
|
||||
// Write requested state
|
||||
_fbWriteRequestedState(
|
||||
@@ -408,8 +479,14 @@ _fbWriteRequestedState(
|
||||
bError=> ,
|
||||
nErrId=> );
|
||||
|
||||
IF (NOT _fbWriteRequestedState.bBusy) AND _fbWriteRequestedState.bError THEN
|
||||
_xErrorCyclicData := TRUE;
|
||||
IF (NOT _fbWriteRequestedState.bBusy) THEN
|
||||
IF _fbWriteRequestedState.bError THEN
|
||||
_iCurrentErrorCountWRS := _iCurrentErrorCountWRS + 1;
|
||||
_iErrorCountWRS := _iErrorCountWRS + 1;
|
||||
_iErrorIDWRS := _fbWriteRequestedState.nErrId;
|
||||
ELSE
|
||||
_iCurrentErrorCountWRS := 0;
|
||||
END_IF
|
||||
END_IF
|
||||
|
||||
|
||||
@@ -428,8 +505,14 @@ _fbWritePowerCommand(
|
||||
bError=> ,
|
||||
nErrId=> );
|
||||
|
||||
IF (NOT _fbWritePowerCommand.bBusy) AND _fbWritePowerCommand.bError THEN
|
||||
_xErrorCyclicData := TRUE;
|
||||
IF (NOT _fbWritePowerCommand.bBusy) THEN
|
||||
IF _fbWritePowerCommand.bError THEN
|
||||
_iCurrentErrorCountWPC := _iCurrentErrorCountWPC + 1;
|
||||
_iErrorCountWPC := _iErrorCountWPC + 1;
|
||||
_iErrorIDWPC := _fbWritePowerCommand.nErrId;
|
||||
ELSE
|
||||
_iCurrentErrorCountWPC := 0;
|
||||
END_IF
|
||||
END_IF
|
||||
|
||||
|
||||
@@ -449,8 +532,14 @@ _fbReadCurrentState(
|
||||
nErrId=> ,
|
||||
cbRead=> );
|
||||
|
||||
IF (NOT _fbReadCurrentState.bBusy) AND _fbReadCurrentState.bError THEN
|
||||
_xErrorCyclicData := TRUE;
|
||||
IF (NOT _fbReadCurrentState.bBusy) THEN
|
||||
IF _fbReadCurrentState.bError THEN
|
||||
_iCurrentErrorCountRCS := _iCurrentErrorCountRCS + 1;
|
||||
_iErrorCountRCS := _iErrorCountRCS + 1;
|
||||
_iErrorIDRCS := _fbReadCurrentState.nErrId;
|
||||
ELSE
|
||||
_iCurrentErrorCountRCS := 0;
|
||||
END_IF
|
||||
END_IF
|
||||
|
||||
IF _eCurrentState = E_KACO_CURRENT_STATE.GRID_CONNECTED OR _eCurrentState = E_KACO_CURRENT_STATE.THROTTLED THEN
|
||||
@@ -476,16 +565,35 @@ _fbReadPCUState(
|
||||
nErrId=> ,
|
||||
cbRead=> );
|
||||
|
||||
IF (NOT _fbReadPCUState.bBusy) AND _fbReadPCUState.bError THEN
|
||||
_xErrorCyclicData := TRUE;
|
||||
IF (NOT _fbReadPCUState.bBusy) THEN
|
||||
IF _fbReadPCUState.bError THEN
|
||||
_iCurrentErrorCountRPCUS := _iCurrentErrorCountRPCUS + 1;
|
||||
_iErrorCountRPCUS := _iErrorCountRPCUS + 1;
|
||||
_iErrorIDRPCUS := _fbReadPCUState.nErrId;
|
||||
IF _iCurrentErrorCountRPCUS >= GVL_CONFIG.udiMaxConsecutiveInvError THEN
|
||||
_xErrorCyclicData := TRUE;
|
||||
END_IF
|
||||
ELSE
|
||||
_iCurrentErrorCountRPCUS := 0;
|
||||
END_IF
|
||||
END_IF
|
||||
|
||||
IF (_stPCUState.ePCUState = E_KACO_PCU_STATE.ERROR) OR (_stPCUState.ePCUError <> E_KACO_PCU_ERROR.NO_EVENT) THEN
|
||||
_xErrorInverter := TRUE;
|
||||
IF ((_stPCUState.ePCUState = E_KACO_PCU_STATE.ERROR) OR (_stPCUState.ePCUError <> E_KACO_PCU_ERROR.NO_EVENT)) AND (_stPCUState.ePCUError <> 11) THEN
|
||||
// ignore undervoltage error when not enabled
|
||||
_stPCUStateDebug := _stPCUState;
|
||||
IF NOT xReleasePower AND _stPCUState.ePCUError = E_KACO_PCU_ERROR.UNDER_VOLT THEN
|
||||
_xErrorInverter := FALSE;
|
||||
ELSE
|
||||
_xErrorInverter := TRUE;
|
||||
_stPCUStateDebug2 := _stPCUState;
|
||||
END_IF
|
||||
ELSE
|
||||
_xErrorInverter := FALSE;
|
||||
END_IF
|
||||
|
||||
IF _eCurrentState = E_KACO_CURRENT_STATE.FAULT AND xReleasePower THEN
|
||||
_xErrorInverter := TRUE;
|
||||
END_IF
|
||||
|
||||
// Read current dc values
|
||||
_fbReadDCValues(
|
||||
@@ -516,6 +624,8 @@ IF (NOT _fbReadDCValues.bBusy) THEN
|
||||
stCurrentValues.rActDCCurrent := 0.0;
|
||||
stCurrentValues.rActDCVoltage := 0.0;
|
||||
stCurrentValues.rActDCPower := 0.0;
|
||||
_iErrorCountRDCV := _iErrorCountRDCV + 1;
|
||||
_iErrorIDRDCV := _fbReadDCValues.nErrId;
|
||||
END_IF
|
||||
END_IF
|
||||
|
||||
@@ -561,9 +671,39 @@ IF (NOT _fbReadACValues.bBusy) THEN
|
||||
stCurrentValues.rActApparentPower := 0.0;
|
||||
stCurrentValues.rActReactivePower := 0.0;
|
||||
stCurrentValues.rActPowerFactor := 0.0;
|
||||
_iErrorCountRACV := _iErrorCountRACV + 1;
|
||||
_iErrorIDRACV := _fbReadACValues.nErrId;
|
||||
END_IF
|
||||
END_IF
|
||||
|
||||
IF _iCurrentErrorCountRPCUS >= GVL_CONFIG.udiMaxConsecutiveInvError OR
|
||||
_iCurrentErrorCountRCS >= GVL_CONFIG.udiMaxConsecutiveInvError OR
|
||||
_iCurrentErrorCountWPC >= GVL_CONFIG.udiMaxConsecutiveInvError OR
|
||||
_iCurrentErrorCountWRS >= GVL_CONFIG.udiMaxConsecutiveInvError OR
|
||||
_iCurrentErrorCountHB >= GVL_CONFIG.udiMaxConsecutiveInvError THEN
|
||||
_xErrorCyclicData := TRUE;
|
||||
ELSE
|
||||
_xErrorCyclicData := FALSE;
|
||||
END_IF
|
||||
|
||||
// set fault flag when error active
|
||||
IF _xErrorCyclicData THEN
|
||||
_xErrorCyclicDataLedge := TRUE;
|
||||
END_IF
|
||||
|
||||
// handle alarm
|
||||
IF _xErrorCyclicData AND NOT _fbCyclicDataAlarm.bRaised THEN
|
||||
_fbCyclicDataAlarm.Raise();
|
||||
END_IF
|
||||
|
||||
IF NOT _xErrorCyclicData AND _fbCyclicDataAlarm.bRaised THEN
|
||||
_fbCyclicDataAlarm.Clear(0, FALSE);
|
||||
END_IF
|
||||
|
||||
IF _fbCyclicDataAlarm.eConfirmationState = TcEventConfirmationState.WaitForConfirmation AND xReset THEN
|
||||
_fbCyclicDataAlarm.Confirm(0);
|
||||
END_IF
|
||||
|
||||
// Reset polling timer
|
||||
IF _tonPollingTimer.Q THEN
|
||||
_tonPollingTimer(IN := FALSE);
|
||||
@@ -572,12 +712,7 @@ END_IF]]></ST>
|
||||
</Action>
|
||||
<Action Name="HandleHeartbeat" Id="{eeb5f65a-fd91-4c22-ab2e-3080c24e87fb}">
|
||||
<Implementation>
|
||||
<ST><![CDATA[// Reset hearbeat signal only with reset signal
|
||||
IF (NOT xHeartbeatOk) AND xReset THEN
|
||||
xHeartbeatOk := TRUE;
|
||||
END_IF
|
||||
|
||||
// Self resetting watchdog timer
|
||||
<ST><![CDATA[// Self resetting watchdog timer
|
||||
_tonWatchdogResetTimer(IN := TRUE);
|
||||
|
||||
// Timeout should be less than timer interval
|
||||
@@ -595,9 +730,37 @@ _fbWriteHearbeatRegister(
|
||||
|
||||
// Because there is no heartbeat register to read,
|
||||
// we will use a successfull write as a valid heartbeat signal
|
||||
IF _fbWriteHearbeatRegister.bError THEN
|
||||
xHeartbeatOk := FALSE;
|
||||
xError := TRUE;
|
||||
IF NOT _fbWriteHearbeatRegister.bBusy THEN
|
||||
IF _fbWriteHearbeatRegister.bError THEN
|
||||
_iCurrentErrorCountHB := _iCurrentErrorCountHB + 1;
|
||||
_iErrorCountHB := _iErrorCountHB + 1;
|
||||
_iErrorIDHB := _fbWriteHearbeatRegister.nErrId;
|
||||
IF _iCurrentErrorCountHB >= GVL_CONFIG.udiMaxConsecutiveInvError THEN
|
||||
xHeartbeatOk := FALSE;
|
||||
xError := TRUE;
|
||||
END_IF
|
||||
ELSE
|
||||
_iCurrentErrorCountHB := 0;
|
||||
xHeartbeatOk := TRUE;
|
||||
END_IF
|
||||
END_IF
|
||||
|
||||
// set fault flag when error active
|
||||
IF NOT xHeartbeatOk THEN
|
||||
_xHeartBeatNOK := TRUE;
|
||||
END_IF
|
||||
|
||||
// handle alarm
|
||||
IF NOT xHeartbeatOk AND NOT _fbHeartBeatAlarm.bRaised THEN
|
||||
_fbHeartBeatAlarm.Raise();
|
||||
END_IF
|
||||
|
||||
IF xHeartbeatOk AND _fbHeartBeatAlarm.bRaised THEN
|
||||
_fbHeartBeatAlarm.Clear(0, FALSE);
|
||||
END_IF
|
||||
|
||||
IF _fbHeartBeatAlarm.eConfirmationState = TcEventConfirmationState.WaitForConfirmation AND xReset THEN
|
||||
_fbHeartBeatAlarm.Confirm(0);
|
||||
END_IF
|
||||
|
||||
// Reset timer
|
||||
@@ -640,7 +803,7 @@ _fbErrorInverterAlarm.ipArguments.Clear().AddString(_sName);]]></ST>
|
||||
_fbReadRegisters(
|
||||
sIPAddr:= sInverterIPAddr,
|
||||
nTCPPort:= 502,
|
||||
nUnitID:= 16#FF, // 16#FF for Modbus TCP
|
||||
nUnitID:= 16#01, // 16#FF for Modbus TCP
|
||||
nQuantity:= 2,
|
||||
nMBAddr:= BATTERY_LIMIT_SF_START,
|
||||
cbLength:= SIZEOF(_arBattScalingFactors),
|
||||
@@ -668,7 +831,7 @@ _fbErrorInverterAlarm.ipArguments.Clear().AddString(_sName);]]></ST>
|
||||
_fbWriteRegisters(
|
||||
sIPAddr:= sInverterIPAddr,
|
||||
nTCPPort:= 502,
|
||||
nUnitID:= 16#FF, // 16#FF for Modbus TCP
|
||||
nUnitID:= 16#01, // 16#FF for Modbus TCP
|
||||
nQuantity:= 6,
|
||||
nMBAddr:= BATTERY_SET_LIMITS_START,
|
||||
cbLength:= SIZEOF(_auiBatteryLimitValues),
|
||||
@@ -695,7 +858,7 @@ _fbErrorInverterAlarm.ipArguments.Clear().AddString(_sName);]]></ST>
|
||||
_fbWriteRegister(
|
||||
sIPAddr:= sInverterIPAddr,
|
||||
nTCPPort:= 502,
|
||||
nUnitID:= 16#FF, // 16#FF for Modbus TCP
|
||||
nUnitID:= 16#01, // 16#FF for Modbus TCP
|
||||
nQuantity:= 1,
|
||||
nMBAddr:= DIS_MIN_V,
|
||||
cbLength:= SIZEOF(uiMinDisVoltage),
|
||||
@@ -723,7 +886,7 @@ _fbErrorInverterAlarm.ipArguments.Clear().AddString(_sName);]]></ST>
|
||||
_fbWriteRegister(
|
||||
sIPAddr:= sInverterIPAddr,
|
||||
nTCPPort:= 502,
|
||||
nUnitID:= 16#FF, // 16#FF for Modbus TCP
|
||||
nUnitID:= 16#01, // 16#FF for Modbus TCP
|
||||
nQuantity:= 1,
|
||||
nMBAddr:= CHA_MAX_V,
|
||||
cbLength:= SIZEOF(uiMaxChaVoltage),
|
||||
@@ -751,7 +914,7 @@ _fbErrorInverterAlarm.ipArguments.Clear().AddString(_sName);]]></ST>
|
||||
_fbWriteRegister(
|
||||
sIPAddr:= sInverterIPAddr,
|
||||
nTCPPort:= 502,
|
||||
nUnitID:= 16#FF, // 16#FF for Modbus TCP
|
||||
nUnitID:= 16#01, // 16#FF for Modbus TCP
|
||||
nQuantity:= 1,
|
||||
nMBAddr:= CHA_MAX_A,
|
||||
cbLength:= SIZEOF(uiMaxChaCurrent),
|
||||
@@ -779,7 +942,7 @@ _fbErrorInverterAlarm.ipArguments.Clear().AddString(_sName);]]></ST>
|
||||
_fbWriteRegister(
|
||||
sIPAddr:= sInverterIPAddr,
|
||||
nTCPPort:= 502,
|
||||
nUnitID:= 16#FF, // 16#FF for Modbus TCP
|
||||
nUnitID:= 16#01, // 16#FF for Modbus TCP
|
||||
nQuantity:= 1,
|
||||
nMBAddr:= DIS_MAX_A,
|
||||
cbLength:= SIZEOF(uiMaxDisCurrent),
|
||||
@@ -808,7 +971,7 @@ _fbErrorInverterAlarm.ipArguments.Clear().AddString(_sName);]]></ST>
|
||||
_fbWriteRegisters(
|
||||
sIPAddr:= sInverterIPAddr,
|
||||
nTCPPort:= 502,
|
||||
nUnitID:= 16#FF, // 16#FF for Modbus TCP
|
||||
nUnitID:= 16#01, // 16#FF for Modbus TCP
|
||||
nQuantity:= 1,
|
||||
nMBAddr:= EN_LIMIT,
|
||||
cbLength:= SIZEOF(_uiEnableLimit),
|
||||
|
||||
Reference in New Issue
Block a user