Implemented fixes and improvements during comissioning

- New Balancing mode
- HMI Interface for Inverterdata implemented
- Adjusted GVL_CONFIG values
- Read inverter data even when inverter is off
- Added OPC UA settings to inverter data hmi interface
- Added multisettings to safety project for strings
This commit is contained in:
Matthias Heisig
2024-05-06 11:05:33 +02:00
parent b95033a155
commit 327f324be8
58 changed files with 24795 additions and 3667 deletions

View File

@@ -12,7 +12,7 @@ VAR_INPUT
END_VAR
VAR_OUTPUT
// Output for SCS DC-Relais
xCloseDCRelais AT %Q*: BOOL;
//xCloseDCRelais AT %Q*: BOOL;
// Inverter active
xActive : BOOL;
@@ -86,7 +86,7 @@ VAR
_iErrorInState : INT;
// Time for polling for current dc values and check for inverter error
_timPollingDelay : TIME := T#250MS;
_timPollingDelay : TIME := T#500MS;
// Timer for polling of current values
_tonPollingTimer : TON;
@@ -103,6 +103,11 @@ VAR
// Inverter reset errors command
_uiResetInverter : UINT := 1;
// Inverter alarm
_fbErrorInverterAlarm : Fb_TcAlarm;
_sName : STRING;
END_VAR
VAR CONSTANT
// Inverter statemachine status register
@@ -195,9 +200,120 @@ CASE _iState OF
// If enable and INTLK Ok
IF xEnable THEN
_iState := 10;
xCloseDCRelais := TRUE;
//xCloseDCRelais := TRUE;
_tonPollingTimer(IN := FALSE, PT := _timPollingDelay);
ELSE
_tonPollingTimer(IN := TRUE, PT := _timPollingDelay);
END_IF
IF _tonPollingTimer.Q THEN
_tonPollingTimer(IN := FALSE, PT := _timPollingDelay);
_iState := 1;
END_IF
1: // Read inverter status
_fbReadRegister(
sIPAddr:= sInverterIPAddr,
nTCPPort:= 502,
nUnitID:= 16#FF, // 16#FF for Modbus TCP
nQuantity:= 1,
nMBAddr:= STATUS_REGISTER,
cbLength:= SIZEOF(_uiInverterState),
pDestAddr:= ADR(_uiInverterState),
bExecute:= TRUE,
tTimeout:= T#5S,
bBusy=> ,
bError=> ,
nErrId=> ,
cbRead=> );
// Check if reading mudbus register is done
IF NOT _fbReadRegister.bBusy THEN
IF NOT _fbReadRegister.bError THEN
_iState := 2;
ELSE
_iState := 1000;
END_IF
_fbReadRegister(bExecute := FALSE);
END_IF
2: // IF inverter is not in STANDYB(8) STATE, send command to shutdown inverter
IF (_uiInverterState = 8) OR (_uiInverterState = 1) THEN
_iState := 3;
ELSE
_uiPCSSetOperation := 3;
_iState := 200;
END_IF
3: // Read current DC values
_iErrorInState := _iState;
_fbReadRegister(
sIPAddr:= sInverterIPAddr,
nTCPPort:= 502,
nUnitID:= 16#FF, // 16#FF for Modbus TCP
nQuantity:= 6,
nMBAddr:= DC_VALUES_START_REGISTER,
cbLength:= SIZEOF(_awCurrentDCValues),
pDestAddr:= ADR(_awCurrentDCValues),
bExecute:= TRUE,
tTimeout:= T#5S,
bBusy=> ,
bError=> ,
nErrId=> ,
cbRead=> );
// Check if reading mudbus register is done
IF NOT _fbReadRegister.bBusy THEN
// If there was no error and the converter has no error continue
IF NOT _fbReadRegister.bError THEN
_iState := 4;
stCurrentValues.rActDCCurrent := LREAL_TO_REAL(WORD_TO_INT(_awCurrentDCValues[0]) * EXPT(10,WORD_TO_INT(_awCurrentDCValues[1])));
stCurrentValues.rActDCVoltage := LREAL_TO_REAL(WORD_TO_UINT(_awCurrentDCValues[2]) * EXPT(10,WORD_TO_INT(_awCurrentDCValues[3])));
stCurrentValues.rActDCPower := LREAL_TO_REAL(WORD_TO_INT(_awCurrentDCValues[4]) * EXPT(10,WORD_TO_INT(_awCurrentDCValues[5])));
ELSE
// Read error register
_iState := 1000;
END_IF
_fbReadRegister(bExecute := FALSE);
END_IF
4: // Read current ac values
_iErrorInState := _iState;
_fbReadRegister(
sIPAddr:= sInverterIPAddr,
nTCPPort:= 502,
nUnitID:= 16#FF, // 16#FF for Modbus TCP
nQuantity:= 10,
nMBAddr:= AC_VALUES_START_REGISTER,
cbLength:= SIZEOF(_awCurrentACValues),
pDestAddr:= ADR(_awCurrentACValues),
bExecute:= TRUE,
tTimeout:= T#5S,
bBusy=> ,
bError=> ,
nErrId=> ,
cbRead=> );
// Check if reading mudbus register is done
IF NOT _fbReadRegister.bBusy THEN
// If there was no error and the converter has no error continue
IF NOT _fbReadRegister.bError THEN
// Go back to polling state
_iState := 0;
stCurrentValues.rActACPower := LREAL_TO_REAL(WORD_TO_INT(_awCurrentACValues[0]) * EXPT(10,WORD_TO_INT(_awCurrentACValues[1])));
stCurrentValues.rActACFreq := LREAL_TO_REAL(WORD_TO_UINT(_awCurrentACValues[2]) * EXPT(10,WORD_TO_INT(_awCurrentACValues[3])));
stCurrentValues.rActApparentPower := LREAL_TO_REAL(WORD_TO_INT(_awCurrentACValues[4]) * EXPT(10,WORD_TO_INT(_awCurrentACValues[5])));
stCurrentValues.rActReactivePower := LREAL_TO_REAL(WORD_TO_INT(_awCurrentACValues[6]) * EXPT(10,WORD_TO_INT(_awCurrentACValues[7])));
stCurrentValues.rActPowerFactor := LREAL_TO_REAL(WORD_TO_INT(_awCurrentACValues[8]) * EXPT(10,WORD_TO_INT(_awCurrentACValues[9])));
ELSE
// Read error register
_iState := 1000;
END_IF
_fbReadRegister(bExecute := FALSE);
END_IF
10: // Wait for inverter to be online and in state STANDBY(8)
_fbReadRegister(
sIPAddr:= sInverterIPAddr,
@@ -529,8 +645,8 @@ CASE _iState OF
IF NOT _fbWriteRegister.bBusy THEN
// And there is no error, then continue
IF NOT _fbWriteRegister.bError THEN
_iState := 60;
_uiPCSSetOperation := 1;
_iState := 51;
_uiPCSSetOperation := 4;
ELSE
xError := TRUE;
// Goto error state
@@ -539,6 +655,36 @@ CASE _iState OF
_fbWriteRegister(bExecute := FALSE);
END_IF
51: // Go to started
_iErrorInState := _iState;
_fbWriteRegister(
sIPAddr:= sInverterIPAddr,
nTCPPort:= 502,
nUnitID:= 16#FF, // 16#FF for Modbus TCP
nQuantity:= 1,
nMBAddr:= PCS_SET_OPERATION_REGISTER,
cbLength:= SIZEOF(_uiPCSSetOperation),
pSrcAddr:= ADR(_uiPCSSetOperation),
bExecute:= TRUE,
tTimeout:= T#5S,
bBusy=> ,
bError=> ,
nErrId=> );
// If writing modbus register is done
IF NOT _fbWriteRegister.bBusy THEN
// And there is no error, then continue
IF NOT _fbWriteRegister.bError THEN
_uiPCSSetOperation := 1;
_iState := 60;
ELSE
// Goto error state
_iState := 1000;
END_IF
_fbWriteRegister(bExecute := FALSE);
END_IF
60: // Switch to THROTTLED mode
_iErrorInState := _iState;
_fbWriteRegister(
@@ -616,8 +762,9 @@ CASE _iState OF
END_IF
ELSE
xError := TRUE;
_uiPCSSetOperation := 3;
// Read error register
_iState := 990;
_iState := 200;
END_IF
_fbReadRegister(bExecute := FALSE);
END_IF
@@ -644,8 +791,8 @@ CASE _iState OF
// If there was no error and the converter has no error continue
IF NOT _fbReadRegister.bError THEN
_iState := 85;
stCurrentValues.rActDCCurrent := LREAL_TO_REAL(WORD_TO_UINT(_awCurrentDCValues[0]) * EXPT(10,WORD_TO_INT(_awCurrentDCValues[1])));
stCurrentValues.rActDCVoltage := LREAL_TO_REAL(WORD_TO_UINT(_awCurrentDCValues[2]) * EXPT(10,WORD_TO_INT(_awCurrentDCValues[3])));
stCurrentValues.rActDCCurrent := LREAL_TO_REAL(WORD_TO_INT(_awCurrentDCValues[0]) * EXPT(10,WORD_TO_INT(_awCurrentDCValues[1])));
stCurrentValues.rActDCVoltage := LREAL_TO_REAL(WORD_TO_INT(_awCurrentDCValues[2]) * EXPT(10,WORD_TO_INT(_awCurrentDCValues[3])));
stCurrentValues.rActDCPower := LREAL_TO_REAL(WORD_TO_INT(_awCurrentDCValues[4]) * EXPT(10,WORD_TO_INT(_awCurrentDCValues[5])));
ELSE
// Read error register
@@ -676,7 +823,7 @@ CASE _iState OF
// If there was no error and the converter has no error continue
IF NOT _fbReadRegister.bError THEN
// Go back to polling state
_iState := 65;
_iState := 90;
stCurrentValues.rActACPower := LREAL_TO_REAL(WORD_TO_INT(_awCurrentACValues[0]) * EXPT(10,WORD_TO_INT(_awCurrentACValues[1])));
stCurrentValues.rActACFreq := LREAL_TO_REAL(WORD_TO_UINT(_awCurrentACValues[2]) * EXPT(10,WORD_TO_INT(_awCurrentACValues[3])));
stCurrentValues.rActApparentPower := LREAL_TO_REAL(WORD_TO_INT(_awCurrentACValues[4]) * EXPT(10,WORD_TO_INT(_awCurrentACValues[5])));
@@ -689,6 +836,34 @@ CASE _iState OF
_fbReadRegister(bExecute := FALSE);
END_IF
90: // Read current inverter status
_fbReadRegister(
sIPAddr:= sInverterIPAddr,
nTCPPort:= 502,
nUnitID:= 16#FF, // 16#FF for Modbus TCP
nQuantity:= 1,
nMBAddr:= STATUS_REGISTER,
cbLength:= SIZEOF(_uiInverterState),
pDestAddr:= ADR(_uiInverterState),
bExecute:= TRUE,
tTimeout:= T#5S,
bBusy=> ,
bError=> ,
nErrId=> ,
cbRead=> );
// Check if reading mudbus register is done
IF NOT _fbReadRegister.bBusy THEN
IF NOT _fbReadRegister.bError THEN
_iState := 65;
stCurrentValues.uiStatus := _uiInverterState;
ELSE
// Read error register
_iState := 1000;
END_IF
_fbReadRegister(bExecute := FALSE);
END_IF
200: // Shutdown sequence
_iErrorInState := _iState;
_fbWriteRegister(
@@ -710,8 +885,6 @@ CASE _iState OF
// And there is no error, then continue
IF NOT _fbWriteRegister.bError THEN
_iState := 210;
stCurrentValues.rActDCCurrent := 0.0;
stCurrentValues.rActDCVoltage := 0.0;
ELSE
// Goto error state
_iState := 1000;
@@ -749,7 +922,7 @@ CASE _iState OF
IF NOT _fbReadRegister.bError THEN
_iState := 0;
xActive := FALSE;
xCloseDCRelais := FALSE;
//xCloseDCRelais := FALSE;
END_IF
_fbReadRegister(bExecute := FALSE);
END_IF
@@ -805,13 +978,68 @@ CASE _iState OF
xError := FALSE;
_fbWriteRegister(bExecute := FALSE);
END_IF
END_CASE]]></ST>
END_CASE
IF xError AND (NOT _fbErrorInverterAlarm.bRaised) THEN
_fbErrorInverterAlarm.Raise(0);
END_IF
IF (NOT xError) AND _fbErrorInverterAlarm.bRaised THEN
_fbErrorInverterAlarm.Clear(0, FALSE);
END_IF
IF (_fbErrorInverterAlarm.eConfirmationState = TcEventConfirmationState.WaitForConfirmation) AND xReset THEN
_fbErrorInverterAlarm.Confirm(0);
END_IF]]></ST>
</Implementation>
<Method Name="FB_init" Id="{a80728a8-68c7-4f6a-87fc-246cb88104d4}">
<Declaration><![CDATA[METHOD FB_init : BOOL
VAR_INPUT
bInitRetains : BOOL; // if TRUE, the retain variables are initialized (warm start / cold start)
bInCopyCode : BOOL; // if TRUE, the instance afterwards gets moved into the copy code (online change)
sName : STRING;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[_sName := sName;
// Create inverter main alarm
_fbErrorInverterAlarm.CreateEx(stEventEntry := TC_EVENTS.Inverter.InverterError, bWithConfirmation := TRUE, 0);
_fbErrorInverterAlarm.ipArguments.Clear().AddString(_sName);]]></ST>
</Implementation>
</Method>
<LineIds Name="FB_PowerSupplySunspec">
<LineId Id="774" Count="10" />
<LineId Id="1550" Count="0" />
<LineId Id="785" Count="28" />
<LineId Id="785" Count="4" />
<LineId Id="2615" Count="0" />
<LineId Id="790" Count="0" />
<LineId Id="2614" Count="0" />
<LineId Id="2613" Count="0" />
<LineId Id="2616" Count="1" />
<LineId Id="2906" Count="0" />
<LineId Id="2618" Count="3" />
<LineId Id="2623" Count="15" />
<LineId Id="2622" Count="0" />
<LineId Id="2639" Count="0" />
<LineId Id="2644" Count="0" />
<LineId Id="2641" Count="0" />
<LineId Id="2643" Count="0" />
<LineId Id="2642" Count="0" />
<LineId Id="2721" Count="0" />
<LineId Id="2640" Count="0" />
<LineId Id="2645" Count="1" />
<LineId Id="2648" Count="1" />
<LineId Id="2651" Count="0" />
<LineId Id="2722" Count="0" />
<LineId Id="2652" Count="0" />
<LineId Id="2650" Count="0" />
<LineId Id="2653" Count="0" />
<LineId Id="2656" Count="64" />
<LineId Id="2654" Count="1" />
<LineId Id="2647" Count="0" />
<LineId Id="791" Count="22" />
<LineId Id="1701" Count="5" />
<LineId Id="814" Count="1" />
<LineId Id="1714" Count="0" />
@@ -866,7 +1094,14 @@ END_CASE]]></ST>
<LineId Id="1493" Count="0" />
<LineId Id="948" Count="23" />
<LineId Id="1175" Count="0" />
<LineId Id="972" Count="42" />
<LineId Id="972" Count="4" />
<LineId Id="2907" Count="1" />
<LineId Id="2969" Count="18" />
<LineId Id="3031" Count="0" />
<LineId Id="2988" Count="5" />
<LineId Id="2909" Count="0" />
<LineId Id="2996" Count="0" />
<LineId Id="977" Count="37" />
<LineId Id="1560" Count="1" />
<LineId Id="1015" Count="3" />
<LineId Id="1127" Count="0" />
@@ -876,6 +1111,7 @@ END_CASE]]></ST>
<LineId Id="1099" Count="0" />
<LineId Id="1045" Count="0" />
<LineId Id="1176" Count="0" />
<LineId Id="2723" Count="0" />
<LineId Id="1046" Count="6" />
<LineId Id="1063" Count="20" />
<LineId Id="1090" Count="0" />
@@ -891,10 +1127,18 @@ END_CASE]]></ST>
<LineId Id="1776" Count="1" />
<LineId Id="1762" Count="4" />
<LineId Id="1738" Count="0" />
<LineId Id="3213" Count="1" />
<LineId Id="3216" Count="15" />
<LineId Id="3215" Count="0" />
<LineId Id="3232" Count="0" />
<LineId Id="3240" Count="0" />
<LineId Id="3234" Count="0" />
<LineId Id="3236" Count="2" />
<LineId Id="3235" Count="0" />
<LineId Id="3239" Count="0" />
<LineId Id="3233" Count="0" />
<LineId Id="1093" Count="1" />
<LineId Id="1102" Count="19" />
<LineId Id="1166" Count="1" />
<LineId Id="1122" Count="4" />
<LineId Id="1102" Count="24" />
<LineId Id="1054" Count="0" />
<LineId Id="1295" Count="4" />
<LineId Id="1128" Count="0" />
@@ -917,8 +1161,21 @@ END_CASE]]></ST>
<LineId Id="1293" Count="0" />
<LineId Id="2235" Count="0" />
<LineId Id="1291" Count="1" />
<LineId Id="1056" Count="0" />
<LineId Id="12" Count="0" />
<LineId Id="2418" Count="0" />
<LineId Id="2417" Count="0" />
<LineId Id="2419" Count="1" />
<LineId Id="2422" Count="0" />
<LineId Id="2421" Count="0" />
<LineId Id="2423" Count="1" />
<LineId Id="2426" Count="0" />
<LineId Id="2425" Count="0" />
<LineId Id="2427" Count="1" />
</LineIds>
<LineIds Name="FB_PowerSupplySunspec.FB_init">
<LineId Id="15" Count="1" />
<LineId Id="11" Count="0" />
<LineId Id="7" Count="1" />
</LineIds>
</POU>
</TcPlcObject>

