Linked all tank sensors in media cabinet

- Additional fixes for the hmi
This commit is contained in:
2026-03-10 18:03:28 +01:00
parent 218d815380
commit f4562af86f
24 changed files with 1859 additions and 288 deletions

View File

@@ -17,6 +17,10 @@ VAR
_fbCoolplate : FB_Coolplate;
_fbHVTesterHot : FB_HVTester;
_fbHVTesterCold : FB_HVTester;
_fbMediaCabinet : FB_MediaCabinet;
_fbModbusMaster : FB_ModbusMaster;
_fbFlowSensor : FB_Levi_LFC6IO;
//_fbInput : FB_Input;
//_fbNOK : FB_NOK;
//_fbTrayFeederOutput : FB_TrayFeeder(sIPAddr := '192.168.1.11', udiPort := 5000);
@@ -25,6 +29,7 @@ VAR
// =======================
// DEBUG AND TESTING STUFF
// =======================
_xReadFullScale : BOOL;
_xReleaseAlarms : BOOL;
_stRobotCmd : ST_PMLc;
@@ -109,6 +114,12 @@ _fbCoolplate(stHMIInterface := GVL_SCADA.stMachine.stCoolplate);
_fbAligner(stCommand:= , stStatus=> , stAdmin=> , xConfirmAlarms:= GVL_SCADA.stMachine.stConfirmAlarmsBtn.xRequest, stHMIInterface := GVL_SCADA.stMachine.stAligner);
_fbMediaCabinet(
xReleaseManualMode := TRUE,
xReleaseErrors := _xReleaseAlarms,
xConfirmAlarms := GVL_SCADA.stMachine.stConfirmAlarmsBtn.xRequest,
stHMIInterface := GVL_SCADA.stMachine.stMediaCabinet);
// Call safety program
PRG_Safety(
@@ -117,6 +128,23 @@ PRG_Safety(
// Handle robot cmds
M_HandleRobotCmd();
// DEBUG
//_fbModbusMaster();
// IF _xReadFullScale THEN
// _xReadFullScale := FALSE;
//
// _fbFlowSensor(
// byBaseAddr:= ,
// xReleaseAlarms:= ,
// xConfirmAlarms:= ,
// fbMBMaster:= ,
// rCurrFlowrate=> ,
// xBusy=> ,
// xDone=> ,
// xError=> );
// END_IF
// Main state machine
CASE _iState OF

View File

@@ -22,6 +22,10 @@ VAR
xLEDMachineOn AT %Q* : BOOL;
xLEDMachineOff AT %Q* : BOOL;
xLockMediaDoor1 AT %Q* : BOOL := TRUE;
xLockMediaDoor2 AT %Q* : BOOL := TRUE;
xLockMediaDoor3 AT %Q* : BOOL := TRUE;
_rtDoorUnlock : R_TRIG;
_tofErrorAck : TOF;

View File

@@ -39,6 +39,8 @@ STRUCT
stHVTesterCold : ST_HMI_HVTester;
stTrayFeederOut : ST_HMI_TrayFeeder;
stNOK : ST_HMI_NOK;
stMediaCabinet : ST_HMI_MediaCabinet;
END_STRUCT
END_TYPE
]]></Declaration>

View File

@@ -90,7 +90,7 @@ _fbValveDoor(
xAutomaticOpen:= xOpenDoor,
xReleaseErrors:= xReleaseAlarms,
stValveConfig:= _stValveDoorCfg,
xReleaseManualMode:= FALSE,
xReleaseManualMode:= xReleaseManualMode,
xConfirmAlarms:= xConfirmAlarms,
stHMIInterface:= stHMIInterface.stDoorValve);

View File

