Finished first implementation of modbus error registers
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<TcPlcObject Version="1.1.0.1" ProductVersion="3.1.4026.8">
|
||||
<TcPlcObject Version="1.1.0.1" ProductVersion="3.1.4026.12">
|
||||
<POU Name="FB_PowerSupplySunspec" Id="{a826dd09-442c-45c5-8ae3-9b71f293003c}" SpecialFunc="None">
|
||||
<Declaration><![CDATA[FUNCTION_BLOCK FB_PowerSupplySunspec
|
||||
VAR_INPUT
|
||||
@@ -27,6 +27,9 @@ VAR
|
||||
// Current state
|
||||
_iState : INT := 0;
|
||||
|
||||
// Internal power command
|
||||
_rPowerInternal : REAL;
|
||||
|
||||
// FB for reading Modbus holding registers
|
||||
_fbReadRegister : FB_MBReadRegs;
|
||||
|
||||
@@ -67,9 +70,6 @@ VAR
|
||||
// Current state of the inverters internal statemachine
|
||||
_uiInverterState : UINT;
|
||||
|
||||
// Last written power to the inverter
|
||||
_rOldPower : REAL;
|
||||
|
||||
// Value to enable or dissable the Power limiting feature
|
||||
_uiMaxLimEn : UINT;
|
||||
|
||||
@@ -88,9 +88,15 @@ VAR
|
||||
// Time for polling for current dc values and check for inverter error
|
||||
_timPollingDelay : TIME := T#500MS;
|
||||
|
||||
// Time for setting the current power
|
||||
_timSetPowerDelay : TIME := T#250MS;
|
||||
|
||||
// Timer for polling of current values
|
||||
_tonPollingTimer : TON;
|
||||
|
||||
// Timer for setting the inverter power
|
||||
_tonSetPowerTimer : TON;
|
||||
|
||||
// Current DC values (DCA, DCA_SF, DCV, DCV_SF, DCW, DCW_SF) in word array for efficient modbus reading
|
||||
_awCurrentDCValues : ARRAY[0..5] OF WORD;
|
||||
|
||||
@@ -227,6 +233,7 @@ CASE _iState OF
|
||||
// If enable and INTLK Ok
|
||||
IF xEnable THEN
|
||||
_iState := 10;
|
||||
_rPowerInternal := 0.0;
|
||||
_tonPollingTimer(IN := FALSE, PT := _timPollingDelay);
|
||||
ELSE
|
||||
_tonPollingTimer(IN := TRUE, PT := _timPollingDelay);
|
||||
@@ -598,7 +605,7 @@ CASE _iState OF
|
||||
_rWMax := LREAL_TO_REAL(_uiWMax * EXPT(10,_iWMaxSF));
|
||||
|
||||
// Calculate power to write to register
|
||||
_iWMaxLimPct := LREAL_TO_INT((rPower*100)/(_rWMax * EXPT(10,_iWMaxLimPctSF)));
|
||||
_iWMaxLimPct := LREAL_TO_INT((_rPowerInternal*100)/(_rWMax * EXPT(10,_iWMaxLimPctSF)));
|
||||
ELSE
|
||||
xError := TRUE;
|
||||
// Goto error state
|
||||
@@ -629,7 +636,6 @@ CASE _iState OF
|
||||
// And there is no error, then continue
|
||||
IF NOT _fbWriteRegister.bError THEN
|
||||
_iState := 50;
|
||||
_rOldPower := rPower;
|
||||
_uiMaxLimEn := 1;
|
||||
_uiLastSetPowerLimitErrorCounter := _uiSetPowerLimitErrorCounter;
|
||||
_uiSetPowerLimitErrorCounter := 0;
|
||||
@@ -734,8 +740,8 @@ CASE _iState OF
|
||||
IF NOT _fbWriteRegister.bBusy THEN
|
||||
// And there is no error, then continue
|
||||
IF NOT _fbWriteRegister.bError THEN
|
||||
_iState := 51;
|
||||
_uiPCSSetOperation := 4;
|
||||
_iState := 60; // 51
|
||||
_uiPCSSetOperation := 1; // 4
|
||||
ELSE
|
||||
xError := TRUE;
|
||||
// Goto error state
|
||||
@@ -764,10 +770,11 @@ CASE _iState OF
|
||||
// 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;
|
||||
IF (NOT _fbWriteRegister.bError) THEN
|
||||
//_uiPCSSetOperation := 1;
|
||||
_iState := 60;
|
||||
ELSE
|
||||
_uiPCSSetOperation := 1;
|
||||
// Goto error state
|
||||
_iState := 1000;
|
||||
END_IF
|
||||
@@ -806,22 +813,28 @@ CASE _iState OF
|
||||
|
||||
65: // Wait for polling timer
|
||||
_tonPollingTimer(IN := TRUE, PT := _timPollingDelay);
|
||||
_tonSetPowerTimer(IN := TRUE, PT := _timSetPowerDelay);
|
||||
IF _tonPollingTimer.Q THEN
|
||||
_tonPollingTimer(IN := FALSE);
|
||||
_iState := 70;
|
||||
ELSIF (ABS(rPower - _rOldPower) > 0.1) THEN
|
||||
//_tonPollingTimer(IN := FALSE);
|
||||
ELSIF (ABS(rPower - _rPowerInternal) > 0.1) AND _tonSetPowerTimer.Q AND xEnable THEN
|
||||
_tonSetPowerTimer(IN := FALSE);
|
||||
_rPowerInternal := rPower;
|
||||
|
||||
// Calculate power to write to register
|
||||
_iWMaxLimPct := LREAL_TO_INT((_rPowerInternal*100)/(_rWMax * EXPT(10,_iWMaxLimPctSF)));
|
||||
|
||||
// If power has been changed, goto set power limit mode
|
||||
_iState := 40;
|
||||
// Calculate power to write to register
|
||||
_iWMaxLimPct := LREAL_TO_INT((rPower*100)/(_rWMax * EXPT(10,_iWMaxLimPctSF)));
|
||||
END_IF
|
||||
|
||||
// check if inverter should shut down
|
||||
IF NOT xEnable THEN
|
||||
IF (NOT xEnable) THEN
|
||||
_uiPCSSetOperation := 3;
|
||||
_rPowerInternal := 0.0;
|
||||
_iWMaxLimPct := 0;
|
||||
// Goto shutdown sequence
|
||||
_iState := 200;
|
||||
_iState := 200;
|
||||
END_IF
|
||||
|
||||
|
||||
@@ -1024,7 +1037,8 @@ CASE _iState OF
|
||||
_xInverterHBCounterIncremented := FALSE;
|
||||
END_IF
|
||||
|
||||
_iState := 65;
|
||||
// _iState := 65;
|
||||
_iState := 93;
|
||||
ELSE
|
||||
xError := TRUE;
|
||||
// Goto error state
|
||||
@@ -1034,8 +1048,75 @@ CASE _iState OF
|
||||
_fbReadRegister(bExecute := FALSE);
|
||||
END_IF
|
||||
|
||||
93: // Send current power demand
|
||||
_iErrorInState := _iState;
|
||||
_fbWriteRegister(
|
||||
sIPAddr:= sInverterIPAddr,
|
||||
nTCPPort:= 502,
|
||||
nUnitID:= 16#FF, // 16#FF for Modbus TCP
|
||||
nQuantity:= 1,
|
||||
nMBAddr:= W_MAX_LIM_PCT_REGISTER,
|
||||
cbLength:= SIZEOF(_iWMaxLimPct),
|
||||
pSrcAddr:= ADR(_iWMaxLimPct),
|
||||
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
|
||||
_iState := 65;
|
||||
_uiMaxLimEn := 1;
|
||||
_uiLastSetPowerLimitErrorCounter := _uiSetPowerLimitErrorCounter;
|
||||
_uiSetPowerLimitErrorCounter := 0;
|
||||
// Calculate reactive power setting
|
||||
//_iMaxPowerVar := LREAL_TO_INT((rReactivePower*100)/(_iMaxPowerVar * EXPT(10,_iVarPctSF)));
|
||||
ELSE
|
||||
_uiSetPowerLimitErrorCounter := _uiSetPowerLimitErrorCounter + 1;
|
||||
IF _uiSetPowerLimitErrorCounter > 5 THEN
|
||||
// Goto error state
|
||||
_iState := 1000;
|
||||
ELSE
|
||||
_iState := 41;
|
||||
END_IF
|
||||
END_IF
|
||||
_fbWriteRegister(bExecute := FALSE);
|
||||
END_IF
|
||||
|
||||
200: // Shutdown sequence
|
||||
|
||||
200: // Shutdown send zero power command
|
||||
_iErrorInState := _iState;
|
||||
_fbWriteRegister(
|
||||
sIPAddr:= sInverterIPAddr,
|
||||
nTCPPort:= 502,
|
||||
nUnitID:= 16#FF, // 16#FF for Modbus TCP
|
||||
nQuantity:= 1,
|
||||
nMBAddr:= W_MAX_LIM_PCT_REGISTER,
|
||||
cbLength:= SIZEOF(_iWMaxLimPct),
|
||||
pSrcAddr:= ADR(_iWMaxLimPct),
|
||||
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
|
||||
_iState := 201;
|
||||
_uiPCSSetOperation := 3;
|
||||
ELSE
|
||||
// Goto error state
|
||||
_iState := 1000;
|
||||
END_IF
|
||||
_fbWriteRegister(bExecute := FALSE);
|
||||
END_IF
|
||||
|
||||
201: // Shutdown sequence
|
||||
_iErrorInState := _iState;
|
||||
_fbWriteRegister(
|
||||
sIPAddr:= sInverterIPAddr,
|
||||
|
||||
Reference in New Issue
Block a user