View File

@@ -4,28 +4,49 @@
<Declaration><![CDATA[TYPE ST_SUNSPEC_CURRENT_VALUES :
STRUCT
// Current DC current (A)
{attribute 'OPC.UA.DA' := '1'}
{attribute 'OPC.UA.DA.Access' := '1'}
rActDCCurrent : REAL;
// Current DC voltage (V)
{attribute 'OPC.UA.DA' := '1'}
{attribute 'OPC.UA.DA.Access' := '1'}
rActDCVoltage : REAL;
// Current DC power (W)
{attribute 'OPC.UA.DA' := '1'}
{attribute 'OPC.UA.DA.Access' := '1'}
rActDCPower : REAL;
// Current AC power (W)
{attribute 'OPC.UA.DA' := '1'}
{attribute 'OPC.UA.DA.Access' := '1'}
rActACPower : REAL;
// Current AC frequency (Hz)
{attribute 'OPC.UA.DA' := '1'}
{attribute 'OPC.UA.DA.Access' := '1'}
rActACFreq : REAL;
// Current AC apparent power (VA)
{attribute 'OPC.UA.DA' := '1'}
{attribute 'OPC.UA.DA.Access' := '1'}
rActApparentPower : REAL;
// Current AC reactive power (VAr)
{attribute 'OPC.UA.DA' := '1'}
{attribute 'OPC.UA.DA.Access' := '1'}
rActReactivePower : REAL;
// Current AC power factor
{attribute 'OPC.UA.DA' := '1'}
{attribute 'OPC.UA.DA.Access' := '1'}
rActPowerFactor : REAL;
// Current inverter status
{attribute 'OPC.UA.DA' := '1'}
{attribute 'OPC.UA.DA.Access' := '1'}
uiStatus : UINT;
END_STRUCT
END_TYPE
]]></Declaration>