@@ -90,6 +90,8 @@ _fbPWMOut(
xOutput=> xEnableHotplate);
SUPER^(stPackMLHMIInterface := stHMIInterface.stStationCmds);
M_HandleHMIOutput();
]]></ST>
</Implementation>
<Action Name="A_HandleHMIInput" Id="{d22cec08-4a88-4001-b04b-e7a9775ff9a8}">
@@ -101,6 +103,20 @@ END_IF
IF stHMIInterface.stSetpoint.rValue < 0.0 THEN
stHMIInterface.stSetpoint.rValue := 0.0;
END_IF
IF stHMIInterface.stEnableBtn.xRequest THEN
stHMIInterface.stEnableBtn.xRequest := FALSE;
IF stHMIInterface.stEnableBtn.xRelease THEN
_xEnable := TRUE;
END_IF
END_IF
IF stHMIInterface.stDisableBtn.xRequest THEN
stHMIInterface.stDisableBtn.xRequest := FALSE;
IF stHMIInterface.stDisableBtn.xRelease THEN
_xEnable := FALSE;
END_IF
END_IF]]></ST>
</Implementation>
</Action>
@@ -128,5 +144,23 @@ END_VAR
<ST><![CDATA[]]></ST>
</Implementation>
</Method>
<Method Name="M_HandleHMIOutput" Id="{64dfce9b-801c-40e9-9327-9ba9e736e727}">
<Declaration><![CDATA[METHOD PRIVATE M_HandleHMIOutput
VAR_INPUT
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[stHMIInterface.stEnableBtn.xRelease := (NOT _xEnable);
IF _xEnable THEN
stHMIInterface.stEnableBtn.eFeedback := 1;
stHMIInterface.stDisableBtn.eFeedback := 0;
ELSE
stHMIInterface.stDisableBtn.eFeedback := 1;
stHMIInterface.stEnableBtn.eFeedback := 0;
END_IF
stHMIInterface.stDisableBtn.xRelease := _xEnable;]]></ST>
</Implementation>
</Method>
</POU>
</TcPlcObject>

View File

@@ -460,7 +460,7 @@ END_VAR]]></Declaration>
0:
_byGripperSideNrCalc := M_CalcGripperNr(_stJobParams.byGripperNumber);
IF (_stJobParams.byGripperNumber > 3) // Wrong gripper number
IF (_stJobParams.byGripperNumber > 4) // Wrong gripper number
//OR (_stJobParams.byChuckNumber < 1) OR (_stJobParams.byChuckNumber > 6) // Wrong chuck number
OR (_byGripperSideNrCalc < 1) OR (_byGripperSideNrCalc > 6) // Wrong gripper side
THEN
@@ -470,9 +470,9 @@ END_VAR]]></Declaration>
END_IF
// BLOCKIERE GREIFER TAUSCH, DA AKTUELL KABEL DEFEKT !!!!!
IF _stJobParams.eJob = E_KukaRobot_JobNumberRobot.CHANGE_GRIPPER THEN
_eCmd := E_PackMLCmd.ABORT;;
END_IF
// IF _stJobParams.eJob = E_KukaRobot_JobNumberRobot.CHANGE_GRIPPER THEN
// _eCmd := E_PackMLCmd.ABORT;;
// END_IF
// Transfer job data to robot
10:
@@ -496,16 +496,16 @@ END_VAR]]></Declaration>
END_IF
// Position on hotplate
abyToolsAndPositions[2] := stJobParams.byPlaceOnHotplate;
abyToolsAndPositions[2] := _stJobParams.byPlaceOnHotplate;
// Position on coolplate
abyToolsAndPositions[3] := stJobParams.byPlaceOnCoolPlate;
abyToolsAndPositions[3] := _stJobParams.byPlaceOnCoolPlate;
// Gripper number
abyToolsAndPositions[0] := stJobParams.byGripperNumber;
abyToolsAndPositions[0] := _stJobParams.byGripperNumber;
// Chuck for etcher to load
abyToolsAndPositions[1] := stJobParams.byChuckNumber;
abyToolsAndPositions[1] := _stJobParams.byChuckNumber;
// Safety reset timout fb
_tonTimeout(IN := FALSE);
@@ -516,10 +516,10 @@ END_VAR]]></Declaration>
15:
_tonTimeout(IN := TRUE, PT := T#5S);
IF abyMirrorToolsAndPositions[0] = stJobParams.byGripperNumber
AND abyMirrorToolsAndPositions[1] = stJobParams.byChuckNumber
AND abyMirrorToolsAndPositions[2] = stJobParams.byPlaceOnHotplate
AND abyMirrorToolsAndPositions[3] = stJobParams.byPlaceOnCoolPlate
IF abyMirrorToolsAndPositions[0] = _stJobParams.byGripperNumber
AND abyMirrorToolsAndPositions[1] = _stJobParams.byChuckNumber
AND abyMirrorToolsAndPositions[2] = _stJobParams.byPlaceOnHotplate
AND abyMirrorToolsAndPositions[3] = _stJobParams.byPlaceOnCoolPlate
THEN
_tonTimeout(IN := FALSE);
_iSSM := 20;

View File

@@ -0,0 +1,36 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1">
<DUT Name="ST_HMI_MediaCabinet" Id="{531277fd-be49-4a36-8089-70f1b95b2250}">
<Declaration><![CDATA[TYPE ST_HMI_MediaCabinet :
STRUCT
// (1) Acetic acid 99%
stTankAceticAcidHigh : ST_HMI_Tank;
// (2) Sulfuric acid
stTankSulfuricAcid : ST_HMI_Tank;
// (3) Nitric acid 65% mixing
stTankNitricAcid : ST_HMI_Tank;
// (4) Acetic acid 10%
stTankAceticAcidLow : ST_HMI_Tank;
// (5) Hydrofluoric acid 40%
stTankHydrofluoricAcid : ST_HMI_Tank;
// (6) Sulfuric acid mixing
stTankSulfuricAcidMixing : ST_HMI_Tank;
// (7) Hydrofluoric acid 40% for mixing
stTankHydrofluoricAcidMixing : ST_HMI_Tank;
// (8) SEF
stTankSEF : ST_HMI_Tank;
// (9) Filmetch
stTankFilmetch : ST_HMI_Tank;
END_STRUCT
END_TYPE
]]></Declaration>
</DUT>
</TcPlcObject>

View File

@@ -3,10 +3,14 @@
<DUT Name="ST_HMI_Tank" Id="{65129234-1803-4176-b0ff-e2e1212dc4a3}">
<Declaration><![CDATA[TYPE ST_HMI_Tank :
STRUCT
stWaterValve : ST_HMI_VALVE_DATA;
stFillingValve : ST_HMI_VALVE_DATA;
stDrainValve : ST_HMI_VALVE_DATA;
stPumpValve : ST_HMI_VALVE_DATA;
stEmptyButton : ST_HMI_CONTROL_BUTTON;
stFillButton : ST_HMI_CONTROL_BUTTON;
xOverfull : BOOL;
xFull : BOOL;
xEmpty : BOOL;

View File

@@ -1,164 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1">
<POU Name="FB_Levi_Flowsensor" Id="{650b4e84-15bc-4cc6-bda5-d5ab333779ee}" SpecialFunc="None">
<Declaration><![CDATA[FUNCTION_BLOCK FB_Levi_LFC6IO
VAR_INPUT
// Base station address
byBaseAddr : BYTE;
xReleaseAlarms : BOOL;
xConfirmAlarms : BOOL;
END_VAR
VAR_IN_OUT
// Modbus master comm fb
fbMBMaster : ModbusRtuMasterV2_KL6x22B;
END_VAR
VAR_OUTPUT
// Current flowrate in ml/min
rCurrFlowrate : ARRAY[0..5] OF REAL;
xBusy : BOOL;
xDone : BOOL;
xError : BOOL;
END_VAR
VAR
// Full scale value of all channels in ml/min
_dwFullScale : DWORD;
// Channel data
_astChannelData : ARRAY[0..5] OF ST_Levi_ChData;
// Temporary data storage for writing settings
_awTempData : ARRAY[0..1] OF WORD;
// State machine state
_iState : INT;
// Internal commands
_eCmd : (NONE, SET_FULL_SCALE, );
END_VAR
VAR CONSTANT
REG_SET_MODE : WORD := 0;
REG_FULL_SCALE : WORD := 2;
REG_CH_DATA : WORD := 0;
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[CASE _iState OF
// Wait for Modbus master to be ready
0:
IF (NOT fbMBMaster.BUSY)THEN
// Get full scale value for later flow calculation
fbMBMaster.UnitID := byBaseAddr;
fbMBMaster.MBAddr := REG_FULL_SCALE;
fbMBMaster.Quantity := 2;
fbMBMaster.cbLength := SIZEOF(_dwFullScale);
fbMBMaster.pMemoryAddr := ADR(_dwFullScale);
_iState := 10;
END_IF
// Wait for reading done
10:
fbMBMaster.ReadRegs();
IF (NOT fbMBMaster.BUSY) THEN
_iState := 20;
END_IF
IF fbMBMaster.Error THEN
_iState := 900;
END_IF
// Poll channel data
20:
IF THEN
fbMBMaster.UnitID := byBaseAddr;
fbMBMaster.MBAddr := REG_CH_DATA;
fbMBMaster.Quantity := 24;
fbMBMaster.cbLength := SIZEOF(_astChannelData);
fbMBMaster.pMemoryAddr := ADR(_astChannelData);
// Call once to set MB Master to busy
fbMBMaster.ReadInputRegs();
_iState := 21;
ELSIF (_eCmd <> NONE) AND (NOT fbMBMaster.BUSY) THEN
_iState := 30;
END_IF
// Wait for response
21:
fbMBMaster.ReadInputRegs();
IF (NOT fbMBMaster.BUSY) THEN
// Calculate output flowrates
M_CalcOutputData();
_iState := 20;
END_IF
IF fbMBMaster.Error THEN
_iState := 900;
END_IF
// Command handling -> Set mode
30:
// Set bit 1 to 1 for Set Mode
_awTempData[0] := 2#10;
fbMBMaster.UnitID := byBaseAddr;
fbMBMaster.MBAddr := REG_SET_MODE;
fbMBMaster.Quantity := 1;
fbMBMaster.cbLength := 2;
fbMBMaster.pMemoryAddr := ADR(_awTempData[0]);
// Error state
900:
IF xConfirmAlarms THEN
xError := FALSE;
_iState := 0;
END_IF
END_CASE]]></ST>
</Implementation>
<Method Name="M_CalcOutputData" Id="{5b932e1a-1437-4032-adb5-2eae4b98574c}">
<Declaration><![CDATA[METHOD PRIVATE M_CalcOutputData
VAR
i : int;
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[FOR i := 0 TO 5 DO
// Current flowrate from channel data is in % of full scale (-30.000 ~ 30.000 => (-300 ~ +300) %
// _Full scale is in l/min but scaling is as followed: 10 ~ 500000 => (0.010 ~ 500) l/min => (10 ~ 500.000) ml/min
// Result is in ml/min
rCurrFlowrate[i] := (SINT_TO_REAL(_astChannelData[i].siCurrFlow) * DWORD_TO_REAL(_dwFullScale)) / 10_000;
END_FOR
]]></ST>
</Implementation>
</Method>
<Method Name="M_ReadSensorData" Id="{2cd73435-5e66-4519-8bdc-106eb3093539}">
<Declaration><![CDATA[METHOD M_ReadSensorData : BOOL
VAR_INPUT
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[IF xBusy THEN
M_ReadSensorData := FALSE;
RETURN;
END_IF
]]></ST>
</Implementation>
</Method>
<Method Name="M_SetFullScale" Id="{ee32b999-71fe-4e16-ab8c-09e92e1f41ef}">
<Declaration><![CDATA[METHOD M_SetFullScale : BOOL
VAR_INPUT
// Full scale in ml/min
siFullScale : SINT;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[]]></ST>
</Implementation>
</Method>
</POU>
</TcPlcObject>

View File

@@ -0,0 +1,248 @@
<?xml version="1.0" encoding="utf-8"?>
<TcPlcObject Version="1.1.0.1">
<POU Name="FB_Levi_LFC6IO" Id="{650b4e84-15bc-4cc6-bda5-d5ab333779ee}" SpecialFunc="None">
<Declaration><![CDATA[FUNCTION_BLOCK FB_Levi_LFC6IO
VAR_INPUT
// Base station address
byBaseAddr : BYTE;
xReleaseAlarms : BOOL;
xConfirmAlarms : BOOL;
END_VAR
VAR_IN_OUT
// Modbus master comm fb
fbMBMaster : FB_ModbusMaster;
END_VAR
VAR_OUTPUT
// Current flowrate in ml/min
rCurrFlowrate : ARRAY[0..5] OF REAL;
xBusy : BOOL;
xDone : BOOL;
xError : BOOL;
END_VAR
VAR
// Full scale value of all channels in ml/min
_dwFullScale : DWORD := 4000;
// Channel data
_astChannelData : ARRAY[0..5] OF ST_Levi_ChData;
// Temporary data storage for writing settings
_awTempData : ARRAY[0..1] OF WORD;
// Start waiting for response
_xExecute : BOOL;
_xReady : BOOL;
_xError : BOOL;
// Request data
_stModbusData : ST_Modbus_Req;
_xMBDone : BOOL;
_xMBError : BOOL;
// State machine state
_iState : INT;
END_VAR
VAR CONSTANT
REG_SET_MODE : WORD := 0;
REG_FULL_SCALE : WORD := 2;
REG_CH_DATA : WORD := 0;
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[CASE _iState OF
// Idle
0:
IF _xExecute THEN
_xExecute := FALSE;
_iState := 10;
END_IF
// Wait for reading done
10:
IF _xMBDone THEN
_xReady := TRUE;
xBusy := FALSE;
xDone := TRUE;
_iState := 0;
END_IF
IF _xMBError THEN
_iState := 900;
END_IF
// Error state
900:
xDone := FALSE;
xBusy := FALSE;
xError := TRUE;
_iState := 901;
// Wait for reset
901:
IF xConfirmAlarms THEN
_xReady := TRUE;
xError := FALSE;
_iState := 0;
END_IF
END_CASE
// Calculate output data
M_CalcOutputData();]]></ST>
</Implementation>
<Method Name="M_CalcOutputData" Id="{5b932e1a-1437-4032-adb5-2eae4b98574c}">
<Declaration><![CDATA[METHOD PRIVATE M_CalcOutputData
VAR
i : int;
END_VAR]]></Declaration>
<Implementation>
<ST><![CDATA[FOR i := 0 TO 5 DO
// Current flowrate from channel data is in % of full scale (-30.000 ~ 30.000 => (-300 ~ +300) %
// _Full scale is in l/min but scaling is as followed: 10 ~ 500000 => (0.010 ~ 500) l/min => (10 ~ 500.000) ml/min
// Result is in ml/min
rCurrFlowrate[i] := (SINT_TO_REAL(_astChannelData[i].siCurrFlow) * DWORD_TO_REAL(_dwFullScale)) / 10_000;
END_FOR
]]></ST>
</Implementation>
</Method>
<Method Name="M_DisableSetMode" Id="{f89e844d-3a6f-40d7-9da3-bae450f616ea}">
<Declaration><![CDATA[METHOD M_DisableSetMode : BOOL
VAR_INPUT
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[IF _xReady THEN
M_StartExec();
// Prepare value to write
_awTempData[0] := 0;
_awTempData[1] := 0;
_stModbusData.bySlaveAddr := byBaseAddr;
_stModbusData.eCmd := E_Modbus_Cmd.WRITE_HOLDING;
_stModbusData.pvData := ADR(_awTempData);
_stModbusData.pxDone := ADR(_xMBDone);
_stModbusData.pxError := ADR(_xMBError);
_stModbusData.wDataSize := SIZEOF(_awTempData[0]);
_stModbusData.wQuantity := 1;
_stModbusData.wStartAddr := REG_SET_MODE;
fbMBMaster.M_Enqueue(stReq := _stModbusData);
END_IF]]></ST>
</Implementation>
</Method>
<Method Name="M_EnableSetMode" Id="{de18b8f5-be31-468c-a5e8-49fab953c64b}">
<Declaration><![CDATA[METHOD M_EnableSetMode : BOOL
VAR_INPUT
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[IF _xReady THEN
M_StartExec();
// Prepare value to write
_awTempData[0] := 2#10;
_awTempData[1] := 0;
_stModbusData.bySlaveAddr := byBaseAddr;
_stModbusData.eCmd := E_Modbus_Cmd.WRITE_HOLDING;
_stModbusData.pvData := ADR(_awTempData);
_stModbusData.pxDone := ADR(_xMBDone);
_stModbusData.pxError := ADR(_xMBError);
_stModbusData.wDataSize := SIZEOF(_awTempData[0]);
_stModbusData.wQuantity := 1;
_stModbusData.wStartAddr := REG_SET_MODE;
fbMBMaster.M_Enqueue(stReq := _stModbusData);
END_IF]]></ST>
</Implementation>
</Method>
<Method Name="M_PollSensorData" Id="{95195e13-015b-491e-bb17-770ecd95cc2e}">
<Declaration><![CDATA[METHOD M_PollSensorData : BOOL;
VAR_INPUT
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[IF _xReady THEN
M_StartExec();
_stModbusData.bySlaveAddr := byBaseAddr;
_stModbusData.eCmd := E_Modbus_Cmd.READ_INPUTS;
_stModbusData.pvData := ADR(_astChannelData);
_stModbusData.pxDone := ADR(_xMBDone);
_stModbusData.pxError := ADR(_xMBError);
_stModbusData.wDataSize := SIZEOF(_astChannelData);
_stModbusData.wQuantity := 24;
_stModbusData.wStartAddr := REG_CH_DATA;
fbMBMaster.M_Enqueue(stReq := _stModbusData);
END_IF
]]></ST>
</Implementation>
</Method>
<Method Name="M_ReadFullScale" Id="{14c84036-88ce-4b20-9f11-8cae269c566f}">
<Declaration><![CDATA[METHOD M_ReadFullScale : BOOL
VAR_INPUT
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[IF _xReady THEN
M_StartExec();
_stModbusData.bySlaveAddr := byBaseAddr;
_stModbusData.eCmd := E_Modbus_Cmd.READ_HOLDING;
_stModbusData.pvData := ADR(_dwFullScale);
_stModbusData.pxDone := ADR(_xMBDone);
_stModbusData.pxError := ADR(_xMBError);
_stModbusData.wDataSize := SIZEOF(_dwFullScale);
_stModbusData.wQuantity := 2;
_stModbusData.wStartAddr := REG_FULL_SCALE;
fbMBMaster.M_Enqueue(stReq := _stModbusData);
END_IF]]></ST>
</Implementation>
</Method>
<Method Name="M_SetFullScale" Id="{ee32b999-71fe-4e16-ab8c-09e92e1f41ef}">
<Declaration><![CDATA[METHOD M_SetFullScale : BOOL
VAR_INPUT
// Full scale in ml/min
dwFullScale : DWORD;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[IF _xReady THEN
M_StartExec();
_dwFullScale := dwFullScale;
_stModbusData.bySlaveAddr := byBaseAddr;
_stModbusData.eCmd := E_Modbus_Cmd.WRITE_HOLDING;
_stModbusData.pvData := ADR(_dwFullScale);
_stModbusData.pxDone := ADR(_xMBDone);
_stModbusData.pxError := ADR(_xMBError);
_stModbusData.wDataSize := SIZEOF(_dwFullScale);
_stModbusData.wQuantity := 2;
_stModbusData.wStartAddr := REG_FULL_SCALE;
fbMBMaster.M_Enqueue(stReq := _stModbusData);
END_IF]]></ST>
</Implementation>
</Method>
<Method Name="M_StartExec" Id="{991a93fa-4cc2-4ad6-b2a3-8f9bf70f5fb5}">
<Declaration><![CDATA[METHOD PRIVATE M_StartExec
VAR_INPUT
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[xBusy := TRUE;
xDone := FALSE;
xError := FALSE;
_xReady := FALSE;
_xExecute := TRUE;]]></ST>
</Implementation>
</Method>
</POU>
</TcPlcObject>

View File

@@ -3,9 +3,15 @@
<POU Name="FB_MediaCabinet" Id="{9de34b64-23ba-4fef-b086-9297bbd06f24}" SpecialFunc="None">
<Declaration><![CDATA[FUNCTION_BLOCK FB_MediaCabinet
VAR_INPUT
xReleaseManualMode : BOOL;
xReleaseErrors : BOOL;
xConfirmAlarms : BOOL;
END_VAR
VAR_OUTPUT
END_VAR
VAR_IN_OUT
stHMIInterface : ST_HMI_MediaCabinet;
END_VAR
VAR
// (1) Acetic acid 99%
_fbTankAceticAcidHigh : FB_Tank;
@@ -35,12 +41,64 @@ VAR
_fbTankFilmetch : FB_Tank;
// Flowsensors
//_fbFlowSensors16 : FB_Levi_LFC6IO
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[]]></ST>
<ST><![CDATA[_fbTankAceticAcidHigh(
xReleaseErrors:= xReleaseErrors,
xReleaseManualMode:= xReleaseManualMode,
xConfirmAlarms:= xConfirmAlarms,
stHMIInterface:= stHMIInterface.stTankAceticAcidHigh);
_fbTankSulfuricAcid(
xReleaseErrors:= xReleaseErrors,
xReleaseManualMode:= xReleaseManualMode,
xConfirmAlarms:= xConfirmAlarms,
stHMIInterface:= stHMIInterface.stTankSulfuricAcid);
_fbTankNitricAcid(
xReleaseErrors:= xReleaseErrors,
xReleaseManualMode:= xReleaseManualMode,
xConfirmAlarms:= xConfirmAlarms,
stHMIInterface:= stHMIInterface.stTankNitricAcid);
_fbTankAceticAcidLow(
xReleaseErrors:= xReleaseErrors,
xReleaseManualMode:= xReleaseManualMode,
xConfirmAlarms:= xConfirmAlarms,
stHMIInterface:= stHMIInterface.stTankAceticAcidLow);
_fbTankHydrofluoricAcid(
xReleaseErrors:= xReleaseErrors,
xReleaseManualMode:= xReleaseManualMode,
xConfirmAlarms:= xConfirmAlarms,
stHMIInterface:= stHMIInterface.stTankHydrofluoricAcid);
_fbTankSulfuricAcidMixing(
xReleaseErrors:= xReleaseErrors,
xReleaseManualMode:= xReleaseManualMode,
xConfirmAlarms:= xConfirmAlarms,
stHMIInterface:= stHMIInterface.stTankSulfuricAcidMixing);
_fbTankHydrofluoricAcidMixing(
xReleaseErrors:= xReleaseErrors,
xReleaseManualMode:= xReleaseManualMode,
xConfirmAlarms:= xConfirmAlarms,
stHMIInterface:= stHMIInterface.stTankHydrofluoricAcidMixing);
_fbTankSEF(
xReleaseErrors:= xReleaseErrors,
xReleaseManualMode:= xReleaseManualMode,
xConfirmAlarms:= xConfirmAlarms,
stHMIInterface:= stHMIInterface.stTankSEF);
_fbTankFilmetch(
xReleaseErrors:= xReleaseErrors,
xReleaseManualMode:= xReleaseManualMode,
xConfirmAlarms:= xConfirmAlarms,
stHMIInterface:= stHMIInterface.stTankFilmetch);]]></ST>
</Implementation>
</POU>
</TcPlcObject>

View File

@@ -21,20 +21,31 @@ VAR
i_xFull AT %I* : BOOL;
i_xEmpty AT %I* : BOOL;
fbFillingValve : FB_Valve;
fbDrainValve : FB_Valve;
fbPumpValve : FB_Valve;
_fbWaterValve : FB_Valve('Water valve');
_fbFillingValve : FB_Valve('Filling valve');
_fbDrainValve : FB_Valve('Drain Valve');
_fbPumpValve : FB_Valve('Pump Valve');
_stValveConfig : ST_ValveConfig;
_wFillingValveSafetyIntlkUsed : T_INTERLOCK;
_wFillingValveSafetyIntlk : T_INTERLOCK;
_iState : INT;
_xFirstCycle : BOOL := TRUE;
END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[// Overfull is NC so true if ok
<ST><![CDATA[IF _xFirstCycle THEN
_xFirstCycle := FALSE;
stHMIInterface.stFillingValve.stInterlock.asSafetyINTLKName[0] := 'Tank overfull';
_wFillingValveSafetyIntlkUsed.0 := 1;
END_IF
// Overfull is NC so true if ok
_wFillingValveSafetyIntlk.0 := i_xOverfull;
fbFillingValve(
_fbFillingValve(
xReleaseErrors:= xReleaseErrors,
stValveConfig:= _stValveConfig,
xReleaseManualMode:= xReleaseManualMode,
@@ -42,20 +53,60 @@ fbFillingValve(
wSafetyINTLKUsed:= _wFillingValveSafetyIntlkUsed,
xConfirmAlarms:= xConfirmAlarms,
stHMIInterface:= stHMIInterface.stFillingValve);
_fbWaterValve(
xReleaseErrors:= xReleaseErrors,
stValveConfig:= _stValveConfig,
xReleaseManualMode:= xReleaseManualMode,
xConfirmAlarms:= xConfirmAlarms,
stHMIInterface:= stHMIInterface.stDrainValve);
fbDrainValve(
_fbDrainValve(
xReleaseErrors:= xReleaseErrors,
stValveConfig:= _stValveConfig,
xReleaseManualMode:= xReleaseManualMode,
xConfirmAlarms:= xConfirmAlarms,
stHMIInterface:= stHMIInterface.stDrainValve);
fbPumpValve(
_fbPumpValve(
xReleaseErrors:= xReleaseErrors,
stValveConfig:= _stValveConfig,
xReleaseManualMode:= xReleaseManualMode,
xConfirmAlarms:= xConfirmAlarms,
stHMIInterface:= stHMIInterface.stPumpValve);]]></ST>
stHMIInterface:= stHMIInterface.stPumpValve);
CASE _iState OF
// Idle
0:
// Start emptying tank
IF stHMIInterface.stEmptyButton.xRequest THEN
stHMIInterface.stEmptyButton.xRequest := FALSE;
_iState := 10;
END_IF
// Start filling tank with water
IF stHMIInterface.stFillButton.xRequest THEN
stHMIInterface.stFillButton.xRequest := FALSE;
_iState := 20;
END_IF
// Empty tank
10:
_fbDrainValve.xAutomaticOpen := TRUE;
IF (NOT i_xEmpty) THEN
_fbDrainValve.xAutomaticOpen := FALSE;
_iState := 0;
END_IF
// Fill tank with water
20:
IF xFull THEN
;
END_IF
END_CASE]]></ST>
</Implementation>
<Method Name="FB_Init" Id="{9c6d1842-9c2e-4437-b40f-941f77668ffe}">
<Declaration><![CDATA[//FB_Init is always available implicitly and it is used primarily for initialization.
@@ -70,10 +121,7 @@ END_VAR
]]></Declaration>
<Implementation>
<ST><![CDATA[_stValveConfig.xHasOpenFeedback := FALSE;
_stValveConfig.xHasClosedFeedback := FALSE;
stHMIInterface.stFillingValve.stInterlock.asSafetyINTLKName[0] := 'Tank overfull';
_wFillingValveSafetyIntlkUsed.0 := 1;]]></ST>
_stValveConfig.xHasClosedFeedback := FALSE;]]></ST>
</Implementation>
</Method>
<Method Name="M_HandleHMIOutput" Id="{8939e00b-3459-4b5e-a4b3-7b489eec260a}">

View File

@@ -114,7 +114,7 @@ IF _iHead = _iTail THEN
M_Dequeue := FALSE;
ELSE
// Get next entry
_stCurrReq := _astReqQueue;
_stCurrReq := _astReqQueue[_iHead];
_iHead := (_iHead + 1) MOD GVL_ModbusMaster.QUEUE_SIZE;
M_Dequeue := TRUE;
END_IF]]></ST>
@@ -140,7 +140,11 @@ ELSE
_astReqQueue[_iNextTail] := stReq;
_iTail := _iNextTail;
M_Enqueue := TRUE;
END_IF]]></ST>
END_IF
// Reset error and done
stReq.pxDone^ := FALSE;
stReq.pxError^ := FALSE;]]></ST>
</Implementation>
</Method>
</POU>

View File

@@ -182,6 +182,9 @@
<Compile Include="01_Stationen\Kuka_Robot\ST_KukaRobot_UnitFeedbacks.TcDUT">
<SubType>Code</SubType>
</Compile>
<Compile Include="01_Stationen\MediaStation\DUTs\ST_HMI_MediaCabinet.TcDUT">
<SubType>Code</SubType>
</Compile>
<Compile Include="01_Stationen\MediaStation\DUTs\ST_HMI_Tank.TcDUT">
<SubType>Code</SubType>
</Compile>
@@ -191,7 +194,7 @@
<Compile Include="01_Stationen\MediaStation\DUTs\ST_Levi_ChDStatus.TcDUT">
<SubType>Code</SubType>
</Compile>
<Compile Include="01_Stationen\MediaStation\FB_Levi_Flowsensor.TcPOU">
<Compile Include="01_Stationen\MediaStation\FB_Levi_LFC6IO.TcPOU">
<SubType>Code</SubType>
</Compile>
<Compile Include="01_Stationen\MediaStation\POUs\FB_MediaCabinet.TcPOU">

File diff suppressed because one or more lines are too long