changes during start of safety check

- Refactoring of string fb
- Added pump safety interlocks for pressure segment inlet too low and too high
This commit is contained in:
Matthias Heisig
2025-06-02 19:51:57 +02:00
parent ac0a8d160b
commit 2f9f4df261
10 changed files with 636 additions and 514 deletions

View File

@@ -35,6 +35,9 @@ VAR
// FB for writing Modbus holding registers
_fbWriteRegister : FB_MBWriteRegs;
// FB for writing Modbus holding registers for inverter heartbeat
_fbWriteHeartbeatRegister : FB_MBWriteRegs;
// Timer for checking if the inverter started in a reasonable amount of time
//_tonInverterStartup : TON;
@@ -228,6 +231,24 @@ _tonHearbeatIncTimer(IN := TRUE);
IF _tonHearbeatIncTimer.Q THEN
_tonHearbeatIncTimer(IN := FALSE);
_uiPLCToInverterCounter := _uiPLCToInverterCounter + 1;
_fbWriteHeartbeatRegister.bExecute := TRUE;
END_IF
_fbWriteHeartbeatRegister(
sIPAddr:= sInverterIPAddr,
nTCPPort:= 502,
nUnitID:= 16#FF, // 16#FF for Modbus TCP
nQuantity:= 1,
nMBAddr:= CONTROLLER_HB,
cbLength:= SIZEOF(_uiPLCToInverterCounter),
pSrcAddr:= ADR(_uiPLCToInverterCounter),
tTimeout:= T#5S,
bBusy=> ,
bError=> ,
nErrId=> );
// If writing modbus register is done
IF NOT _fbWriteHeartbeatRegister.bBusy THEN
// And there is no error, then continue
_fbWriteHeartbeatRegister(bExecute := FALSE);
END_IF
// State machine
@@ -277,8 +298,10 @@ CASE _iState OF
2: // IF inverter is not in STANDYB(8) STATE, send command to shutdown inverter
IF (_uiInverterState = 8) OR (_uiInverterState = 1) OR (_uiInverterState = 7) THEN
IF (_uiInverterState = 8) OR (_uiInverterState = 1) THEN
_iState := 3;
ELSIF _uiInverterState = 7 THEN
_iState := 990;
ELSE
_uiPCSSetOperation := 3;
_iState := 200;
@@ -339,7 +362,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 := 5;
_iState := 6;
stCurrentValues.rActACCurrent := LREAL_TO_REAL(WORD_TO_INT(_awCurrentACValues[0]) * EXPT(10,WORD_TO_INT(_awCurrentACValues[4])));
stCurrentValues.rActtACPhaseACurrent := LREAL_TO_REAL(WORD_TO_INT(_awCurrentACValues[1]) * EXPT(10,WORD_TO_INT(_awCurrentACValues[4])));
stCurrentValues.rActtACPhaseBCurrent := LREAL_TO_REAL(WORD_TO_INT(_awCurrentACValues[2]) * EXPT(10,WORD_TO_INT(_awCurrentACValues[4])));
@@ -356,36 +379,6 @@ CASE _iState OF
END_IF
_fbReadRegister(bExecute := FALSE);
END_IF
5: // Send heartbeat signal
_fbWriteRegister(
sIPAddr:= sInverterIPAddr,
nTCPPort:= 502,
nUnitID:= 16#FF, // 16#FF for Modbus TCP
nQuantity:= 1,
nMBAddr:= CONTROLLER_HB,
cbLength:= SIZEOF(_uiPLCToInverterCounter),
pSrcAddr:= ADR(_uiPLCToInverterCounter),
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 := 6;
ELSE
xError := TRUE;
_iErrorInState := _iState;
// Goto error state
_iState := 1000;
END_IF
_fbWriteRegister(bExecute := FALSE);
END_IF
6: // Check heartbeat signal
@@ -828,13 +821,19 @@ CASE _iState OF
IF _tonPollingTimer.Q THEN
_tonPollingTimer(IN := FALSE);
_iState := 70;
ELSIF (ABS(rPower - _rPowerInternal) > 0.1) AND _tonSetPowerTimer.Q AND xEnable THEN
ELSIF _tonSetPowerTimer.Q AND xEnable THEN // (ABS(rPower - _rPowerInternal) > 0.1) AND
_tonSetPowerTimer(IN := FALSE);
_rPowerInternal := rPower;
// Add power when derating is active
IF (stCurrentValues.rActDCVoltage > 900) AND (rPower < 0) THEN
_rPowerInternal := rPower - ((stCurrentValues.rActDCVoltage - 900.0) * 35.0);
END_IF
// 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;
END_IF
@@ -1224,6 +1223,7 @@ CASE _iState OF
1000: // Write error state to log
ADSLOGDINT(msgCtrlMask:= ADSLOG_MSGTYPE_ERROR, msgFmtStr:= 'Fehler im state: %s', dintArg:= INT_TO_DINT(_iErrorInState));
xActive := FALSE;
_iState := 1001;
1001: // Error state, wait for reset