DUTs ---- E_GasType ^^^^^^^^^ :: TYPE E_GasType : ( none := 0, Nitrogen, Argon ); END_TYPE Related: * `E_GasType`_ E_HomeState ^^^^^^^^^^^ :: TYPE E_HomeState : ( H_READY, H_INIT, H_RESET_LL, H_RESET_HL, H_ENABLE, H_MOVING, H_MOVING2, H_CHECK, H_RESET, H_SET_POS, H_ERROR, H_WRITE_LL, H_WRITE_HL, H_DONE ) UDINT; END_TYPE E_MAA_States ^^^^^^^^^^^^ :: TYPE E_MAA_States : ( Unknown := 0, Aprt1 := 1, //smallest Aprt2 := 2, Aprt3 := 3, Aprt4 := 4 ); END_TYPE E_MAA_States_X ^^^^^^^^^^^^^^ :: TYPE E_MAA_States_X : ( Unknown := 0, Centered:=1 ); END_TYPE E_MoveState ^^^^^^^^^^^ :: TYPE E_MoveState : ( ABORT, INIT, ENABLE, FORWARD, BACKWARDS, READY, MOVING, NEWTARGETPOSITION, NEWTARGETPOSITION2, ERROR, RESET, HALT, HOME ) UDINT; END_TYPE E_State ^^^^^^^ :: {attribute 'qualified_only'} {attribute 'strict'} TYPE E_State : ( unknown, error, warning, ok ); END_TYPE ST_DRL ^^^^^^ :: TYPE ST_DRL : STRUCT {attribute 'pytmc' := ' pv: TEMP '} TEMP AT%I*: UINT; {attribute 'pytmc' := ' pv: SV '} SV AT%I*: UINT; {attribute 'pytmc' := ' pv: SC '} SC AT%I*: UINT; END_STRUCT END_TYPE ST_VGP ^^^^^^ :: TYPE ST_VGP : STRUCT {attribute 'pytmc' := ' pv: POS_RBV; io: i; '} // Inputs i_iPosition : REAL; //Encoder position readback (if it exists) {attribute 'pytmc' := ' pv: ENC_RBV; io: i; '} // Inputs rEnoder_Position : REAL; //Encoder position readback (if it exists) {attribute 'pytmc' := ' pv: ERROR; field: ZNAM FALSE; field: ONAM TRUE; io: i; '} // Inputs pv_xError : BOOL; {attribute 'pytmc' := ' pv: IS_HOMED; field: ZNAM FALSE; field: ONAM TRUE; io: i; '} // Inputs pv_xHomed : BOOL :=false; //Softvariables {attribute 'pytmc' := ' pv: ILK_OK; field: ZNAM FALSE; field: ONAM TRUE; io: i; '} xIlkOK : BOOL := FALSE; // Interlock Bit //Manually Pressing valve "Open/Close" on EDM {attribute 'pytmc' := ' pv: OPN_SW; field: ZNAM FALSE; field: ONAM TRUE; io: io; '} pv_xOPN_SW : BOOL; {attribute 'pytmc' := ' pv: GO_SW; field: ZNAM FALSE; field: ONAM TRUE; io: io; '} pv_xGo_SW : BOOL; {attribute 'pytmc' := ' pv: HOME_SW; field: ZNAM FALSE; field: ONAM TRUE; io: io; '} pv_xHome_SW : BOOL; {attribute 'pytmc' := ' pv: Reset_SW; field: ZNAM FALSE; field: ONAM TRUE; io: io; '} pv_xReset_SW : BOOL; {attribute 'pytmc' := ' pv: Busy; field: ZNAM FALSE; field: ONAM TRUE; io: io; '} xBusy : BOOL; {attribute 'pytmc' := ' pv: ABORT; field: ZNAM FALSE; field: ONAM TRUE; io: io; '} pv_xABORT_SW : BOOL; {attribute 'pytmc' := ' pv: POS_CTRL; io: io; '} rReqPosition : REAL; // Outputs {attribute 'pytmc' := ' pv: POS_DES; io: io; '} q_iRawPosition : INT; //Position control {attribute 'pytmc' := ' pv: STATE; type: mbbi ; field: ZRST CLOSE ; field: ONST OPEN; field: TWST PRESS CNTRL ; field: THST MANUAL CNTRL ; io: io; '} eValveControl : E_VCN := CloseValve; // Valve control state /// state machine state {attribute 'pytmc' := ' pv: Axis_STATE; io: io; '} eState: E_MoveState; //Axis Move state ftIlk : F_TRIG; {attribute 'pytmc' := ' pv: ERR_ID; io: i; '} nErrorID: UDINT; {attribute 'pytmc' := ' pv: ERR_MSG; io: i; '} sErrorMessage : STRING; END_STRUCT END_TYPE Related: * `E_MoveState`_ GVLs ---- Global_Version ^^^^^^^^^^^^^^ :: {attribute 'TcGenerated'} {attribute 'no-analysis'} {attribute 'linkalways'} // This function has been automatically generated from the project information. VAR_GLOBAL CONSTANT {attribute 'const_non_replaced'} stLibVersion_KFE_GATT : ST_LibVersion := (iMajor := 0, iMinor := 3, iBuild := 1, iRevision := 0, nFlags := 1, sVersion := '0.3.1'); END_VAR GVL_Devices ^^^^^^^^^^^ :: VAR_GLOBAL (*AT1K0*) /// Injector //Valves {attribute 'pytmc' :=' pv: AT1K0:GAS:VCN:70 '} VCN_70 : FB_VCN; {attribute 'pytmc' :=' pv: AT1K0:GAS:VVC:71 '} VVC_71 : FB_VVC; {attribute 'pytmc' :=' pv: AT1K0:GAS:VVC:72 '} VVC_72 : FB_VVC; {attribute 'pytmc' :=' pv: AT1K0:GAS:VGP:80 '} VGP_80 : FB_VGP; //Gauges {attribute 'pytmc' :=' pv: AT1K0:GAS:GCM:70 '} GCM_70: FB_GCM; {attribute 'pytmc' :=' pv: AT1K0:GAS:GCM:80 '} GCM_80: FB_GCM; {attribute 'pytmc' :=' pv: AT1K0:GAS:GCM:81 '} GCM_81: FB_GCM; (*Pseudo gauge device Structure to combine the readings of two GCM gauges*) {attribute 'pytmc' :=' pv: AT1K0:GAS:GCM:82 '} GCM_82 : ST_VG; ///////////////////////////// ////////////////////////////////// // MKS275 Gauges {attribute 'pytmc' := ' pv: AT1K0:GAS:GPI:111 '} fb_AT1K0_GAS_GPI_111 : FB_MKS275; {attribute 'pytmc' := ' pv: AT1K0:GAS:GPI:121 '} fb_AT1K0_GAS_GPI_121 : FB_MKS275; {attribute 'pytmc' := ' pv: AT1K0:GAS:GPI:141 '} fb_AT1K0_GAS_GPI_141 : FB_MKS275; // FB_MKS317 {attribute 'pytmc' := ' pv: AT1K0:GAS:GPI:10 '} fb_AT1K0_GAS_GPI_10 : FB_MKS317; {attribute 'pytmc' := ' pv: AT1K0:GAS:GPI:20 '} fb_AT1K0_GAS_GPI_20 : FB_MKS317; {attribute 'pytmc' := ' pv: AT1K0:GAS:GPI:11 '} fb_AT1K0_GAS_GPI_11 : FB_MKS317; {attribute 'pytmc' := ' pv: AT1K0:GAS:GPI:30 '} fb_AT1K0_GAS_GPI_30 : FB_MKS317; {attribute 'pytmc' := ' pv: AT1K0:GAS:GPI:40 '} fb_AT1K0_GAS_GPI_40 : FB_MKS317; {attribute 'pytmc' := ' pv: AT1K0:GAS:GPI:50 '} fb_AT1K0_GAS_GPI_50 : FB_MKS317; {attribute 'pytmc' := ' pv: AT1K0:GAS:GPI:60 '} fb_AT1K0_GAS_GPI_60 : FB_MKS317; {attribute 'pytmc' := ' pv: AT1K0:GAS:GPI:51 '} fb_AT1K0_GAS_GPI_51 : FB_MKS317; {attribute 'pytmc' := ' pv: AT1K0:GAS:GPI:80 '} fb_AT1K0_GAS_GPI_80 : FB_MKS317; {attribute 'pytmc' := ' pv: AT1K0:GAS:GPI:90 '} fb_AT1K0_GAS_GPI_90 : FB_MKS317; {attribute 'pytmc' := ' pv: AT1K0:GAS:GPI:100 '} fb_AT1K0_GAS_GPI_100 : FB_MKS317; {attribute 'pytmc' := ' pv: AT1K0:GAS:GPI:110 '} fb_AT1K0_GAS_GPI_110 : FB_MKS317; {attribute 'pytmc' := ' pv: AT1K0:GAS:GPI:120 '} fb_AT1K0_GAS_GPI_120 : FB_MKS317; {attribute 'pytmc' := ' pv: AT1K0:GAS:GPI:130 '} fb_AT1K0_GAS_GPI_130 : FB_MKS317; {attribute 'pytmc' := ' pv: AT1K0:GAS:GPI:140 '} fb_AT1K0_GAS_GPI_140 : FB_MKS317; // FB_MKS422 {attribute 'pytmc' := ' pv: AT1K0:GAS:GCC:10 '} fb_AT1K0_GAS_GCC_10 : FB_MKS422; {attribute 'pytmc' := ' pv: AT1K0:GAS:GCC:20 '} fb_AT1K0_GAS_GCC_20 : FB_MKS422; {attribute 'pytmc' := ' pv: AT1K0:GAS:GCC:30 '} fb_AT1K0_GAS_GCC_30 : FB_MKS422; {attribute 'pytmc' := ' pv: AT1K0:GAS:GCC:40 '} fb_AT1K0_GAS_GCC_40 : FB_MKS422; {attribute 'pytmc' := ' pv: AT1K0:GAS:GCC:50 '} fb_AT1K0_GAS_GCC_50 : FB_MKS422; {attribute 'pytmc' := ' pv: AT1K0:GAS:GCC:60 '} fb_AT1K0_GAS_GCC_60 : FB_MKS422; {attribute 'pytmc' := ' pv: AT1K0:GAS:GCC:80 '} fb_AT1K0_GAS_GCC_80 : FB_MKS422; {attribute 'pytmc' := ' pv: AT1K0:GAS:GCC:90 '} fb_AT1K0_GAS_GCC_90 : FB_MKS422; {attribute 'pytmc' := ' pv: AT1K0:GAS:GCC:100 '} fb_AT1K0_GAS_GCC_100 : FB_MKS422; {attribute 'pytmc' := ' pv: AT1K0:GAS:GCC:110 '} fb_AT1K0_GAS_GCC_110 : FB_MKS422; {attribute 'pytmc' := ' pv: AT1K0:GAS:GCC:120 '} fb_AT1K0_GAS_GCC_120 : FB_MKS422; {attribute 'pytmc' := ' pv: AT1K0:GAS:GCC:130 '} fb_AT1K0_GAS_GCC_130 : FB_MKS422; {attribute 'pytmc' := ' pv: AT1K0:GAS:GCC:140 '} fb_AT1K0_GAS_GCC_140 : FB_MKS422; // FB_VRC {attribute 'pytmc' := ' pv: AT1K0:GAS:VRC:10 '} fb_AT1K0_GAS_VRC_10 : FB_VRC_EBD; {attribute 'pytmc' := ' pv: AT1K0:GAS:VRC:20 '} fb_AT1K0_GAS_VRC_20 : FB_VRC_EBD; {attribute 'pytmc' := ' pv: AT1K0:GAS:VRC:30 '} fb_AT1K0_GAS_VRC_30 : FB_VRC_EBD; {attribute 'pytmc' := ' pv: AT1K0:GAS:VRC:40 '} fb_AT1K0_GAS_VRC_40 : FB_VRC_EBD; {attribute 'pytmc' := ' pv: AT1K0:GAS:VRC:50 '} fb_AT1K0_GAS_VRC_50 : FB_VRC; {attribute 'pytmc' := ' pv: AT1K0:GAS:VRC:60 '} fb_AT1K0_GAS_VRC_60 : FB_VRC; {attribute 'pytmc' := ' pv: AT1K0:GAS:VRC:70 '} fb_AT1K0_GAS_VRC_70 : FB_VRC; {attribute 'pytmc' := ' pv: AT1K0:GAS:VRC:80 '} fb_AT1K0_GAS_VRC_80 : FB_VRC; {attribute 'pytmc' := ' pv: AT1K0:GAS:VRC:90 '} fb_AT1K0_GAS_VRC_90 : FB_VRC; {attribute 'pytmc' := ' pv: AT1K0:GAS:VRC:100 '} fb_AT1K0_GAS_VRC_100 : FB_VRC; {attribute 'pytmc' := ' pv: AT1K0:GAS:VRC:110 '} fb_AT1K0_GAS_VRC_110 : FB_VRC; {attribute 'pytmc' := ' pv: AT1K0:GAS:VRC:120 '} fb_AT1K0_GAS_VRC_120 : FB_VRC; {attribute 'pytmc' := ' pv: AT1K0:GAS:VRC:130 '} fb_AT1K0_GAS_VRC_130 : FB_VRC; {attribute 'pytmc' := ' pv: AT1K0:GAS:VRC:140 '} fb_AT1K0_GAS_VRC_140 : FB_VRC; // PUMPS // Turbos // FB_PTM_Ebara_010M {attribute 'pytmc' := ' pv: AT1K0:GAS:PTM:10 '} fb_AT1K0_GAS_PTM_10 : FB_PTM_Ebara_010M; {attribute 'pytmc' := ' pv: AT1K0:GAS:PTM:20 '} fb_AT1K0_GAS_PTM_20 : FB_PTM_Ebara_010M; {attribute 'pytmc' := ' pv: AT1K0:GAS:PTM:30 '} fb_AT1K0_GAS_PTM_30 : FB_PTM_Ebara_010M; {attribute 'pytmc' := ' pv: AT1K0:GAS:PTM:40 '} fb_AT1K0_GAS_PTM_40 : FB_PTM_Ebara_010M; {attribute 'pytmc' := ' pv: AT1K0:GAS:PTM:80 '} fb_AT1K0_GAS_PTM_80 : FB_PTM_TwisTorr; {attribute 'pytmc' := ' pv: AT1K0:GAS:PTM:120 '} fb_AT1K0_GAS_PTM_120 : FB_PTM_Ebara_010M; {attribute 'pytmc' := ' pv: AT1K0:GAS:PTM:130 '} fb_AT1K0_GAS_PTM_130 : FB_PTM_Ebara_010M; {attribute 'pytmc' := ' pv: AT1K0:GAS:PTM:140 '} fb_AT1K0_GAS_PTM_140 : FB_PTM_Ebara_010M; // FB_PTM_Ebara_011M {attribute 'pytmc' := ' pv: AT1K0:GAS:PTM:110 '} fb_AT1K0_GAS_PTM_110 : FB_PTM_Ebara_011M; // Roughing // FB_EbaraDryPump {attribute 'pytmc' := ' pv: AT1K0:GAS:PMF:10 '} fb_AT1K0_GAS_PMF_10 : FB_ScrollPump; {attribute 'pytmc' := ' pv: AT1K0:GAS:PMF:60 '} fb_AT1K0_GAS_PMF_60 : FB_ScrollPump; {attribute 'pytmc' := ' pv: AT1K0:GAS:PMF:90 '} fb_AT1K0_GAS_PMF_90 : FB_EbaraDryPump; {attribute 'pytmc' := ' pv: AT1K0:GAS:PMF:100 '} fb_AT1K0_GAS_PMF_100 : FB_EbaraDryPump; {attribute 'pytmc' := ' pv: AT1K0:GAS:PMF:110 '} fb_AT1K0_GAS_PMF_110 : FB_EbaraEVA; {attribute 'pytmc' := ' pv: AT1K0:GAS:PMF:120 '} fb_AT1K0_GAS_PMF_120 : FB_EbaraEVA; {attribute 'pytmc' := ' pv: AT1K0:GAS:PMF:140 '} fb_AT1K0_GAS_PMF_140 : FB_EbaraEVA; //Roughing DC Valves {attribute 'pytmc' := ' pv: AT1K0:GAS:VCP:110 '} //{attribute 'TcLinkTo' := '.q_xOPN_DO := TIIB[=+-EL2212_06_25]^DOX Control Channel 1^Control^Output'} {attribute 'TcLinkTo' := '.q_xOPN_DO := TIIB[=+-ES2004_05_02]^Channel 3^Output'} fb_AT1K0_GAS_VVC_110 : FB_VVC; {attribute 'pytmc' := ' pv: AT1K0:GAS:VCP:120 '} //{attribute 'TcLinkTo' := '.q_xOPN_DO := TIIB[=+-EL2212_06_25]^DOX Control Channel 2^Control^Output'} {attribute 'TcLinkTo' := '.q_xOPN_DO := TIIB[=+-ES2004_05_02]^Channel 4^Output'} fb_AT1K0_GAS_VVC_120 : FB_VVC; {attribute 'pytmc' := ' pv: AT1K0:GAS:VCP:140 '} //{attribute 'TcLinkTo' := '.q_xOPN_DO := TIIB[=+-EL2212_04_18]^DOX Control Channel 1^Control^Output'} {attribute 'TcLinkTo' := '.q_xOPN_DO := TIIB[=+-ES2004_05_04]^Channel 3^Output'} fb_AT1K0_GAS_VVC_140 : FB_VVC; //PTM 80 VRC back stream valve {attribute 'pytmc' := ' pv: AT1K0:GAS:VVC:80 '} {attribute 'TcLinkTo' := '.q_xOPN_DO := TIIB[=+-EL2212_04_18]^DOX Control Channel 2^Control^Output'} fb_AT1K0_GAS_VVC_80 : FB_VVC; //NEW added Valve instead of the manual valve at the roughing line in the EBD {attribute 'pytmc' := ' pv: AT1K0:GAS:VRC:11 '} {attribute 'TcLinkTo' := '.q_xOPN_DO := TIIB[=+-ES2008_02_14]^Channel 1^Output; .i_xClsLS := TIIB[=+-ES1004_03_21]^Channel 2^Input; .i_xOpnLS := TIIB[=+-ES1004_03_21]^Channel 1^Input'} fb_AT1K0_GAS_VRC_11 : FB_VRC_EBD; {attribute 'pytmc' := ' pv: AT1K0:GAS:GPI:12 '} {attribute 'TcLinkTo' := '.i_iPRESS_R := TIIB[=+-ES3064_01_09]^AI Standard Channel 4^Value'} fb_AT1K0_GAS_GPI_12 : FB_MKS317; END_VAR Related: * `FB_VGP`_ GVL_GATT ^^^^^^^^ :: VAR_GLOBAL fbLogHandler: FB_LogHandler; fbLogger : FB_LogMessage := (eSubsystem:=E_SubSystem.MPS,nMinTimeViolationAcceptable:=10,nLocalTripThreshold := T#500ms); fbEcatDiagWrapper : FB_EcatDiagWrapper; END_VAR GVL_MOT ^^^^^^^ :: VAR_GLOBAL END_VAR GVL_PMPS ^^^^^^^^ :: VAR_GLOBAL //MPS {attribute 'pytmc' := ' pv: PLC:KFE:GATT:FFO:01 '} {attribute 'TcLinkTo' := '.q_xFastFaultOut:=TIIB[=+-ES2202_00_07]^Channel 1^Output'} g_FastFaultOutput1 : FB_HardwareFFOutput :=(i_sNetID:='172.21.92.73.1.1'); {attribute 'pytmc' := ' pv: PLC:KFE:GATT:FFO:02 '} {attribute 'TcLinkTo' := '.q_xFastFaultOut:=TIIB[=+-ES2202_00_07]^Channel 2^Output'} g_FastFaultOutput2 : FB_HardwareFFOutput :=(i_sNetID:='172.21.92.73.1.1'); {attribute 'pytmc' := ' pv: PLC:KFE:GATT:FF_RESET; field: ZNAM FALSE; field: ONAM TRUE; io: io; '} xFastFaultReset : BOOL; {attribute 'pytmc' := ' pv: PLC:KFE:GATT:ARB:01 '} fbArbiter1 : FB_Arbiter(1); {attribute 'pytmc' := ' pv: PLC:KFE:GATT:ARB:02 '} fbArbiter2 : FB_Arbiter(2); {attribute 'pytmc' := ' pv: AT1K0:GAS:MODE ; field: ZNAM Local; field: ONAM PMPS; io: io; '} xPMPSMode :BOOL; {attribute 'TcLinkTo' := ':=TIIB[PMPS_PRE]^IO Inputs^Requested Transmission'} Req_Trans AT%I*: ST_PMPS_Attenuator_IO; {attribute 'TcLinkTo' := ':=TIIB[PMPS_PRE]^IO Outputs^Current Transmission'} Cur_Trans AT%Q*: ST_PMPS_Attenuator_IO; {attribute 'pytmc' := ' pv: AT1K0:GAS:PhotonEnergy '} rPhotonEnergy : REAL; stStatus: ST_AttenuatorStatus; {attribute 'TcLinkTo' := ':=TIIB[PMPS_PRE]^IO Outputs^bGattStatus'} bStatus AT%Q*:Byte; END_VAR GVL_Variables ^^^^^^^^^^^^^ :: VAR_GLOBAL (*Transmission related variables*) {attribute 'pytmc' := ' pv: AT1K0:GAS:GAS_TYPE ; type: mbbi ; field: ZRST none ; field: ONST N2; field: TWST Ar ; io: i '} SelectedGas: E_GasType; {attribute 'pytmc' :=' pv: AT1K0:GAS:CNTRL:CALC_SP; field: HOPR 1000; field: LOPR 0; field: PREC 2; field: EGU "TORR"; '} rRequiredPressureSP: REAL; {attribute 'pytmc' := ' pv: AT1K0:GAS:MAA:GET; io: i; field: ZRST Unknown; field: ONST 5.5mm; field: TWST 8mm; field: THST 10mm; field: FRST 13mm; '} eSelectedAprt:E_MAA_States; {attribute 'pytmc' := ' pv: AT1K0:GAS:MAA:SET; io: i; field: ZRST Unknown; field: ONST 5.5mm; field: TWST 8mm; field: THST 10mm; field: FRST 13mm; '} eSetAprt:E_MAA_States; {attribute 'pytmc' := ' pv: AT1K0:GAS:TRANS; field: HOPR 1000; field: LOPR 0; field: PREC 2; io:i; '} rCalculatedTransmissionValue: REAL:=1; {attribute 'pytmc' := ' pv: AT1K0:GAS:TRANS_REQ; field: HOPR 1000; field: LOPR 0; field: PREC 2; io:i; '} rRequestedTransmission: REAL:=1; {attribute 'pytmc' := ' pv: AT1K0:GAS:TRANS_SP; field: HOPR 1000; field: LOPR 0; field: PREC 2; io:io; '} rTransmissionSP: REAL:=1; {attribute 'pytmc' := ' pv: AT1K0:GAS:STATE; field: ZRST unknown; field: ONST error; field: TWST warning; field: THST ok; io: i; '} eState:E_State; TransmissionValue: REAL; OldTransmissionValue: REAL; rtNewTrans : R_TRIG; bChangeAperture: BOOL:=FALSE; bChangeGas:BOOL:=FALSE; (* EPS and Interlock Variables*) {attribute 'pytmc' := 'pv: AT1K0:GAS:VAC:OVRD_ON ; field: ZNAM Override OFF; field: ONAM Override ON; io: io;'} xSystemOverrideMode : BOOL; (* Global system override for the GATT*) //VRC ILK setpoints to OPEN {attribute 'pytmc' :=' pv: AT1K0:GAS:CNTRL:US:SP; field: HOPR 1000; field: LOPR 0; field: PREC 2; field: EGU "TORR"; '} rVRC_US_SP :REAL:=0.001; {attribute 'pytmc' :=' pv: AT1K0:GAS:CNTRL:DS:SP; field: HOPR 1000; field: LOPR 0; field: PREC 2; field: EGU "TORR"; '} rVRC_DS_SP :REAL:=0.001; {attribute 'pytmc' := ' pv: AT1K0:GAS:MODE:PressureControl ; field: ZNAM Local; field: ONAM PMPS; io: io; '} xPressureControlMode :BOOL := FALSE; {attribute 'pytmc' := ' pv: AT1K0:GAS:AtTarget ; field: ZNAM FALSE; field: ONAM TRUE; io: io; '} xAtTarget :BOOL := FALSE; {attribute 'pytmc' := ' pv: AT1K0:GAS:Moving ; field: ZNAM FALSE; field: ONAM TRUE; io: io; '} xMoving :BOOL := FALSE; {attribute 'pytmc' := ' pv: AT1K0:GAS:OK ; field: ZNAM FALSE; field: ONAM TRUE; io: io; '} xOK :BOOL := FALSE; (* Interlock related bits, local to the PLC*) US_MAA_OK: BOOL; US_Turbo_Valves_Open: BOOL; DS_MAA_OK: BOOL; DS_Turbo_Valves_Open: BOOL; US_Turbo_Running: BOOL; DS_Turbo_Running: BOOL; TwinscrewPumps_Valves_Closed: BOOL; US_Roughing_Valves_Open : BOOL; DS_Roughing_Valves_Open : BOOL; US_Aperture_Closed: BOOL; DS_Aperture_Closed: BOOL; END_VAR Related: * `E_GasType`_ * `E_MAA_States`_ * `E_State`_ Main ^^^^ :: VAR_GLOBAL //MAA EBD {attribute 'pytmc' := 'pv: AT1K0:GAS_MA_X:MMS:1'} {attribute 'TcLinkTo' := '.bLimitForwardEnable := TIIB[=+-ES7041_02_05]^STM Status^Status^Digital input 1; .bLimitBackwardEnable := TIIB[=+-ES7041_02_05]^STM Status^Status^Digital input 2'} // .nRawEncoderINT := TIIB[=+-E3054_02_17]^AI Standard Channel 1^Value'} M1: DUT_MotionStage := (sName := 'AT1K0:GAS_MA_X:MMS:1'); {attribute 'pytmc' := 'pv: AT1K0:GAS_MA_Y:MMS:1'} {attribute 'TcLinkTo' := '.bLimitForwardEnable := TIIB[=+-ES7041_02_06]^STM Status^Status^Digital input 2; .bLimitBackwardEnable := TIIB[=+-ES7041_02_06]^STM Status^Status^Digital input 1; .bBrakeRelease := TIIB[=+-ES2004_02_07]^Channel 3^Output'} //.nRawEncoderINT := TIIB[=+-E3054_02_17]^AI Standard Channel 2^Value'} M2: DUT_MotionStage := (sName := 'AT1K0:GAS_MA_Y:MMS:1'); {attribute 'pytmc' := 'pv: AT1K0:GAS_MA_X:MMS:2'} {attribute 'TcLinkTo' := '.bLimitForwardEnable := TIIB[=+-ES7041_02_09]^STM Status^Status^Digital input 1; .bLimitBackwardEnable := TIIB[=+-ES7041_02_09]^STM Status^Status^Digital input 2'} // .nRawEncoderINT := TIIB[=+-E3054_02_17]^AI Standard Channel 3^Value'} M3: DUT_MotionStage := (sName := 'AT1K0:GAS_MA_X:MMS:2'); {attribute 'pytmc' := 'pv: AT1K0:GAS_MA_Y:MMS:2'} {attribute 'TcLinkTo' := '.bLimitForwardEnable := TIIB[=+-ES7041_02_10]^STM Status^Status^Digital input 2; .bLimitBackwardEnable := TIIB[=+-ES7041_02_10]^STM Status^Status^Digital input 1; .bBrakeRelease := TIIB[=+-ES2004_02_07]^Channel 4^Output'} // .nRawEncoderINT := TIIB[=+-E3054_02_17]^AI Standard Channel 4^Value'} M4: DUT_MotionStage := (sName := 'AT1K0:GAS_MA_Y:MMS:2'); //MAA FEE {attribute 'pytmc' := 'pv: AT1K0:GAS_MA_X:MMS:3'} {attribute 'TcLinkTo' := '.bLimitForwardEnable := TIIB[=+-EL7041_04_07]^STM Status^Status^Digital input 2; .bLimitBackwardEnable := TIIB[=+-EL7041_04_07]^STM Status^Status^Digital input 1; .bBrakeRelease := TIIB[=+-ES2004_04_09]^Channel 1^Output'} // .nRawEncoderINT := TIIB[=+-E3054_04_12]^AI Standard Channel 1^Value'} M5: DUT_MotionStage := (sName := 'AT1K0:GAS_MA_X:MMS:3'); {attribute 'pytmc' := 'pv: AT1K0:GAS_MA_Y:MMS:3'} {attribute 'TcLinkTo' := '.bLimitForwardEnable := TIIB[=+-EL7041_04_08]^STM Status^Status^Digital input 2; .bLimitBackwardEnable := TIIB[=+-EL7041_04_08]^STM Status^Status^Digital input 1; .bBrakeRelease := TIIB[=+-ES2004_04_09]^Channel 2^Output'} // .nRawEncoderINT := TIIB[=+-E3054_04_12]^AI Standard Channel 2^Value'} M6: DUT_MotionStage := (sName := 'AT1K0:GAS_MA_Y:MMS:3'); {attribute 'pytmc' := 'pv: AT1K0:GAS_MA_X:MMS:4'} {attribute 'TcLinkTo' := '.bLimitForwardEnable := TIIB[=+-EL7041_04_10]^STM Status^Status^Digital input 2; .bLimitBackwardEnable := TIIB[=+-EL7041_04_10]^STM Status^Status^Digital input 1; .bBrakeRelease := TIIB[=+-ES2004_04_09]^Channel 3^Output'} //.nRawEncoderINT := TIIB[=+-E3054_04_12]^AI Standard Channel 3^Value'} M7: DUT_MotionStage := (sName := 'AT1K0:GAS_MA_X:MMS:4'); {attribute 'pytmc' := 'pv: AT1K0:GAS_MA_Y:MMS:4'} {attribute 'TcLinkTo' := '.bLimitForwardEnable := TIIB[=+-EL7041_04_11]^STM Status^Status^Digital input 2; .bLimitBackwardEnable := TIIB[=+-EL7041_04_11]^STM Status^Status^Digital input 1; .bBrakeRelease := TIIB[=+-ES2004_04_09]^Channel 4^Output'} // .nRawEncoderINT := TIIB[=+-E3054_04_12]^AI Standard Channel 4^Value'} M8: DUT_MotionStage := (sName := 'AT1K0:GAS_MA_Y:MMS:4'); END_VAR POUs ---- DIAGNOSTICS ^^^^^^^^^^^ :: PROGRAM DIAGNOSTICS VAR //Change the PLC String Name to the actual PLC NAME sPLCName :STRING := 'PLC-KFE_GATT'; //Link the sAMSNetID to the Etherat Master netID i_sAMSNetID AT %I*: AMSNETID; // DO NOT CHANGE sAMSNetID : STRING; //used for EPICS PV sLibVersion_LCLS_General : STRING;(* := stLibVersion_LCLS_General.sVersion*) ; fbEcatDiag:FB_EcatDiag; bAllSlaveStateGood : BOOL; bMasterStateGood :BOOL; iMasterState: WORD; sMasterState:STRING; nSlaveNumber : UINT; aiSlaveStates: ARRAY[1..256] OF BYTE; aEcSlaveInfo : ARRAY[1..256] OF ST_EcDevice; // Infor Data from Diagnostics terminals {attribute 'pytmc' := ' pv: AT1K0:GAS:DRL:04 '} {attribute 'TcLinkTo' := '.TEMP := TIIB[=+-EL2212_04_18]^DOX Synchron info data Channel 1^Info data 1; .SV := TIIB[=+-EL2212_04_18]^DOX Synchron info data Channel 1^Info data 2; .SC := TIIB[=+-EL2212_04_18]^DOX Synchron info data Channel 2^Info data 1'} DRL_04 : ST_DRL; {attribute 'pytmc' := ' pv: AT1K0:GAS:DRL:05 '} {attribute 'TcLinkTo' := '.TEMP := TIIB[=+-EL2212_05_09]^DOX Synchron info data Channel 1^Info data 1; .SV := TIIB[=+-EL2212_05_09]^DOX Synchron info data Channel 1^Info data 2; .SC := TIIB[=+-EL2212_05_09]^DOX Synchron info data Channel 2^Info data 1'} DRL_05 : ST_DRL; {attribute 'pytmc' := ' pv: AT1K0:GAS:DRL:06 '} {attribute 'TcLinkTo' := '.TEMP := TIIB[=+-EL2212_06_25]^DOX Synchron info data Channel 1^Info data 1; .SV := TIIB[=+-EL2212_06_25]^DOX Synchron info data Channel 1^Info data 2; .SC := TIIB[=+-EL2212_06_25]^DOX Synchron info data Channel 2^Info data 1'} DRL_06 : ST_DRL; END_VAR // Instaniating a call to the fbEcatDiag fbEcatDiag( I_AMSNetId:=i_sAMSNetID , i_xFirstPass:= _TaskInfo[1].FirstCycle, q_xAllSlaveStatesGood=> bAllSlaveStateGood , q_anTermStates=> aiSlaveStates, q_xMasterStateGood=>bMasterStateGood , q_nMasterState=> iMasterState, q_sMasterState=> sMasterState , q_astEcConfSlaveInfo=> aEcSlaveInfo , q_nSlaves=> nSlaveNumber); END_PROGRAM Related: * `ST_DRL`_ F_COEF_AR ^^^^^^^^^ :: FUNCTION F_COEF_AR : REAL VAR_INPUT END_VAR VAR END_VAR END_FUNCTION FB_ILK_TEST ^^^^^^^^^^^ :: FUNCTION_BLOCK FB_ILK_TEST VAR_INPUT END_VAR VAR_OUTPUT END_VAR VAR END_VAR END_FUNCTION_BLOCK FB_MAA ^^^^^^ :: FUNCTION_BLOCK FB_MAA VAR_IN_OUT fbArbiter: FB_Arbiter; fbFFHWO: FB_HardwareFFOutput; stYStage: DUT_MotionStage; stXStage: DUT_MotionStage; END_VAR VAR_INPUT {attribute 'pytmc' := ' pv: :PMPS:AribterEnabled io: io '} bArbiterEnabled: BOOL:=TRUE;; nTransitionAssertionID: UDINT; stAprt1: DUT_PositionState; stAprt2: DUT_PositionState; stAprt3: DUT_PositionState; stAprt4: DUT_PositionState; stXCen: DUT_PositionState; i_DevName: STRING:= 'AT1K0-MAA'; {attribute 'pytmc' := ' pv: Y:STATE:SET; io: io; field: ZRST Unknown; field: ONST 5.5mm; field: TWST 8mm; field: THST 10mm; field: FRST 13mm; '} enumSet: E_MAA_states; sPmpsDeviceName: STRING; sTransitionKey: STRING; END_VAR VAR_OUTPUT {attribute 'pytmc' := ' pv: Y:STATE io: io '} fbStates: FB_MAA_States; {attribute 'pytmc' := ' pv: X:STATE io: io '} fbStates_X: FB_MAA_States_X; END_VAR VAR fbYStage: FB_MotionStage; fbXStage: FB_MotionStage; // fSize1: REAL:=3.0; //mm // fSize2: REAL:=7.0; //mm // fSize3: REAL:=8.5; //mm // fSize4: REAL:=9.0; //mm bInit:BOOL := TRUE; tArbiterTimeout: TIME:= T#10S; FFO : FB_FastFault :=( i_DevName := 'AT1K0-MAA', i_Desc := 'Fault occurs when the PMPS Aribter is switched off for the aperture plate states BPTM', i_TypeCode := 16#AAFF); END_VAR if(bInit) THEN stYStage.bHardwareEnable := TRUE; stYStage.bPowerSelf := FALSE; stYStage.nBrakeMode := ENUM_StageBrakeMode.IF_MOVING; stXStage.bHardwareEnable := TRUE; stXStage.bPowerSelf := FALSE; stXStage.nBrakeMode := ENUM_StageBrakeMode.NO_BRAKE; bInit:=FALSE; // States settings //stAprt1.nRequestAssertionID := nTransitionAssertionID+1; //stAprt1.stBeamParams := PMPS_GVL.cstFullBeam; //stAprt1.stBeamParams.astApertures[1].Height := fSize1; //stAprt1.stBeamParams.astApertures[1].Width := fSize1; stAprt1.bUseRawCounts := FALSE; stAprt1.bValid := TRUE; stAprt1.stPMPS.sPmpsState := CONCAT(sPmpsDeviceName,'-APERTURE1'); //stAprt2.nRequestAssertionID := nTransitionAssertionID+2; //stAprt2.stBeamParams := PMPS_GVL.cstFullBeam; //stAprt2.stBeamParams.astApertures[1].Height := fSize2; //stAprt2.stBeamParams.astApertures[1].Width :=fSize2; stAprt2.bUseRawCounts := FALSE; stAprt2.bValid := TRUE; stAprt2.stPMPS.sPmpsState := CONCAT(sPmpsDeviceName,'-APERTURE2'); //stAprt3.nRequestAssertionID := nTransitionAssertionID+3; //stAprt3.stBeamParams := PMPS_GVL.cstFullBeam; //stAprt3.stBeamParams.astApertures[1].Height := fSize3; //stAprt3.stBeamParams.astApertures[1].Width := fSize3; stAprt3.bUseRawCounts := FALSE; stAprt3.bValid := TRUE; stAprt3.stPMPS.sPmpsState := CONCAT(sPmpsDeviceName,'-APERTURE3'); //stAprt4.nRequestAssertionID := nTransitionAssertionID+4; //stAprt4.stBeamParams := PMPS_GVL.cstFullBeam; //stAprt4.stBeamParams.astApertures[1].Height := fSize4; //stAprt4.stBeamParams.astApertures[1].Width := fSize4; stAprt4.bUseRawCounts := FALSE; stAprt4.bValid := TRUE; stAprt4.stPMPS.sPmpsState := CONCAT(sPmpsDeviceName,'-APERTURE4'); //stXCen.nRequestAssertionID := nTransitionAssertionID+6; //stXCen.stBeamParams := PMPS_GVL.cstFullBeam; stXCen.bUseRawCounts := FALSE; stXCen.bValid := TRUE; stXCen.stPMPS.sPmpsState := CONCAT(sPmpsDeviceName,'-XCENTER'); FFO.i_DevName := i_DevName; END_IF fbYStage(stMotionStage:=stYStage); fbXStage(stMotionStage:=stXStage); fbStates( fbArbiter:=fbArbiter, fbFFHWO:=fbFFHWO, //nTransitionAssertionID:=nTransitionAssertionID, //stTransitionBeam:= PMPS_GVL.cst0RateBeam, bArbiterEnabled := bArbiterEnabled, tArbiterTimeout :=tArbiterTimeout, stMotionStage:=stYStage, bEnable:=TRUE, stAprt1:=stAprt1, stAprt2:=stAprt2, stAprt3:=stAprt3, stAprt4:=stAprt4, enumSet:= enumSet, sPmpsDeviceName:=sPmpsDeviceName, sTransitionKey:=CONCAT(sTransitionKey,'_Y'), bBPOKAutoReset := TRUE); fbStates_X( fbArbiter:=fbArbiter, fbFFHWO:=fbFFHWO, tArbiterTimeout := tArbiterTimeout, stMotionStage:=stXStage, bEnable:=TRUE, stXCen:=stXCen, sPmpsDeviceName:=sPmpsDeviceName, sTransitionKey:=CONCAT(sTransitionKey,'_X'), bBPOKAutoReset := TRUE); (*FAST FAULT*) FFO(i_xOK := bArbiterEnabled, i_xReset := , i_xAutoReset := TRUE, io_fbFFHWO := fbFFHWO); END_FUNCTION_BLOCK Related: * `FB_MAA_States`_ * `FB_MAA_States_X`_ FB_MAA_States ^^^^^^^^^^^^^ :: FUNCTION_BLOCK FB_MAA_States EXTENDS FB_PositionStateBase_WithPMPS VAR_IN_OUT enumSet: E_MAA_states; END_VAR VAR_INPUT bStatesLock: BOOL; stAprt1: DUT_PositionState; stAprt2: DUT_PositionState; stAprt3: DUT_PositionState; stAprt4: DUT_PositionState; END_VAR VAR_OUTPUT {attribute 'pytmc' := ' pv: GET io: i field: ZRST Unknown; field: ONST 5.5mm; field: TWST 8mm; field: THST 10mm; field: FRST 13mm; '} enumGet: E_MAA_States; END_VAR VAR bStatesInit: BOOL := TRUE; fDelta1: LREAL := 0.5; //only for commissioning should change to more conservative values fDelta2: LREAL := 0.5; fDelta3: LREAL := 0.5; fDelta4: LREAL := 3; END_VAR VAR CONSTANT fVelocity: LREAL := 1; fAccel: LREAL := 200; fDecel: LREAL := 25; END_VAR IF bStatesInit THEN bStatesInit := FALSE; stAprt1.sName := '5.5mm'; stAprt1.fVelocity := fVelocity; stAprt1.fDelta := fDelta1; stAprt1.fAccel := fAccel; stAprt1.fDecel := fAccel; stAprt1.bMoveOk := TRUE; stAprt2.sName := '8mm'; stAprt2.fVelocity := fVelocity; stAprt2.fDelta := fDelta2; stAprt2.fAccel := fAccel; stAprt2.fDecel := fAccel; stAprt2.bMoveOk := TRUE; stAprt3.sName := '10mm'; stAprt3.fVelocity := fVelocity; stAprt3.fDelta := fDelta3; stAprt3.fAccel := fAccel; stAprt3.fDecel := fAccel; stAprt3.bMoveOk := TRUE; stAprt4.sName := '13mm'; stAprt4.fVelocity := fVelocity; stAprt4.fDelta := fDelta4; stAprt4.fAccel := fAccel; stAprt4.fDecel := fAccel; stAprt4.bMoveOk := TRUE; arrStates[1] := stAprt1; arrStates[2] := stAprt2; arrStates[3] := stAprt3; arrStates[4] := stAprt4; END_IF setState := enumSet; Exec(); enumGet := getState; enumSet := setState; END_FUNCTION_BLOCK Related: * `E_MAA_States`_ FB_MAA_States_X ^^^^^^^^^^^^^^^ :: FUNCTION_BLOCK FB_MAA_States_X EXTENDS FB_PositionStateBase_WithPMPS VAR_INPUT {attribute 'pytmc' := ' pv: SET; io: io; field: ZRST Unknown; field: ONST Centered; '} enumSet: E_MAA_states_X; bStatesLock: BOOL; stXCen: DUT_PositionState; END_VAR VAR_OUTPUT {attribute 'pytmc' := ' pv: GET io: i field: ZRST Unknown; field: ONST Centered; '} enumGet: E_MAA_states_X; END_VAR VAR bStatesInit: BOOL := TRUE; fDelta: LREAL := 0.5; END_VAR VAR CONSTANT fVelocity: LREAL := 0.1; fAccel: LREAL := 25; fDecel: LREAL := 25; END_VAR IF bStatesInit THEN bStatesInit := FALSE; stXCen.sName := 'Centered'; stXCen.fVelocity := fVelocity; stXCen.fDelta := fDelta; stXCen.fAccel := fAccel; stXCen.fDecel := fAccel; stXCen.bMoveOk := TRUE; arrStates[1] := stXCen; END_IF setState := enumSet; Exec(); enumGet := getState; enumSet := setState; END_FUNCTION_BLOCK FB_VCN_Lin ^^^^^^^^^^ :: (* This function implements the Basic functions for the Pfeiffer EVR 116 needle valve*) FUNCTION_BLOCK FB_VCN_Lin EXTENDS FB_Valve VAR_INPUT i_xExtIlkOK : BOOL; //External Interlock, SET to TRUE if not used i_ReqPos : REAL; //Requested position i_xPurge : BOOL:= FALSE;// When purge is set the maximum threshold is ignored, has to be set evey cycle. END_VAR VAR_OUTPUT {attribute 'pytmc' := ' pv: '} iq_stVCN : ST_VCN; //Needle valve structure END_VAR VAR CONSTANT rOpenVoltage : REAL := 9.1; // From the EVR 116 manual, A Voltage of 9V it is completely Open rCloseVoltage : REAL := 0.4;// a voltage <0.5 V the valve is closed END_VAR VAR // Requested voltage {attribute 'pytmc' := ' pv: POS_AO; io: i ; '} rReqVoltage: REAL := 0; //iResolution: INT :=16; // (*IO*) q_iRawPosition AT%Q* :INT; //CONTROL stCTRL_LIN_INTERPOLATION_PARAMS : ST_CTRL_LIN_INTERPOLATION_PARAMS; fbCTRL_LIN_INTERPOLATION : FB_CTRL_LIN_INTERPOLATION; arrTable : ARRAY[1..10,1..2] OF FLOAT; arrTable_RBV : ARRAY[1..10,1..2] OF FLOAT; //Readdback stCTRL_LIN_INTERPOLATION_PARAMS_RBV : ST_CTRL_LIN_INTERPOLATION_PARAMS; fbCTRL_LIN_INTERPOLATION_RBV : FB_CTRL_LIN_INTERPOLATION; eMode : E_CTRL_MODE; iCounter:INT; bInit :BOOL :=TRUE; END_VAR VAR PERSISTENT rUpperLimit : REAL; END_VAR (* Needle valve control FB A. Wallace 2016-7-21 This FB should be used as a low level control block. It provides: Valve position ceiling Interlock Scaling It is not intended for: Closed-loop control It could be used for: Valve position/flow linearization Note: Raw position calc is based on 0.5 to 9V span, 32767 bits *) iq_stVCN.rUpperLimit := LIMIT(0, iq_stVCN.rUpperLimit, 100); // Interlocking iq_stVCN.xIlkOK := i_xExtIlkOK; (*Checking which Control mode is selected*) IF iq_stVCN.xIlkOK THEN IF iq_stVCN.eValveControl = OpenValve THEN iq_stVCN.rReqPosition := iq_stVCN.rUpperLimit;(*Percentage*) ELSIF iq_stVCN.eValveControl = CloseValve THEN iq_stVCN.rReqPosition := 0; (*Percentage*) ELSIF (iq_stVCN.eValveControl = ManualControl) (*AND (iq_stVCN.xOPN_SW)*) THEN iq_stVCN.rReqPosition := LIMIT(0, iq_stVCN.rReqPosition, iq_stVCN.rUpperLimit); ELSIF iq_stVCN.eValveControl = PressureControl THEN IF (i_xPurge) THEN iq_stVCN.rReqPosition := LIMIT(0, i_ReqPos, 100); ELSE iq_stVCN.rReqPosition := LIMIT(0, i_ReqPos, iq_stVCN.rUpperLimit); END_IF END_IF ELSE iq_stVCN.rReqPosition := 0; iq_stVCN.eValveControl := CloseValve; END_IF //Raw position calc iq_stvcn.q_iRawPosition := REAL_TO_INT( 32767/10 * rReqVoltage); (*SOft IO Mapping*) ACT_IO(); (*Load or save the persistent variables*) ACT_Persistent(); ACT_INIT(); END_FUNCTION_BLOCK ACTION ACT_INIT: {attribute no_check} IF bInit THEN (* init array with the interpolation points *) (* fIn | fOut *) arrTable[1,1] := 0; arrTable[1,2] := 0; arrTable[2,1] := 15; arrTable[2,2] := 1.4; arrTable[3,1] := 19; arrTable[3,2] := 1.75; arrTable[4,1] := 25; arrTable[4,2] := 2.25; arrTable[5,1] := 31; arrTable[5,2] := 2.8; arrTable[6,1] := 39; arrTable[6,2] := 3.55; arrTable[7,1] := 49; arrTable[7,2] := 4.45; arrTable[8,1] := 62; arrTable[8,2] := 5.65; arrTable[9,1] := 78; arrTable[9,2] := 7.1; arrTable[10,1] := 100; arrTable[10,2] := 9.1; (* init parameter struct *) stCTRL_LIN_INTERPOLATION_PARAMS.tCtrlCycleTime := T#10ms; stCTRL_LIN_INTERPOLATION_PARAMS.tTaskCycleTime := T#10ms; stCTRL_LIN_INTERPOLATION_PARAMS.nDataTable_NumberOfRows := INT_TO_UINT(10); (* set the addresses *) stCTRL_LIN_INTERPOLATION_PARAMS.pDataTable_ADR := ADR(arrTable); stCTRL_LIN_INTERPOLATION_PARAMS.nDataTable_SIZEOF := SIZEOF(arrTable); (* set the mode to ACTIVE --> normal operation *) eMode := eCTRL_MODE_ACTIVE; (* init array with the interpolation points *) (* fIn | fOut *) FOR iCounter:=1 TO 10 BY 1 DO arrTable_RBV[iCounter,1] := arrTable[iCounter,2]; arrTable_RBV[iCounter,2] := arrTable[iCounter,1]; END_FOR; (* init parameter struct *) stCTRL_LIN_INTERPOLATION_PARAMS_RBV.tCtrlCycleTime := T#10ms; stCTRL_LIN_INTERPOLATION_PARAMS_RBV.tTaskCycleTime := T#10ms; stCTRL_LIN_INTERPOLATION_PARAMS_RBV.nDataTable_NumberOfRows := INT_TO_UINT(10); (* set the addresses *) stCTRL_LIN_INTERPOLATION_PARAMS_RBV.pDataTable_ADR := ADR(arrTable_RBV); stCTRL_LIN_INTERPOLATION_PARAMS_RBV.nDataTable_SIZEOF := SIZEOF(arrTable_RBV); (* reset the init flag *) bInit := FALSE; END_IF; END_ACTION ACTION ACT_IO: (*outputs*) q_iRawPosition := iq_stVCN.q_iRawPosition; (*inputs*) iq_stVCN.i_iPosition := iq_stvcn.q_iRawPosition; END_ACTION ACTION ACT_LIN_INTERPOLATION: {attribute 'no_check'} fbCTRL_LIN_INTERPOLATION( fIn:= iq_stVCN.rReqPosition , fManValue:= 0, bExtrapolate:= , eMode:= eMode, fOut=> , bInIsGreaterThanMaxElement=> , bInIsLessThanMinElement=> , eState=> , eErrorId=> , bError=> , stParams:= stCTRL_LIN_INTERPOLATION_PARAMS ); // Requested Voltage calculation //rReqVoltage := iq_stVCN.rReqPosition * (rOpenVoltage-rCloseVoltage)/100 + rCloseVoltage; rReqVoltage := LREAL_TO_REAL(LIMIT(rCloseVoltage, fbCTRL_LIN_INTERPOLATION.fOut, rOpenVoltage)); //The requested voltage should remain within this range fbCTRL_LIN_INTERPOLATION_RBV( fIn:= rReqVoltage , fManValue:= 0, bExtrapolate:= , eMode:= eMode, fOut=> , bInIsGreaterThanMaxElement=> , bInIsLessThanMinElement=> , eState=> , eErrorId=> , bError=> , stParams:= stCTRL_LIN_INTERPOLATION_PARAMS_RBV ); // iq_stVCN.rReqPosition := LREAL_TO_REAL(fbCTRL_LIN_INTERPOLATION_RBV.fOut); END_ACTION ACTION ACT_Logger: // ILK logger IF NOT (iq_stVCN.xIlkOK ) AND NOT(ePrevState = CloseValve) THEN fbLogger(sMsg:='Lost interlock ok bit while valve was open.', eSevr:=TcEventSeverity.Critical); END_IF //Control STATE Logger IF ePrevState <> iq_stVCN.eValveControl THEN CASE iq_stVCN.eValveControl OF ManualControl: fbLogger(sMsg:='Valve in manual control mode', eSevr:=TcEventSeverity.Warning); OpenValve: fbLogger(sMsg:='Valve Open.', eSevr:=TcEventSeverity.Info); PressureControl: fbLogger(sMsg:='Valve in pressure control mode.', eSevr:=TcEventSeverity.Info); CloseValve: fbLogger(sMsg:='Valve closed.', eSevr:=TcEventSeverity.Info); END_CASE ePrevState := iq_stVCN.eValveControl; END_IF // Log valve open tAction(CLK:= (iq_stVCN.eValveControl = OpenValve) ); IF tAction.Q THEN fbLogger(sMsg:='Valve commanded to fully open', eSevr:=TcEventSeverity.Info); END_IF END_ACTION ACTION ACT_Persistent: (*On first PLC pass, load the persistent value into the structrue variable*) IF (bRestorePersistentData) THEN bRestorePersistentData := FALSE; IF (rUpperLimit <> 0) THEN iq_stVCN.rUpperLimit := rUpperLimit; END_IF; END_IF (*Check if a new value has been written in the structure variable copy it to the persistent variable*) IF NOT (iq_stVCN.rUpperLimit = rUpperLimit) THEN rUpperLimit := iq_stVCN.rUpperLimit; //fbWritePersistentData(NETID:='', PORT:=851, START:=TRUE, TMOUT:=T#1s ); ELSE // fbWritePersistentData( START:=FALSE); END_IF; END_ACTION METHOD M_SetThrottle : BOOL VAR_INPUT rUpperLimit : REAL; END_VAR iq_stVCN.rUpperLimit := LIMIT(0, rUpperLimit, 100); END_METHOD METHOD M_ValveControl : BOOL VAR_INPUT state:E_VCN; // Close, Open, Pressure, Manual END_VAR iq_stVCN.eValveControl := state; END_METHOD FB_VGP ^^^^^^ :: (* This function implements the Basic functions for the Vat Motorized valve*) {attribute 'no_check'} FUNCTION_BLOCK FB_VGP VAR_INPUT i_xExtIlkOK : BOOL; //External Interlock, SET to TRUE if not used i_xOpenIlkOK: BOOL; //Interlock Bit that allows the valve to open i_xCloseIlkOK: BOOL; //Interlock Bit that allows the valve to Close i_ReqPos : REAL; //Requested position arrTable : ARRAY[1..14,1..2] OF FLOAT; END_VAR VAR_OUTPUT {attribute 'pytmc' := ' pv: '} q_stVGP : ST_VGP; // valve structure END_VAR VAR_IN_OUT END_VAR VAR CONSTANT rUpperLimit : REAL:=100; //Percentage Upper limit on valve open rClosePosition : REAL:=0; // Encoder Min. Fully Closed rMaxDiffPressure: REAL:= 22.5; //Torr END_VAR VAR rOpenPosition: REAL:=1680; // Encoder MAX. Fully Open rTargetPosition : REAL; rTargetVelocity: REAL:=30; rHomingVelocity: REAL:=10; rHomingDistance: REAL:=-20;//every 150 is 10% , 1% is 14.975 rOldTargetPosition: REAL; rHyst:REAL :=10; // /// axis reference data structure Axis: AXIS_REF; // InfoData_State AT %I*: UINT ; // Axis MC functions fbPowerAxis: MC_Power; /// debug function block output data PowerAxisOut: ST_McOutputs; fbMoveAxisABS: MC_MoveAbsolute; /// debug function block output data MoveAbsoluteOut: ST_McOutputs; fbMoveAxisABS2: MC_MoveAbsolute; /// debug function block output data MoveAbsoluteOut2: ST_McOutputs; fbReset: MC_Reset; /// debug function block output data ResetOut: ST_McOutputs; MoveAxisREL: MC_MoveAbsolute; MoveRelativeOut: ST_McOutputs; rOverride: LREAL := 100; fbHalt: MC_Halt; // Homing Functions bGo:BOOL := FALSE; //to execute motion bHome:BOOL :=FALSE; // should be set to true bEnable:Bool; //to be removed fbMoveRel: MC_MoveRelative; fbSetPosition: MC_SetPosition; fbWriteParameter: MC_WriteBoolParameter; HomeState: E_HomeState; // For Monitoring while Axis moving rPrevEncoderPosition : REAL; // interpolation bInit : BOOL := TRUE; eMode : E_CTRL_MODE; iCounter:INT; //CONTROL stCTRL_LIN_INTERPOLATION_PARAMS : ST_CTRL_LIN_INTERPOLATION_PARAMS; fbCTRL_LIN_INTERPOLATION : FB_CTRL_LIN_INTERPOLATION; arrTable_ENC : ARRAY[1..14,1..2] OF FLOAT; //Readdback stCTRL_LIN_INTERPOLATION_PARAMS_ENC : ST_CTRL_LIN_INTERPOLATION_PARAMS; fbCTRL_LIN_INTERPOLATION_ENC : FB_CTRL_LIN_INTERPOLATION; // Logger // For logging fbLogger : FB_LogMessage := (eSubsystem:=E_SubSystem.VACUUM); ePrevState : E_VCN; tErrorPresent : R_TRIG; tAction : R_TRIG; // Primary action of this device (OPN_DO, PUMP_RUN, etc.) rt_close :R_TRIG; rt_Open :R_TRIG; END_VAR /// Interpolation function initialization ACT_INIT(); // Interlocking q_stVGP.xIlkOK := i_xExtIlkOK; (*Checking which Control mode is selected*) IF i_xExtIlkOK AND NOT (q_stVGP.pv_xError) THEN IF q_stVGP.eValveControl = OpenValve THEN q_stVGP.rReqPosition := rUpperLimit; ELSIF q_stVGP.eValveControl = CloseValve THEN q_stVGP.rReqPosition := 0; ELSIF q_stVGP.eValveControl = ManualControl THEN q_stVGP.rReqPosition := LIMIT(0, q_stVGP.rReqPosition, rUpperLimit); ELSIF q_stVGP.eValveControl = PressureControl THEN q_stVGP.rReqPosition := LIMIT(0, i_ReqPos, rUpperLimit); END_IF ELSIF NOT i_xExtIlkOK THEN q_stVGP.rReqPosition := 0; q_stVGP.eValveControl := CloseValve;//CloseValve; END_IF rt_close (CLK:= q_stVGP.eValveControl = CloseValve); rt_Open (CLK:= q_stVGP.eValveControl = OpenValve); IF (rt_close.Q) OR (rt_Open.Q) THEN q_stVGP.pv_xGo_SW:=TRUE; END_IF //Check the Drive State IF (*(InfoData_State<>16#8) OR*) (q_stVGP.eState = ERROR) THEN q_stVGP.pv_xError:=TRUE; ELSE q_stVGP.pv_xError:=FALSE; // Call function to execute move // call motion function blocks??? END_IF IF (q_stVGP.pv_xABORT_SW ) THEN q_stVGP.pv_xABORT_SW := FALSE; q_stVGP.eState:= ABORT; HomeState:= H_READY; END_IF ACT_LIN_INTERPOLATION(); ACT_AXIS(); ACT_HOME(); ACT_MONITOR(); END_FUNCTION_BLOCK ACTION ACT_AXIS: //update the axis status AXIS(); q_stVGP.rEnoder_Position := LREAL_TO_REAL(Axis.NcToPlc.ActPos); // encoder position (*IF NOT (i_xExtIlkOK) THEN q_stVGP.eState := NEWTARGETPOSITION; END_IF*) //Homing STATE is missing // state machine for axis motion (* move axis using a state machine *) CASE q_stVGP.eState OF INIT : (* initialisation *) (* initialize all function blocks *) fbMoveAxisABS.Execute := FALSE; fbMoveAxisABS2.Execute := FALSE; fbReset.Execute := FALSE; fbHALT.Execute :=FALSE;// q_stVGP.eState := ENABLE; // Check homing first HomeState:= H_READY; ENABLE : fbPowerAxis.Enable := TRUE; fbPowerAxis.Enable_Positive := TRUE; fbPowerAxis.Enable_Negative := TRUE; IF fbPowerAxis.Status THEN q_stVGP.eState := READY; ELSIF fbPowerAxis.Error THEN q_stVGP.eState := ERROR; END_IF READY: // waiting for move command IF NOT fbPowerAxis.Status THEN q_stVGP.eState := ENABLE; ELSIF fbPowerAxis.Error THEN q_stVGP.eState := ERROR; END_IF IF (HomeState = H_READY) AND (q_stVGP.pv_xHome_SW) THEN HomeState:= H_INIT; q_stVGP.pv_xHome_SW:=false; q_stVGP.eState := HOME; ELSE q_stVGP.eState := READY; END_IF IF (q_stVGP.pv_xGo_SW) AND q_stVGP.pv_xHomed(* AND( rOldTargetPosition <> rTargetPosition) *) THEN q_stVGP.pv_xGo_SW := false; q_stVGP.eState := NEWTARGETPOSITION; rOldTargetPosition:= rTargetPosition; END_IF HOME: if (HomeState = H_DONE) THEN q_stVGP.eState := INIT; q_stVGP.pv_xHomed := TRUE; HomeState := H_READY; END_IF if (HomeState = H_ERROR) THEN q_stVGP.eState := ERROR; q_stVGP.pv_xHomed := FALSE; END_IF NEWTARGETPOSITION: fbMoveAxisABS.Position := rTargetPosition; fbMoveAxisABS.Velocity := rTargetVelocity; //fbMoveAxisABS.BufferMode := MC_BlendingNext; fbMoveAxisABS.Execute := TRUE; IF fbMoveAxisABS.Active THEN (* axis is executing job but is not yet finished *) fbMoveAxisABS.Execute := FALSE; (* leave this state and buffer a second command *) q_stVGP.eState := MOVING; ElSIF fbMoveAxisABS.Done THEN fbMoveAxisABS.Execute := FALSE; q_stVGP.eState := READY; ELSIF fbMoveAxisABS.CommandAborted OR fbMoveAxisABS.Error THEN q_stVGP.eState := ERROR; END_IF MOVING:// IF fbMoveAxisABS.CommandAborted OR fbMoveAxisABS.Error THEN q_stVGP.eState := ERROR; END_IF IF NOT ( Axis.Status.Moving) OR (fbMoveAxisABS.Done) THEN //(fbMoveAxisABS.Done) AND (fbMoveAxisABS2.Done) THEN q_stVGP.eState := READY; END_IF HALT: fbHALT.Execute :=TRUE; IF Axis.Status.Error THEN q_stVGP.eState := RESET; (* axis error requires reset *) ELSE q_stVGP.eState := INIT; (* function block errors don't need a reset *) END_IF ERROR : IF HomeState = H_READY THEN q_stVGP.eState := RESET; ELSE q_stVGP.eState := HOME; END_IF RESET : //fbReset.Execute := TRUE; IF fbReset.Done THEN q_stVGP.eState :=INIT; // HomeState := H_READY; ELSIF fbReset.Error THEN q_stVGP.eState := ERROR; (* keep trying to reset*) END_IF ABORT: fbMoveAxisABS.Execute := FALSE; fbMoveAxisABS2.Execute := FALSE; fbReset.Execute := FALSE; (* save target position*) rOldTargetPosition := q_stVGP.i_iPosition; fbHALT.Execute :=FALSE; fbPowerAxis.Enable := FALSE; fbPowerAxis.Enable_Positive := FALSE; fbPowerAxis.Enable_Negative := FALSE; q_stVGP.eState := ENABLE; // Check homing first END_CASE /// Motion Function Blocks (* AXIS POWER*) fbPowerAxis( Axis:= Axis, Enable:= , Enable_Positive:= i_xOpenIlkOK, Enable_Negative:= , Override:= rOverride, BufferMode:= , Options:= , Status=> , Busy=> PowerAxisOut.Busy , Active=> PowerAxisOut.Active , Error=> PowerAxisOut.Error, ErrorID=> PowerAxisOut.ErrorID); (* AXIS MOVE ABSOLUTE*) fbMoveAxisABS( Axis:= Axis , Execute:= , Position:= , Velocity:= , Acceleration:= , Deceleration:= , Jerk:= , BufferMode:= MC_BlendingNext , Options:= , Done=>MoveAbsoluteOut.Done, Busy=> MoveAbsoluteOut.Busy, Active=> MoveAbsoluteOut.Active, CommandAborted=> MoveAbsoluteOut.CommandAborted , Error=> MoveAbsoluteOut.Error, ErrorID=> MoveAbsoluteOut.ErrorID); (* AXIS MOVE ABSOLUTE*) fbMoveAxisABS2( Axis:= Axis , Execute:= , Position:= , Velocity:= , Acceleration:= , Deceleration:= , Jerk:= , BufferMode:= MC_BlendingNext , Options:= , Done=>MoveAbsoluteOut2.Done, Busy=> MoveAbsoluteOut2.Busy, Active=> MoveAbsoluteOut2.Active, CommandAborted=> MoveAbsoluteOut2.CommandAborted , Error=> MoveAbsoluteOut2.Error, ErrorID=> MoveAbsoluteOut2.ErrorID); (*AXIS RESET*) fbReset( Axis:= Axis, Execute:= This^.q_stVGP.pv_xReset_SW , Done=>ResetOut.Done , Busy=>ResetOut.Busy , Error=> ResetOut.Error, ErrorID=> ResetOut.ErrorID); (*HALT*) fbHalt( Axis:= Axis, Execute:= , Deceleration:= , Jerk:= , BufferMode:= MC_BlendingNext , Options:= , Done=> , Busy=> , Active=> , CommandAborted=> , Error=> , ErrorID=> ); /// ERROR IF Axis.Status.Error THEN q_stVGP.eState := ERROR; END_IF; // Error Handling if( fbPowerAxis.Error and fbPowerAxis.Active ) then This^.q_stVGP.pv_xError:= fbPowerAxis.Error; This^.q_stVGP.nErrorID:= fbPowerAxis.ErrorID; END_IF if( fbMoveAxisABS.Error and fbMoveAxisABS.Active ) then This^.q_stVGP.pv_xError:= fbMoveAxisABS.Error; This^.q_stVGP.nErrorID:= fbMoveAxisABS.ErrorID; END_IF IF This^.q_stVGP.pv_xReset_SW THEN This^.q_stVGP.pv_xReset_SW:=FALSE; END_IF (*Convert nErrorID to string*) This^.q_stVGP.sErrorMessage:=WORD_TO_HEXSTR(in:=TO_WORD(This^.q_stVGP.nErrorID) , iPrecision:= 4, bLoCase:=0 ); This^.q_stVGP.xBusy := (NOT(q_stVGP.eState = READY) AND (HomeState = H_READY)); END_ACTION ACTION ACT_HOME: CASE HomeState OF H_READY: fbSetPosition.Execute := FALSE; fbWriteParameter.Execute := FALSE; fbMoveRel.Execute := FALSE; H_INIT: HomeState:=H_RESET_LL; H_RESET_LL: // disable soft limits in order to be able to move the drive fbWriteParameter.ParameterNumber := MC_AxisParameter.EnableLimitNeg;//EnableLimitPos;// .EnableLimitNeg; fbWriteParameter.Value := FALSE; fbWriteParameter.Execute := TRUE; if (fbWriteParameter.Done) THEN fbWriteParameter.Execute := FALSE; HomeState:= H_RESET_HL; END_IF H_RESET_HL: // disable soft limits in order to be able to move the drive fbWriteParameter.ParameterNumber := MC_AxisParameter.EnableLimitPos; fbWriteParameter.Value := FALSE; fbWriteParameter.Execute := TRUE; if (fbWriteParameter.Done) THEN fbWriteParameter.Execute := FALSE; HomeState:= H_ENABLE; END_IF H_ENABLE: // Make Sure drive is enabled fbPowerAxis.Enable := TRUE; fbPowerAxis.Enable_Positive := TRUE; fbPowerAxis.Enable_Negative := TRUE; IF fbPowerAxis.Status THEN HomeState:= H_MOVING; ELSIF fbPowerAxis.Error THEN HomeState := H_ERROR; END_IF H_MOVING: fbMoveRel.Execute := TRUE; IF fbMoveRel.Active THEN (* axis is executing job but is not yet finished *) fbMoveRel.Execute := FALSE; (* leave this state and buffer a second command *) HomeState := H_MOVING2; ElSIF fbMoveRel.Done THEN fbMoveRel.Execute := FALSE; HomeState := H_MOVING;//2? ELSIF fbMoveRel.CommandAborted OR fbMoveRel.Error THEN fbMoveRel.Execute := FALSE; HomeState := H_CHECK; END_IF H_MOVING2: IF fbMoveRel.CommandAborted OR fbMoveRel.Error THEN HomeState := H_CHECK; END_IF IF NOT ( Axis.Status.Moving) OR (fbMoveRel.Done) THEN //(fbMoveAxisABS.Done) AND (fbMoveAxisABS2.Done) THEN HomeState := H_MOVING; fbMoveRel.Execute := FALSE; END_IF H_CHECK: //Check position lag monitoring error if (Axis.Status.ErrorID = 16#00004550)THEN This^.q_stVGP.pv_xReset_SW := TRUE; HomeState := H_RESET; ELSE HomeState := H_ERROR; END_IF H_RESET: IF fbReset.Done THEN This^.q_stVGP.pv_xReset_SW := FALSE; HomeState := H_SET_POS; END_IF H_SET_POS: // Set Current Position fbSetPosition.Position := 0; fbSetPosition.Execute := TRUE; IF ( fbSetPosition.Done ) THEN fbSetPosition.Execute := FALSE; HomeState:= H_WRITE_LL; ELSIF (fbSetPosition.Error) THEN HomeState := H_ERROR; END_IF H_WRITE_LL: // Re Enable the Soft limits fbWriteParameter.ParameterNumber := MC_AxisParameter.AxisEnMinSoftPosLimit;//AxisEnMaxSoftPosLimit;// .AxisEnMinSoftPosLimit; fbWriteParameter.Value := TRUE; fbWriteParameter.Execute := TRUE; if (fbWriteParameter.Done) THEN fbWriteParameter.Execute := FALSE; HomeState:= H_WRITE_HL; END_IF H_WRITE_HL: // Re Enable the Soft limits fbWriteParameter.ParameterNumber := MC_AxisParameter.AxisEnMaxSoftPosLimit; fbWriteParameter.Value := TRUE; fbWriteParameter.Execute := TRUE; if (fbWriteParameter.Done) THEN fbWriteParameter.Execute := FALSE; HomeState:= H_DONE; END_IF H_ERROR: //taken care of in the axis motion state machine H_DONE: //taken care of in the axis motion state machine END_CASE // Move backward to fully closed fbMoveRel( Axis:= Axis , Execute:= , Distance:= rHomingDistance , Velocity:= rHomingVelocity, Acceleration:= , Deceleration:= , Jerk:= , BufferMode:= MC_BlendingNext, Options:= , Done=> , Busy=> , Active=> , CommandAborted=> , Error=> , ErrorID=> ); // Set Encoder Position fbSetPosition( Axis:= Axis , Execute:= , Position:= 0 , Mode:= FALSE, //Absolute Options:= , Done=> , Busy=> , Error=> , ErrorID=> ); // Write Parameters fbWriteParameter( Axis:= Axis , Execute:= , ParameterNumber:= , Value:= , Done=> , Busy=> , Error=> , ErrorID=> ); If ( fbWriteParameter.Error) OR (fbSetPosition.Error)(* OR (fbMoveRel.Error) *)THEN HomeState:= H_ERROR; q_stVGP.eState := ERROR; END_IF END_ACTION ACTION ACT_INIT: {attribute no_check} IF bInit THEN (* (* init array with the interpolation points *) (* fIn | fOut *) arrTable[1,1] := 0; arrTable[1,2] := 0; arrTable[2,1] := 5; arrTable[2,2] := 135; arrTable[3,1] := 10; arrTable[3,2] := 245; arrTable[4,1] := 20; arrTable[4,2] := 405; arrTable[5,1] := 30; arrTable[5,2] := 535; arrTable[6,1] := 40; arrTable[6,2] := 689; arrTable[7,1] := 50; arrTable[7,2] := 830; arrTable[8,1] := 60; arrTable[8,2] := 960; arrTable[9,1] := 70; arrTable[9,2] := 1095; arrTable[10,1] := 80; arrTable[10,2] := 1225; arrTable[11,1] := 90; arrTable[11,2] := 1415; arrTable[12,1] := 95; arrTable[12,2] := 1495; arrTable[13,1] := 98; arrTable[13,2] := 1559; arrTable[14,1] := 100; arrTable[14,2] := 1645; *) (* init parameter struct *) stCTRL_LIN_INTERPOLATION_PARAMS.tCtrlCycleTime := T#10ms; stCTRL_LIN_INTERPOLATION_PARAMS.tTaskCycleTime := T#10ms; stCTRL_LIN_INTERPOLATION_PARAMS.nDataTable_NumberOfRows := INT_TO_UINT(14); (* set the addresses *) stCTRL_LIN_INTERPOLATION_PARAMS.pDataTable_ADR := ADR(arrTable); stCTRL_LIN_INTERPOLATION_PARAMS.nDataTable_SIZEOF := SIZEOF(arrTable); (* set the mode to ACTIVE --> normal operation *) eMode := eCTRL_MODE_ACTIVE; (* init array with the interpolation points *) (* fIn | fOut *) FOR iCounter:=1 TO 14 BY 1 DO arrTable_ENC[iCounter,1] := arrTable[iCounter,2]; arrTable_ENC[iCounter,2] := arrTable[iCounter,1]; END_FOR; (* arrTable_ENC[1,1] := 0; arrTable_ENC[1,2] := 0; arrTable_ENC[2,1] := 135; arrTable_ENC[2,2] := 5; arrTable_ENC[3,1] := 245; arrTable_ENC[3,2] := 10; arrTable_ENC[4,1] := 405; arrTable_ENC[4,2] := 20; arrTable_ENC[5,1] := 535; arrTable_ENC[5,2] := 30; arrTable_ENC[6,1] := 689; arrTable_ENC[6,2] := 40; arrTable_ENC[7,1] := 830; arrTable_ENC[7,2] := 50; arrTable_ENC[8,1] := 960; arrTable_ENC[8,2] := 60; arrTable_ENC[9,1] := 1095; arrTable_ENC[9,2] := 70; arrTable_ENC[10,1] := 1225; arrTable_ENC[10,2] := 80; arrTable_ENC[11,1] := 1415; arrTable_ENC[11,2] := 90; arrTable_ENC[12,1] := 1495; arrTable_ENC[12,2] := 95; arrTable_ENC[13,1] := 1559; arrTable_ENC[13,2] := 98; arrTable_ENC[14,1] := 1645; arrTable_ENC[14,2] := 100;*) (* init parameter struct *) stCTRL_LIN_INTERPOLATION_PARAMS_ENC.tCtrlCycleTime := T#10ms; stCTRL_LIN_INTERPOLATION_PARAMS_ENC.tTaskCycleTime := T#10ms; stCTRL_LIN_INTERPOLATION_PARAMS_ENC.nDataTable_NumberOfRows := INT_TO_UINT(14); (* set the addresses *) stCTRL_LIN_INTERPOLATION_PARAMS_ENC.pDataTable_ADR := ADR(arrTable_ENC); stCTRL_LIN_INTERPOLATION_PARAMS_ENC.nDataTable_SIZEOF := SIZEOF(arrTable_ENC); (* reset the init flag *) bInit := FALSE; END_IF; END_ACTION ACTION ACT_LIN_INTERPOLATION: {attribute 'no_check'} fbCTRL_LIN_INTERPOLATION( fIn:= q_stVGP.rReqPosition , fManValue:= 0, bExtrapolate:= , eMode:= eMode, fOut=> , bInIsGreaterThanMaxElement=> , bInIsLessThanMinElement=> , eState=> , eErrorId=> , bError=> , stParams:= stCTRL_LIN_INTERPOLATION_PARAMS ); // Target position Calculation rTargetPosition := LREAL_TO_REAL(fbCTRL_LIN_INTERPOLATION.fOut); //rTargetPosition := LIMIT(rClosePosition, rTargetPosition, rOpenPosition); fbCTRL_LIN_INTERPOLATION_ENC( fIn:= Axis.NcToPlc.ActPos , fManValue:= 0, bExtrapolate:= , eMode:= eMode, fOut=> , bInIsGreaterThanMaxElement=> , bInIsLessThanMinElement=> , eState=> , eErrorId=> , bError=> , stParams:= stCTRL_LIN_INTERPOLATION_PARAMS_ENC ); q_stVGP.i_iPosition := LREAL_TO_REAL(fbCTRL_LIN_INTERPOLATION_ENC.fOut); END_ACTION ACTION ACT_MONITOR: IF (This^.q_stVGP.xBusy) THEN rPrevEncoderPosition:= This^.q_stVGP.rEnoder_Position; ELSIF NOT((rPrevEncoderPosition < This^.q_stVGP.rEnoder_Position +rHyst) AND (rPrevEncoderPosition > This^.q_stVGP.rEnoder_Position -rHyst)) AND NOT( q_stVGP.eState =HOME) AND NOT( q_stVGP.eState =ERROR) THEN q_stVGP.eState := ERROR; q_stVGP.pv_xHomed := FALSE; This^.q_stVGP.pv_xError := TRUE; This^.q_stVGP.sErrorMessage := 'Encoder Position Error'; END_IF tErrorPresent(CLK:=q_stVGP.pv_xError); IF tErrorPresent.Q THEN fbLogger(sMsg:=q_stVGP.sErrorMessage, eSevr:=TcEventSeverity.Error); END_IF // Log valve motion tAction(CLK:= q_stVGP.pv_xGo_SW); IF tAction.Q THEN fbLogger(sMsg:='Valve commanded to move', eSevr:=TcEventSeverity.Info); END_IF IF ePrevState <> q_stVGP.eValveControl THEN CASE q_stVGP.eValveControl OF CloseValve: fbLogger(sMsg:='Valve set to Close.', eSevr:=TcEventSeverity.Info); OpenValve: fbLogger(sMsg:='Valve set to Open.', eSevr:=TcEventSeverity.Info); PressureControl: fbLogger(sMsg:='Valve set to pressure control mode.', eSevr:=TcEventSeverity.Info); ManualControl: fbLogger(sMsg:='Valve set to manual control mode.', eSevr:=TcEventSeverity.Info); END_CASE ePrevState := q_stVGP.eValveControl; END_IF END_ACTION METHOD ConfigEncoder : BOOL VAR_INPUT EncoderMax: REAl; // Maximum encoder reading from fully closed to fully open invert: Bool; // Invert Encoder Counting Direction END_VAR VAR fbWriteParameter1: MC_WriteBoolParameter; END_VAR rOpenPosition := EncoderMax; // fEncScaleFactor - AxisEncoderScalingFactor // bEncIsInverse - if (invert) THEN fbWriteParameter1.ParameterNumber := MC_AxisParameter.AxisEncoderDirectionInverse; fbWriteParameter1.Value := True; END_IF // Write Parameters fbWriteParameter1( Axis:= Axis , Execute:= , ParameterNumber:= , Value:= , Done=> , Busy=> , Error=> , ErrorID=> ); END_METHOD METHOD M_INIT : BOOL VAR_INPUT arrTable : ARRAY[1..14,1..2] OF FLOAT; arrTable_ENC : ARRAY[1..14,1..2] OF FLOAT; END_VAR (* init array with the interpolation points *) (* fIn | fOut *) arrTable[1,1] := 0; arrTable[1,2] := 0; arrTable[2,1] := 5; arrTable[2,2] := 135; arrTable[3,1] := 10; arrTable[3,2] := 245; arrTable[4,1] := 20; arrTable[4,2] := 405; arrTable[5,1] := 30; arrTable[5,2] := 535; arrTable[6,1] := 40; arrTable[6,2] := 689; arrTable[7,1] := 50; arrTable[7,2] := 830; arrTable[8,1] := 60; arrTable[8,2] := 960; arrTable[9,1] := 70; arrTable[9,2] := 1095; arrTable[10,1] := 80; arrTable[10,2] := 1225; arrTable[11,1] := 90; arrTable[11,2] := 1415; arrTable[12,1] := 95; arrTable[12,2] := 1495; arrTable[13,1] := 98; arrTable[13,2] := 1559; arrTable[14,1] := 100; arrTable[14,2] := 1645; (* init parameter struct *) stCTRL_LIN_INTERPOLATION_PARAMS.tCtrlCycleTime := T#10ms; stCTRL_LIN_INTERPOLATION_PARAMS.tTaskCycleTime := T#10ms; stCTRL_LIN_INTERPOLATION_PARAMS.nDataTable_NumberOfRows := INT_TO_UINT(14); (* set the addresses *) stCTRL_LIN_INTERPOLATION_PARAMS.pDataTable_ADR := ADR(arrTable); stCTRL_LIN_INTERPOLATION_PARAMS.nDataTable_SIZEOF := SIZEOF(arrTable); (* set the mode to ACTIVE --> normal operation *) eMode := eCTRL_MODE_ACTIVE; (* init array with the interpolation points *) (* fIn | fOut *) arrTable_ENC[1,1] := 0; arrTable_ENC[1,2] := 0; arrTable_ENC[2,1] := 135; arrTable_ENC[2,2] := 5; arrTable_ENC[3,1] := 245; arrTable_ENC[3,2] := 10; arrTable_ENC[4,1] := 405; arrTable_ENC[4,2] := 20; arrTable_ENC[5,1] := 535; arrTable_ENC[5,2] := 30; arrTable_ENC[6,1] := 689; arrTable_ENC[6,2] := 40; arrTable_ENC[7,1] := 830; arrTable_ENC[7,2] := 50; arrTable_ENC[8,1] := 960; arrTable_ENC[8,2] := 60; arrTable_ENC[9,1] := 1095; arrTable_ENC[9,2] := 70; arrTable_ENC[10,1] := 1225; arrTable_ENC[10,2] := 80; arrTable_ENC[11,1] := 1415; arrTable_ENC[11,2] := 90; arrTable_ENC[12,1] := 1495; arrTable_ENC[12,2] := 95; arrTable_ENC[13,1] := 1559; arrTable_ENC[13,2] := 98; arrTable_ENC[14,1] := 1645; arrTable_ENC[14,2] := 100; (* init parameter struct *) stCTRL_LIN_INTERPOLATION_PARAMS_ENC.tCtrlCycleTime := T#10ms; stCTRL_LIN_INTERPOLATION_PARAMS_ENC.tTaskCycleTime := T#10ms; stCTRL_LIN_INTERPOLATION_PARAMS_ENC.nDataTable_NumberOfRows := INT_TO_UINT(14); (* set the addresses *) stCTRL_LIN_INTERPOLATION_PARAMS_ENC.pDataTable_ADR := ADR(arrTable_ENC); stCTRL_LIN_INTERPOLATION_PARAMS_ENC.nDataTable_SIZEOF := SIZEOF(arrTable_ENC); END_METHOD METHOD M_SetGoSw : BOOL VAR_INPUT bGo:BOOL; END_VAR q_stVGP.pv_xGo_SW:=bGo; END_METHOD METHOD M_ValveControl : BOOL VAR_INPUT state:E_VCN; // Close, Open, Pressure, Manual END_VAR q_stVGP.eValveControl := state; END_METHOD METHOD PUBLIC SetEncoderMax : BOOL VAR_INPUT EncoderMax: REAl; END_VAR rOpenPosition := EncoderMax; END_METHOD Related: * `E_HomeState`_ * `ST_VGP`_ PRG_1_PlcTask ^^^^^^^^^^^^^ :: PROGRAM PRG_1_PlcTask VAR bDebug : Bool := FALSE; bMotionTest : Bool := FALSE; fb_ADS_WATCHDOG:FB_ADS_WATCHDOG; sVarName : STRING:='GVL_VAC_INTF.n_AT1K0_VAC_counter'; END_VAR //GVL_VAC_INTF.n_AT1K0_VAC_counter fb_ADS_WATCHDOG(sNetId:='172.21.92.61.1.1' , nPort:=851 , sVarName:=sVarName,bError=> ); (*Ethercat Diagnostics*) DIAGNOSTICS(); // Vacuum and differential pumping PRG_GATT(); if (NOT bDebug)Then // Motorised valve PRG_VGP(); END_IF if (bMotionTest)Then // Functionblock for PTP motion between different appertures PRG_Motors_Test(); ELSE PRG_Motion(); END_IF PRG_ILK(); //PMPS PRG_PMPS(); PRG_GasSelection(); PRG_Transmission(); // Injector PRG_INJ(); //Logger fbLogHandler(); fbEcatDiagWrapper(); END_PROGRAM Related: * `DIAGNOSTICS`_ * `PRG_GATT`_ * `PRG_GasSelection`_ * `PRG_ILK`_ * `PRG_INJ`_ * `PRG_Motion`_ * `PRG_Motors_Test`_ * `PRG_PMPS`_ * `PRG_Transmission`_ * `PRG_VGP`_ PRG_GasSelection ^^^^^^^^^^^^^^^^ :: PROGRAM PRG_GasSelection VAR N2LowerEdge: REAL := 300; N2UpperEdge: REAL := 450; rDelta: REAL :=20; ArEdge:REAL:=2300; END_VAR (*Gas Selection*) IF(VVC_71.M_IsOpen()) THEN SelectedGas := E_GasType.Argon; ELSIF (VVC_72.M_IsOpen()) THEN SelectedGas := E_GasType.Nitrogen; END_IF IF (xPMPSMode) AND (bChangeGas) THEN IF(rPhotonEnergy >=N2LowerEdge-rDelta) AND (rPhotonEnergy <=N2UpperEdge-rDelta)(* AND NOT (SelectedGas = E_GasType.Argon)*) THEN //Block N2 VVC_72.M_Set_OPN_SW (false); IF VVC_72.M_IsClosed() THEN VVC_71.M_Set_OPN_SW (TRUE); bChangeGas := FALSE; fbLogger(sMsg:='AT1K0 switched to Ar', eSevr:=TcEventSeverity.Verbose); END_IF; ELSIF ((rPhotonEnergy <= 220) OR (rPhotonEnergy >=2300)) (*AND NOT (SelectedGas = E_GasType.Nitrogen)*) THEN //Block Ar VVC_71.M_Set_OPN_SW (false); IF VVC_71.M_IsClosed() THEN VVC_72.M_Set_OPN_SW (TRUE); bChangeGas := FALSE; fbLogger(sMsg:='AT1K0 switched to N2', eSevr:=TcEventSeverity.Verbose); END_IF; ELSE VVC_72.M_Set_OPN_SW (TRUE); bChangeGas := FALSE; //fbLogger(sMsg:='AT1K0 switched to N2', eSevr:=TcEventSeverity.Verbose); END_IF ELSE bChangeGas := FALSE; END_IF END_PROGRAM Related: * `E_GasType`_ PRG_GATT ^^^^^^^^ :: PROGRAM PRG_GATT VAR timer:TON; vvcTimer:TON; PG: ST_VG; rPRESS : REAL := 0.001; rPRESS_11 : REAL := 1; fb_ADS_WATCHDOG:FB_ADS_WATCHDOG; rTrig_11: R_TRIG; END_VAR // this function block writes the watchdog bit to the remote PLC reading the treaty valves and/or gauge fb_ADS_WATCHDOG(sNetId:='172.21.88.32.1.1' , nPort:=851 , sVarName:='GVL_Devices.iWatchdog',bError=> ); // GAUGES // MKS275 Gauges fb_AT1K0_GAS_GPI_111(PG=>); fb_AT1K0_GAS_GPI_121(PG=>); fb_AT1K0_GAS_GPI_141(PG=>); // FB_MKS317 fb_AT1K0_GAS_GPI_10(PG=>); fb_AT1K0_GAS_GPI_20(PG=>); fb_AT1K0_GAS_GPI_11(PG=>); fb_AT1K0_GAS_GPI_12(PG=>); fb_AT1K0_GAS_GPI_30(PG=>); fb_AT1K0_GAS_GPI_40(PG=>); fb_AT1K0_GAS_GPI_50(PG=>); fb_AT1K0_GAS_GPI_51(PG=>); fb_AT1K0_GAS_GPI_60(PG=>); fb_AT1K0_GAS_GPI_80(PG=>); fb_AT1K0_GAS_GPI_90(PG=>); fb_AT1K0_GAS_GPI_100(PG=>); fb_AT1K0_GAS_GPI_110(PG=>); fb_AT1K0_GAS_GPI_120(PG=>); fb_AT1K0_GAS_GPI_130(PG=>); fb_AT1K0_GAS_GPI_140(PG=>); // FB_MKS422 fb_AT1K0_GAS_GCC_10(PG := fb_AT1K0_GAS_GPI_10.PG); fb_AT1K0_GAS_GCC_20(PG := fb_AT1K0_GAS_GPI_20.PG); fb_AT1K0_GAS_GCC_30(PG := fb_AT1K0_GAS_GPI_30.PG); fb_AT1K0_GAS_GCC_40(PG := fb_AT1K0_GAS_GPI_40.PG); fb_AT1K0_GAS_GCC_50(PG := fb_AT1K0_GAS_GPI_50.PG); fb_AT1K0_GAS_GCC_60(PG := fb_AT1K0_GAS_GPI_60.PG); fb_AT1K0_GAS_GCC_80(PG := fb_AT1K0_GAS_GPI_80.PG); fb_AT1K0_GAS_GCC_90(PG := fb_AT1K0_GAS_GPI_90.PG); fb_AT1K0_GAS_GCC_100(PG := fb_AT1K0_GAS_GPI_100.PG); fb_AT1K0_GAS_GCC_110(PG := fb_AT1K0_GAS_GPI_110.PG); fb_AT1K0_GAS_GCC_120(PG := fb_AT1K0_GAS_GPI_120.PG); fb_AT1K0_GAS_GCC_130(PG := fb_AT1K0_GAS_GPI_130.PG); fb_AT1K0_GAS_GCC_140(PG := fb_AT1K0_GAS_GPI_140.PG); //VALVES // Pump Isolation Valves // FB_VRC //EBD Side //TURBO fb_AT1K0_GAS_VRC_10(i_xExtILK_OK := F_TurboGateValve_ILK(fb_AT1K0_GAS_PTM_10.iq_stPtm,fb_AT1K0_GAS_GPI_10.PG)AND fb_AT1K0_GAS_PTM_10.iq_stPtm.eState = pumpRUNNING, i_xOverrideMode := xSystemOverrideMode); fb_AT1K0_GAS_VRC_20(i_xExtILK_OK := F_TurboGateValve_ILK(fb_AT1K0_GAS_PTM_20.iq_stPtm,fb_AT1K0_GAS_GPI_20.PG)AND fb_AT1K0_GAS_PTM_20.iq_stPtm.eState = pumpRUNNING, i_xOverrideMode := xSystemOverrideMode); fb_AT1K0_GAS_VRC_30(i_xExtILK_OK := F_TurboGateValve_ILK(fb_AT1K0_GAS_PTM_30.iq_stPtm,fb_AT1K0_GAS_GPI_30.PG)AND fb_AT1K0_GAS_PTM_30.iq_stPtm.eState = pumpRUNNING, i_xOverrideMode := xSystemOverrideMode); fb_AT1K0_GAS_VRC_40(i_xExtILK_OK := F_TurboGateValve_ILK(fb_AT1K0_GAS_PTM_40.iq_stPtm,fb_AT1K0_GAS_GPI_40.PG)AND fb_AT1K0_GAS_PTM_40.iq_stPtm.eState = pumpRUNNING, i_xOverrideMode := xSystemOverrideMode); // Auto open the VRC when pressure if ok rTrig_11(CLK := ( fb_AT1K0_GAS_GPI_11.PG.xPRESS_OK AND fb_AT1K0_GAS_GPI_11.PG.rPRESS < 0.01)); IF (rTrig_11.Q) THEN fb_AT1K0_GAS_VRC_11.M_Set_OPN_SW (TRUE); END_IF fb_AT1K0_GAS_VRC_11(i_xExtILK_OK := (fb_AT1K0_GAS_GPI_11.PG.xPRESS_OK AND fb_AT1K0_GAS_GPI_11.PG.rPRESS < rPRESS_11) , i_xOverrideMode := xSystemOverrideMode); //EBD fb_AT1K0_GAS_VRC_50(i_xExtILK_OK := F_VRC_DIODE_ILK_OK(fb_AT1K0_GAS_GPI_50.PG,fb_AT1K0_GAS_GPI_51.PG), i_xOverrideMode := xSystemOverrideMode); fb_AT1K0_GAS_VRC_60(i_xExtILK_OK := F_VRC_DIODE_ILK_OK(fb_AT1K0_GAS_GPI_60.PG,fb_AT1K0_GAS_GPI_51.PG), i_xOverrideMode := xSystemOverrideMode); //FEE Side PG.xPRESS_OK := TRUE; PG.rPRESS := rPRESS; fb_AT1K0_GAS_VRC_70(i_xExtILK_OK := fb_AT1K0_GAS_PMF_90.stPump.i_xMPStatus AND (F_VRC_DIODE_ILK_OK(fb_AT1K0_GAS_GPI_80.PG,PG) AND VVC_71.M_IsClosed() AND VVC_72.M_IsClosed()), i_xOverrideMode := xSystemOverrideMode); fb_AT1K0_GAS_VRC_90(i_xExtILK_OK := fb_AT1K0_GAS_PMF_90.stPump.i_xMPStatus AND (F_VRC_DIODE_ILK_OK(fb_AT1K0_GAS_GPI_90.PG,PG)), i_xOverrideMode := xSystemOverrideMode); fb_AT1K0_GAS_VRC_100(i_xExtILK_OK := fb_AT1K0_GAS_PMF_100.stPump.i_xMPStatus AND (F_VRC_DIODE_ILK_OK(fb_AT1K0_GAS_GPI_100.PG,PG)), i_xOverrideMode := xSystemOverrideMode); //TURBO fb_AT1K0_GAS_VRC_110(i_xExtILK_OK := F_TurboGateValve_ILK(fb_AT1K0_GAS_PTM_110.iq_stPtm,fb_AT1K0_GAS_GPI_110.PG) AND fb_AT1K0_GAS_PTM_110.iq_stPtm.eState = pumpRUNNING , i_xOverrideMode := xSystemOverrideMode); fb_AT1K0_GAS_VRC_120(i_xExtILK_OK := F_TurboGateValve_ILK(fb_AT1K0_GAS_PTM_120.iq_stPtm,fb_AT1K0_GAS_GPI_120.PG) AND fb_AT1K0_GAS_PTM_120.iq_stPtm.eState = pumpRUNNING, i_xOverrideMode := xSystemOverrideMode); fb_AT1K0_GAS_VRC_130(i_xExtILK_OK := F_TurboGateValve_ILK(fb_AT1K0_GAS_PTM_130.iq_stPtm,fb_AT1K0_GAS_GPI_130.PG) AND fb_AT1K0_GAS_PTM_130.iq_stPtm.eState = pumpRUNNING, i_xOverrideMode := xSystemOverrideMode); fb_AT1K0_GAS_VRC_140(i_xExtILK_OK := F_TurboGateValve_ILK(fb_AT1K0_GAS_PTM_140.iq_stPtm,fb_AT1K0_GAS_GPI_140.PG) AND fb_AT1K0_GAS_PTM_140.iq_stPtm.eState = pumpRUNNING, i_xOverrideMode := xSystemOverrideMode); //N2 valve //INL VCN, VGP and VRC_70 are closed. fb_AT1K0_GAS_VRC_80.i_xExtILK_OK := fb_AT1K0_GAS_VRC_90.iq_stValve.i_xClsLS AND VCN_70.iq_stVCN.rReqPosition <0.4 AND VVC_71.M_IsClosed() AND VVC_72.M_IsClosed() ; //AND VGP is closed; fb_AT1K0_GAS_VRC_80( i_xOverrideMode := xSystemOverrideMode); // Turbo Pumps // FB_PTM_Ebara_010M //EBD SIDE fb_AT1K0_GAS_PTM_10(i_xExtILKOk := F_TurboExtILKLogic_2(fb_AT1K0_GAS_PTM_10.iq_stPtm, fb_AT1K0_GAS_GPI_12.PG, fb_AT1K0_GAS_GPI_10.PG,fb_AT1K0_GAS_PMF_10.iq_stPFO));// AND fb_AT1K0_GAS_VRC_11.M_IsOpen() ); fb_AT1K0_GAS_PTM_20(i_xExtILKOk := F_TurboExtILKLogic_2(fb_AT1K0_GAS_PTM_20.iq_stPtm, fb_AT1K0_GAS_GPI_12.PG, fb_AT1K0_GAS_GPI_20.PG,fb_AT1K0_GAS_PMF_10.iq_stPFO));// AND fb_AT1K0_GAS_VRC_11.M_IsOpen() ); fb_AT1K0_GAS_PTM_30(i_xExtILKOk := F_TurboExtILKLogic_2(fb_AT1K0_GAS_PTM_30.iq_stPtm, fb_AT1K0_GAS_GPI_12.PG, fb_AT1K0_GAS_GPI_30.PG,fb_AT1K0_GAS_PMF_10.iq_stPFO));// AND fb_AT1K0_GAS_VRC_11.M_IsOpen() ); fb_AT1K0_GAS_PTM_40(i_xExtILKOk := F_TurboExtILKLogic_2(fb_AT1K0_GAS_PTM_40.iq_stPtm, fb_AT1K0_GAS_GPI_12.PG, fb_AT1K0_GAS_GPI_40.PG,fb_AT1K0_GAS_PMF_10.iq_stPFO));// AND fb_AT1K0_GAS_VRC_11.M_IsOpen() ); //FEE Side fb_AT1K0_GAS_PTM_110(i_xExtILKOk := F_TurboExtILKLogic_2(fb_AT1K0_GAS_PTM_110.iq_stPtm, fb_AT1K0_GAS_GPI_111.PG,fb_AT1K0_GAS_GPI_110.PG,fb_AT1K0_GAS_PMF_110.stPump)); fb_AT1K0_GAS_PTM_120(i_xExtILKOk := F_TurboExtILKLogic_2(fb_AT1K0_GAS_PTM_120.iq_stPtm, fb_AT1K0_GAS_GPI_121.PG, fb_AT1K0_GAS_GPI_120.PG,fb_AT1K0_GAS_PMF_120.stPump)); fb_AT1K0_GAS_PTM_130(i_xExtILKOk := F_TurboExtILKLogic_2(fb_AT1K0_GAS_PTM_130.iq_stPtm, fb_AT1K0_GAS_GPI_121.PG,fb_AT1K0_GAS_GPI_130.PG,fb_AT1K0_GAS_PMF_120.stPump)); fb_AT1K0_GAS_PTM_140(i_xExtILKOk := F_TurboExtILKLogic_2(fb_AT1K0_GAS_PTM_140.iq_stPtm, fb_AT1K0_GAS_GPI_141.PG,fb_AT1K0_GAS_GPI_140.PG,fb_AT1K0_GAS_PMF_140.stPump)); // Injector side fb_AT1K0_GAS_VVC_80.i_xExtILK_OK:= (fb_AT1K0_GAS_GPI_111.PG.rPRESS <= fb_AT1K0_GAS_PTM_80.iq_stPtm.rBackingPressureSP) AND NOT (fb_AT1K0_GAS_PTM_80.iq_stPtm.eState = pumpFAULT) AND (fb_AT1K0_GAS_PTM_80.iq_stPtm.eState = pumpRUNNING OR fb_AT1K0_GAS_PTM_80.iq_stPtm.eState = pumpSTARTING )AND (fb_AT1K0_GAS_PMF_110.stPump.eState = pumpRUNNING OR fb_AT1K0_GAS_PMF_110.stPump.eState = pumpSTARTING ); fb_AT1K0_GAS_VVC_80(i_xOverrideMode:= xSystemOverrideMode , iq_stValve=> ); IF (fb_AT1K0_GAS_PTM_80.iq_stPtm.eState = pumpRUNNING) AND fb_AT1K0_GAS_VVC_80.M_IsClosed() THEN if (timer.Q) THEN fb_AT1K0_GAS_PTM_80.i_xExtILKOk := fb_AT1K0_GAS_VVC_80.M_IsOpen() AND F_TurboExtILKLogic_2(fb_AT1K0_GAS_PTM_80.iq_stPtm, fb_AT1K0_GAS_GPI_111.PG,fb_AT1K0_GAS_GPI_80.PG,fb_AT1K0_GAS_PMF_110.stPump);//fb_AT1K0_GAS_PTM_80.i_xExtILKOk := FALSE; END_IF; ELSE fb_AT1K0_GAS_PTM_80.i_xExtILKOk := F_TurboExtILKLogic_2(fb_AT1K0_GAS_PTM_80.iq_stPtm, fb_AT1K0_GAS_GPI_111.PG,fb_AT1K0_GAS_GPI_80.PG,fb_AT1K0_GAS_PMF_110.stPump); END_IF fb_AT1K0_GAS_PTM_80(); timer(IN:= (fb_AT1K0_GAS_PTM_80.iq_stPtm.eState = pumpRUNNING), PT:=T#1S); //Rouging pumps // FB_EbaraDryPump //EBD SIDE fb_AT1K0_GAS_PMF_10(xExtIlk :=TRUE,TurboIsOn := TRUE); fb_AT1K0_GAS_PMF_60(xExtIlk :=TRUE,TurboIsOn := TRUE); //FEE SIDE fb_AT1K0_GAS_PMF_90(i_stBPGauge := fb_AT1K0_GAS_GPI_90.PG, i_xVlvOpn := TRUE, i_xExtIlkOK := TRUE); fb_AT1K0_GAS_PMF_100(i_stBPGauge := fb_AT1K0_GAS_GPI_100.PG, i_xVlvOpn := TRUE, i_xExtIlkOK := TRUE); fb_AT1K0_GAS_PMF_110(i_xExtIlkOK:= TRUE (*Interlock Timer on the Rough Valve*) , stPump=> ); fb_AT1K0_GAS_PMF_120(i_xExtIlkOK:= TRUE(*Interlock Timer on the Rough Valve*), stPump=> ); fb_AT1K0_GAS_PMF_140(i_xExtIlkOK:= TRUE(*Interlock Timer on the Rough Valve*), stPump=> ); if( fb_AT1K0_GAS_PMF_110.stPump.eState = pumpSTARTING ) OR ( fb_AT1K0_GAS_PMF_110.stPump.eState = pumpRUNNING ) THEN fb_AT1K0_GAS_VVC_110.M_Open(TRUE); END_IF if( fb_AT1K0_GAS_PMF_120.stPump.eState = pumpSTARTING ) OR ( fb_AT1K0_GAS_PMF_120.stPump.eState = pumpRUNNING ) THEN fb_AT1K0_GAS_VVC_120.M_Open(TRUE); END_IF if( fb_AT1K0_GAS_PMF_140.stPump.eState = pumpSTARTING ) OR ( fb_AT1K0_GAS_PMF_140.stPump.eState = pumpRUNNING ) THEN fb_AT1K0_GAS_VVC_140.M_Open(TRUE); END_IF fb_AT1K0_GAS_VVC_110(i_xExtILK_OK:= (fb_AT1K0_GAS_PMF_110.stPump.eState = pumpRUNNING OR fb_AT1K0_GAS_PMF_110.stPump.eState = pumpSTARTING ), i_xOverrideMode:= , iq_stValve=> ); fb_AT1K0_GAS_VVC_120(i_xExtILK_OK:= (fb_AT1K0_GAS_PMF_120.stPump.eState = pumpRUNNING OR fb_AT1K0_GAS_PMF_120.stPump.eState = pumpSTARTING ), i_xOverrideMode:= , iq_stValve=> ); fb_AT1K0_GAS_VVC_140(i_xExtILK_OK:= (fb_AT1K0_GAS_PMF_140.stPump.eState = pumpRUNNING OR fb_AT1K0_GAS_PMF_140.stPump.eState = pumpSTARTING ), i_xOverrideMode:= , iq_stValve=> ); END_PROGRAM Related: * `GVL_Devices`_ PRG_ILK ^^^^^^^ :: PROGRAM PRG_ILK VAR END_VAR (*Evaluate Global Interlocks*) US_Roughing_Valves_Open := (fb_AT1K0_GAS_VRC_50.M_IsOpen() AND fb_AT1K0_GAS_VRC_60.M_IsOpen()); DS_Roughing_Valves_Open := (fb_AT1K0_GAS_VRC_90.M_IsOpen() AND( fb_AT1K0_GAS_PMF_90.stPump.eState = pumpRUNNING)) OR (fb_AT1K0_GAS_VRC_100.iq_stValve.i_xOpnLS AND (fb_AT1K0_GAS_PMF_100.stPump.eState = pumpRUNNING )); US_Turbo_Valves_Open := fb_AT1K0_GAS_VRC_10.M_IsOpen() AND fb_AT1K0_GAS_VRC_20.M_IsOpen() AND fb_AT1K0_GAS_VRC_30.M_IsOpen() AND fb_AT1K0_GAS_VRC_40.M_IsOpen(); DS_Turbo_Valves_Open := fb_AT1K0_GAS_VRC_110.M_IsOpen() AND fb_AT1K0_GAS_VRC_120.M_IsOpen() AND fb_AT1K0_GAS_VRC_130.M_IsOpen()AND fb_AT1K0_GAS_VRC_140.M_IsOpen(); US_Turbo_Running := (fb_AT1K0_GAS_PTM_10.iq_stPtm.eState = pumpRUNNING) AND (fb_AT1K0_GAS_PTM_20.iq_stPtm.eState = pumpRUNNING) AND (fb_AT1K0_GAS_PTM_30.iq_stPtm.eState = pumpRUNNING) AND (fb_AT1K0_GAS_PTM_40.iq_stPtm.eState = pumpRUNNING); DS_Turbo_Running := (fb_AT1K0_GAS_PTM_110.iq_stPtm.eState = pumpRUNNING) AND (fb_AT1K0_GAS_PTM_120.iq_stPtm.eState = pumpRUNNING) AND (fb_AT1K0_GAS_PTM_130.iq_stPtm.eState = pumpRUNNING) AND (fb_AT1K0_GAS_PTM_140.iq_stPtm.eState = pumpRUNNING); (* Link The correct override bit to the correct vacuum section*) (*P/MPS FF*) END_PROGRAM PRG_INJ ^^^^^^^ :: PROGRAM PRG_INJ VAR {attribute 'pytmc' :=' pv: AT1K0:GAS:CNTRL:SP; field: HOPR 1000; field: LOPR 0; field: PREC 2; field: EGU "TORR"; '} fSetpointValue :REAL; {attribute 'pytmc' :=' pv: AT1K0:GAS:CNTRL:ON; field: ZNAM STOP; field: ONAM START; io: io; '} bGo: BOOL:=FALSE; {attribute 'pytmc' :=' pv: AT1K0:GAS:CNTRL:RESET; field: ZNAM FALSE; field: ONAM TRUE; io: io; '} bReset : BOOL; {attribute 'pytmc' :=' pv: AT1K0:GAS:CNTRL:ERROR; field: ZNAM FALSE; field: ONAM TRUE; io: io; '} bError : BOOL; // different gains for different apertures {attribute 'pytmc' :=' pv: AT1K0:GAS:CNTRL:Kp1 '} fKp1 : REAL:= 0.4;//0.7; {attribute 'pytmc' :=' pv: AT1K0:GAS:CNTRL:Kp2 '} fKp2 : REAL:= 0.7; {attribute 'pytmc' :=' pv: AT1K0:GAS:CNTRL:Kp3 '} fKp3 : REAL:= 2; {attribute 'pytmc' :=' pv: AT1K0:GAS:CNTRL:Kp4 '} fKp4 : REAL:= 1; {attribute 'pytmc' :=' pv: AT1K0:GAS:CNTRL:Tn1 '} fTn1 : REAL:= 0.5; {attribute 'pytmc' :=' pv: AT1K0:GAS:CNTRL:Tn2 '} fTn2 : REAL:= 0.5; arrTable : ARRAY[1..15,1..2] OF FLOAT; arrTableAprt1 : ARRAY[1..15,1..2] OF FLOAT; arrTableAprt2 : ARRAY[1..15,1..2] OF FLOAT; arrTableAprt3 : ARRAY[1..15,1..2] OF FLOAT; arrTableAprt4 : ARRAY[1..15,1..2] OF FLOAT; fManValue : FLOAT; bExtrapolate : BOOL; eMode : E_CTRL_MODE; stCTRL_PID_PARAMS : ST_CTRL_PID_PARAMS; bSync : BOOL; bHold : BOOL; eErrorId : E_CTRL_ERRORCODES; bARWactive : BOOL; (* controller *) fbCTRL_PID : FB_CTRL_PID; bInit : BOOL := TRUE; fbCTRL_LIN_INTERPOLATION : FB_CTRL_LIN_INTERPOLATION; //stCTRL_LIN_INTERPOLATION_PARAMS : ST_CTRL_LIN_INTERPOLATION_PARAMS; stCTRL_LIN_INTERPOLATION_PARAMS : ST_CTRL_LIN_INTERPOLATION_PARAMS; fbCTRL_DEADBAND : FB_CTRL_DEADBAND; stCTRL_DEADBAND_PARAMS : ST_CTRL_DEADBAND_PARAMS; pid_on :TON; wait : time := T#10S; FTrig: F_TRIG; fTrig_PMPS: F_TRIG; rTrig_PMPS: R_TRIG; rtAction : R_TRIG; rtTrans: R_TRIG; rLimit1 : REAL:= 78; rLimit2 : REAL:= 78; rLimit3 : REAL:= 78; rLimit4 : REAL:= 62; rLimit:REAL:=78; rDelta:REAL:=5; tSettle: TON; tSettleTime: Time := T#5S; tExceed: TON; tExceedTime: Time := T#500mS; tMoving: TON; tMovingTime: Time := T#1S; {attribute 'pytmc' :=' pv: AT1K0:GAS:CNTRL:TransPerc '} rTransPerc : REAL; {attribute 'pytmc' :=' pv: AT1K0:GAS:CNTRL:PressPerc '} rPressPerc : REAL; rPressThresholdHigh : REAL:=2.455e-1; rPressThresholdLow : REAL :=7.733e-2; iGauge:INT:=0; //FFO TRANS_FFO : FB_FastFault :=( i_DevName := 'AT1K0-GAS', i_Desc := 'Fault occurs when the current transmission exceeds the requested transmission by 20%', i_TypeCode := 16#AFF); END_VAR (* The gas injection conrol loop is augmented with a feed forward table, where FF provide the major portion of the controller output and the PI(D) controller conpensate for the remaining error.*) //Devices and Interlock // Valves VCN_70(i_xExtIlkOK := (US_MAA_OK AND US_Turbo_Valves_Open AND US_Turbo_Running) AND (DS_MAA_OK AND DS_Turbo_Valves_Open AND DS_Turbo_Running), i_ReqPos:=); VVC_71(i_xExtILK_OK:= VVC_72.M_IsClosed() AND (((*US_MAA_OK AND*) (*US_Roughing_Valves_Open AND*) US_Turbo_Valves_Open AND US_Turbo_Running) AND ((*DS_MAA_OK AND *)(*DS_Roughing_Valves_Open AND*) DS_Turbo_Valves_Open AND DS_Turbo_Running)), i_xOverrideMode:= , iq_stValve=> ); VVC_72(i_xExtILK_OK:= VVC_71.M_IsClosed() AND (((*US_MAA_OK AND *) (*US_Roughing_Valves_Open AND *)US_Turbo_Valves_Open AND US_Turbo_Running) AND ((*DS_MAA_OK AND *)(*DS_Roughing_Valves_Open AND *)DS_Turbo_Valves_Open AND DS_Turbo_Running)), i_xOverrideMode:= , iq_stValve=> ); //Gauges GCM_70.M_SetBits(30518); GCM_80.M_SetBits(30518); GCM_81.M_SetBits(30518); GCM_70(PG=> , i_rFULL_SCALE:= 2000); GCM_80(PG=> , i_rFULL_SCALE:= 20); GCM_81(PG=> , i_rFULL_SCALE:= 0.25); (* Gauge selection *) (*Assign reading to psuedo gauge*) (* IF (fSetpointValue <= 0.0001) AND (fb_AT1K0_GAS_GCC_80.IG.rPRESS >0) THEN GCM_82 := fb_AT1K0_GAS_GCC_80.IG; ELSIF (fSetpointValue < 0.0029) AND (fb_AT1K0_GAS_GPI_80.PG.rPRESS > 0.0001) THEN GCM_82 := fb_AT1K0_GAS_GPI_80.PG; ELSIF ( GCM_81.PG.rPRESS < 0.25 ) THEN GCM_82 := GCM_81.PG; ElSE GCM_82 := GCM_80.PG; END_IF*) (* MG: removed August shutdown 2021 IF (fb_AT1K0_GAS_GCC_80.IG.rPRESS <=0.0009) AND (fb_AT1K0_GAS_GCC_80.IG.rPRESS >0) THEN GCM_82 := fb_AT1K0_GAS_GCC_80.IG; ELSIF ( GCM_81.PG.rPRESS < 0.25 ) THEN GCM_82 := GCM_81.PG; ElSE GCM_82 := GCM_80.PG; END_IF*) //MG: Added to avoid sudden switching IF (fb_AT1K0_GAS_GCC_80.IG.rPRESS <=0.0009) AND (fb_AT1K0_GAS_GCC_80.IG.rPRESS >0) THEN iGauge := 0;//GCM_82 := fb_AT1K0_GAS_GCC_80.IG; ELSIF (GCM_80.PG.rPRESS <= rPressThresholdLow ) THEN iGauge := 1;//GCM_82 := GCM_81.PG; ELSIF (GCM_81.PG.rPRESS >= rPressThresholdHigh ) THEN iGauge := 2;//GCM_82 := GCM_80.PG; //ElSIF (GCM_82.rPRESS = fb_AT1K0_GAS_GCC_80.IG.rPRESS) THEN iGauge := 0;//GCM_82 := GCM_81.PG ; END_IF CASE iGauge OF 0: GCM_82 := fb_AT1K0_GAS_GCC_80.IG; 1: GCM_82 := GCM_81.PG ; 2: GCM_82 := GCM_80.PG; ELSE GCM_82 := GCM_80.PG; END_CASE (*Automation of other devices*) (*When to Open the VRC Valves to the MAA chambers*) (*When PID is ON*) IF (bGo) THEN (*VRC US*) IF ( fb_AT1K0_GAS_GPI_40.PG .rPRESS >= rVRC_US_SP ) THEN IF (fb_AT1K0_GAS_VRC_50.M_IsOpen()) THEN fb_AT1K0_GAS_VRC_60.M_Set_OPN_SW (TRUE); ELSE fb_AT1K0_GAS_VRC_50.M_Set_OPN_SW (TRUE); END_IF END_IF (*VRC DS*) IF ( fb_AT1K0_GAS_GPI_110.PG .rPRESS >= rVRC_DS_SP ) THEN IF (fb_AT1K0_GAS_VRC_100.M_IsOpen()) THEN fb_AT1K0_GAS_VRC_90.M_Set_OPN_SW (TRUE); ELSE fb_AT1K0_GAS_VRC_100.M_Set_OPN_SW (TRUE); END_IF END_IF END_IF //Try to switch on the GCC in the Gas cell for accurate transmission calculation IF NOT(fb_AT1K0_GAS_GCC_80.IG.i_xHV_ON) AND (fb_AT1K0_GAS_GPI_80.PG.rPRESS <= 1.1E-4) THEN fb_AT1K0_GAS_GCC_80.M_HVE(TRUE); END_IF; (* On change transmission reset *) rtNewTrans(CLK:= (OldTransmissionValue <> TransmissionValue) OR (fTrig_PMPS.Q) OR (rTrig_PMPS.Q)); IF(rtNewTrans.Q) THEN OldTransmissionValue := TransmissionValue; bChangeAperture:=TRUE; bChangeGas := TRUE; fbLogger(sMsg:='AT1K0 new transmission request.', eSevr:=TcEventSeverity.Info); IF NOT (tSettle.IN) THEN stStatus.AtTarget := 0; END_IF stStatus.Moving := 1; END_IF // change setpoint // As calculated by the PRG_INJ IF NOT (xPressureControlMode) THEN fSetpointValue := rRequiredPressureSP; END_IF (*Setpoint Validation*) fSetpointValue:= LIMIT(0,fSetpointValue,10); ACT_init(); ACT_Cntrl(); ACT_Logger(); ACT_FFO(); ACT_STATE(); END_PROGRAM ACTION ACT_Cntrl: // Turn the PID on rising edge of the PMPSMode and off at falling edge fTrig_PMPS(CLK:= xPMPSMode); rTrig_PMPS(CLK:= xPMPSMode); IF (xPMPSMode) THEN bGo := TRUE; xPressureControlMode:=FALSE; END_IF IF (fTrig_PMPS.Q) THEN bGo := FALSE; bChangeAperture:=FALSE; bChangeGas := FALSE; rTransmissionSP:=1; END_IF //IF (rTrig_PMPS.Q) THEN bGo := TRUE; END_IF if (bGo) THEN //VCN_70.i_ReqPos:= LREAL_TO_REAL(fbCTRL_LIN_INTERPOLATION.fOut + fbCTRL_PID.fOut); VCN_70.i_ReqPos:= LREAL_TO_REAL(fbCTRL_LIN_INTERPOLATION.fOut + fbCTRL_PID.fOut); IF (bReset) THEN (* set the mode to RESET*) eMode := eCTRL_MODE_RESET ; VCN_70.M_ValveControl(CloseValve); //bReset := False; ELSE (* set the mode to ACTIVE --> normal operation *) eMode := eCTRL_MODE_ACTIVE ; VCN_70.M_ValveControl(PressureControl); END_IF END_IF FTRIG(CLK := bGo); IF(FTrig.Q)THEN eMode := eCTRL_MODE_PASSIVE; VCN_70.M_ValveControl(CloseValve); fSetpointValue :=0; END_IF (*Interlock setpoint reset*) if (VVC_71.M_IsClosed() AND VVC_72.M_IsClosed() ) THEN //eMode := eCTRL_MODE_PASSIVE; fSetpointValue :=0; END_IF (*Switch PID Mode to passive if VCN is interlocked*) IF NOT (VCN_70.i_xExtIlkOK) THEN eMode := eCTRL_MODE_PASSIVE; END_IF fbCTRL_LIN_INTERPOLATION( fIn:= fSetpointValue , fManValue:= fManValue , bExtrapolate:= bExtrapolate, eMode:= eMode, stParams:= stCTRL_LIN_INTERPOLATION_PARAMS, fOut=> , bInIsGreaterThanMaxElement=> , bInIsLessThanMinElement=> , eState=> , eErrorId=> , bError=> ); (* call controller *) fbCTRL_PID( fSetpointValue := fSetpointValue,//TransmissionValue,//fSetpointValue, fActualValue := GCM_82.rPRESS,//rCalculatedTransmissionValue,//GCM_82.rPRESS , fManSyncValue := , bSync := bSync, eMode := eMode, bHold := bHold, stParams := stCTRL_PID_PARAMS, fOut => , bARWactive => bARWactive, eErrorId => eErrorId, bError => ); (*deadband/clipper *) (* call function block *) stCTRL_DEADBAND_PARAMS.fThreshold := fSetpointValue*0.0016 ; (*fbCTRL_DEADBAND ( fIn := , stParams := stCTRL_DEADBAND_PARAMS, bInIsUnderThreshold => , eErrorId => , bError => );*) bError := fbCTRL_PID.bError OR fbCTRL_LIN_INTERPOLATION.bError; END_ACTION ACTION ACT_FFO: TRANS_FFO.i_xOK := (rCalculatedTransmissionValue <= (TransmissionValue + (TransmissionValue*20/100))) OR NOT tExceed.Q; //auto reset true (*FAST FAULT*) TRANS_FFO(i_xOK := ,//NOT tExceed.Q, i_xReset := , i_xAutoReset := TRUE, io_fbFFHWO := GVL_PMPS.g_FastFaultOutput1); END_ACTION ACTION ACT_Init: //control Loop and FeedForward table initialisation (*Iniitialization*) IF bInit THEN (* Feed forward table records 9 disticnt positions of the needle valves, breaking the *) (* the needle valve profile into disticnt nearly linear segments*) (* init array with the interpolation points *) (* fIn | fOut *) arrTable[1,1] := 0; arrTable[1,2] := 12; arrTable[2,1] := 0.000001; arrTable[2,2] := 15; arrTable[3,1] := 0.000024; arrTable[3,2] := 19; arrTable[4,1] := 0.0001; arrTable[4,2] := 25; arrTable[5,1] := 0.001; arrTable[5,2] := 28; arrTable[6,1] := 0.0082; arrTable[6,2] := 31; arrTable[7,1] := 0.04; arrTable[7,2] := 34; arrTable[8,1] := 0.062; arrTable[8,2] := 39; arrTable[9,1] := 0.09; arrTable[9,2] := 44; arrTable[10,1] := 0.112; arrTable[10,2] := 49; arrTable[11,1] := 0.6; arrTable[11,2] := 55; arrTable[12,1] := 1.34; arrTable[12,2] := 62; arrTable[13,1] := 4; arrTable[13,2] := 70; arrTable[14,1] := 7.27; arrTable[14,2] := 78; arrTable[15,1] := 20; arrTable[15,2] := 100; (* init array with the interpolation points *) (* fIn | fOut *) arrTableAprt1[1,1] := 0; arrTableAprt1[1,2] := 12; arrTableAprt1[2,1] := 0.000001; arrTableAprt1[2,2] := 15; arrTableAprt1[3,1] := 0.000024; arrTableAprt1[3,2] := 19; arrTableAprt1[4,1] := 0.0001; arrTableAprt1[4,2] := 25; arrTableAprt1[5,1] := 0.001; arrTableAprt1[5,2] := 28; arrTableAprt1[6,1] := 0.0082; arrTableAprt1[6,2] := 31; arrTableAprt1[7,1] := 0.04; arrTableAprt1[7,2] := 34; arrTableAprt1[8,1] := 0.062; arrTableAprt1[8,2] := 39; arrTableAprt1[9,1] := 0.09; arrTableAprt1[9,2] := 44; arrTableAprt1[10,1] := 0.112; arrTableAprt1[10,2] := 49; arrTableAprt1[11,1] := 0.6; arrTableAprt1[11,2] := 55; arrTableAprt1[12,1] := 1.34; arrTableAprt1[12,2] := 62; arrTableAprt1[13,1] := 4; arrTableAprt1[13,2] := 70; arrTableAprt1[14,1] := 7.27; arrTableAprt1[14,2] := 78; arrTableAprt1[15,1] := 20; arrTableAprt1[15,2] := 100; (* init array with the interpolation points *) (* fIn | fOut *) arrTableAprt2[1,1] := 0; arrTableAprt2[1,2] := 12; arrTableAprt2[2,1] := 0.000001; arrTableAprt2[2,2] := 15; arrTableAprt2[3,1] := 0.000024; arrTableAprt2[3,2] := 19; arrTableAprt2[4,1] := 0.000072; arrTableAprt2[4,2] := 25; arrTableAprt2[5,1] := 0.0059; arrTableAprt2[5,2] := 28; arrTableAprt2[6,1] := 0.0059; arrTableAprt2[6,2] := 31; arrTableAprt2[7,1] := 0.0099; arrTableAprt2[7,2] := 34; arrTableAprt2[8,1] := 0.034; arrTableAprt2[8,2] := 39; arrTableAprt2[9,1] := 0.051; arrTableAprt2[9,2] := 44; arrTableAprt2[10,1] := 0.074; arrTableAprt2[10,2] := 49; arrTableAprt2[11,1] := 0.2; arrTableAprt2[11,2] := 55; arrTableAprt2[12,1] := 0.598; arrTableAprt2[12,2] := 62; arrTableAprt2[13,1] := 1; arrTableAprt2[13,2] := 70; arrTableAprt2[14,1] := 3.34; arrTableAprt2[14,2] := 78; arrTableAprt2[15,1] := 20; arrTableAprt2[15,2] := 100; (* init array with the interpolation points *) (* fIn | fOut *) arrTableAprt3[1,1] := 0; arrTableAprt3[1,2] := 12; arrTableAprt3[2,1] := 0.000001; arrTableAprt3[2,2] := 15; arrTableAprt3[3,1] := 0.000024; arrTableAprt3[3,2] := 19; arrTableAprt3[4,1] := 0.000062; arrTableAprt3[4,2] := 25; arrTableAprt3[5,1] := 0.001; arrTableAprt3[5,2] := 28; arrTableAprt3[6,1] := 0.005; arrTableAprt3[6,2] := 31; arrTableAprt3[7,1] := 0.01; arrTableAprt3[7,2] := 34; arrTableAprt3[8,1] := 0.029; arrTableAprt3[8,2] := 39; arrTableAprt3[9,1] := 0.036; arrTableAprt3[9,2] := 44; arrTableAprt3[10,1] := 0.058; arrTableAprt3[10,2] := 49; arrTableAprt3[11,1] := 0.2; arrTableAprt3[11,2] := 55; arrTableAprt3[12,1] := 0.363; arrTableAprt3[12,2] := 62; arrTableAprt3[13,1] := 1; arrTableAprt3[13,2] := 70; arrTableAprt3[14,1] := 1.95; arrTableAprt3[14,2] := 78; arrTableAprt3[15,1] := 20; arrTableAprt3[15,2] := 100; (* init array with the interpolation points *) (* fIn | fOut *) arrTableAprt4[1,1] := 0; arrTableAprt4[1,2] := 10; arrTableAprt4[2,1] := 0.000001; arrTableAprt4[2,2] := 12; arrTableAprt4[3,1] := 0.000024; arrTableAprt4[3,2] := 17; arrTableAprt4[4,1] := 0.000071; arrTableAprt4[4,2] := 23; arrTableAprt4[5,1] := 0.00036; arrTableAprt4[5,2] := 26; arrTableAprt4[6,1] := 0.005; arrTableAprt4[6,2] := 29; arrTableAprt4[7,1] := 0.0073; arrTableAprt4[7,2] := 32; arrTableAprt4[8,1] := 0.028; arrTableAprt4[8,2] := 37; arrTableAprt4[9,1] := 0.04; arrTableAprt4[9,2] := 42; arrTableAprt4[10,1] := 0.0535; arrTableAprt4[10,2] := 47; arrTableAprt4[11,1] := 0.083; arrTableAprt4[11,2] := 53; arrTableAprt4[12,1] := 0.3; arrTableAprt4[12,2] := 60; arrTableAprt4[13,1] := 1; arrTableAprt4[13,2] := 68; arrTableAprt4[14,1] := 1.95; arrTableAprt4[14,2] := 76; arrTableAprt4[15,1] := 20; arrTableAprt4[15,2] := 98; (* init parameter struct *) stCTRL_LIN_INTERPOLATION_PARAMS.tCtrlCycleTime := T#10ms; stCTRL_LIN_INTERPOLATION_PARAMS.tTaskCycleTime := T#10ms; stCTRL_LIN_INTERPOLATION_PARAMS.nDataTable_NumberOfRows := INT_TO_UINT(15); (*FBCNTRL*) (* init parameter struct *) stCTRL_PID_PARAMS.tCtrlCycleTime := T#250ms; stCTRL_PID_PARAMS.tTaskCycleTime := T#10ms; stCTRL_PID_PARAMS.fKp := fKp1; (* proportional gain Kp *) stCTRL_PID_PARAMS.tTn := T#500ms; (* Tn *) stCTRL_PID_PARAMS.tTv := T#200ms; (* Tv *) stCTRL_PID_PARAMS.tTd := T#500ms; (* Td 200 *) stCTRL_PID_PARAMS.fOutMaxLimit := 25; (* maximum output limit *) stCTRL_PID_PARAMS.fOutMinLimit := -100; (* minimum output limit *) (* set the mode to ACTIVE --> normal operation *) eMode := eCTRL_MODE_PASSIVE ; (*set the upper limit on the VCN*) VCN_70.M_SetThrottle(rLimit); (* reset the init flag *) bInit := FALSE; END_IF (* set the addresses *) (* Gain selection *) (* VCN limit *) IF (bGo) THEN CASE eSelectedAprt of E_MAA_States.Aprt1: arrTable := arrTableAprt1; stCTRL_PID_PARAMS.fKp := fKp1; //rLimit:= rLimit1; //VCN_70.M_SetThrottle(78); E_MAA_States.Aprt2: arrTable := arrTableAprt2; stCTRL_PID_PARAMS.fKp := fKp2; //rLimit:= rLimit2; //VCN_70.M_SetThrottle(78); E_MAA_States.Aprt3: arrTable := arrTableAprt3; stCTRL_PID_PARAMS.fKp := fKp3; //rLimit:= rLimit3; //VCN_70.M_SetThrottle(78); E_MAA_States.Aprt4: arrTable := arrTableAprt4; stCTRL_PID_PARAMS.fKp := fKp4; //rLimit:= rLimit4; //VCN_70.M_SetThrottle(78); END_CASE END_IF stCTRL_LIN_INTERPOLATION_PARAMS.pDataTable_ADR := ADR(arrTable); stCTRL_LIN_INTERPOLATION_PARAMS.nDataTable_SIZEOF := SIZEOF(arrTable); END_ACTION ACTION ACT_Logger: rtAction(CLK:=eSelectedAprt <> eSetAprt); IF (fTrig_PMPS.Q) THEN fbLogger(sMsg:='AT1K0 switched to local mode.', eSevr:=TcEventSeverity.Info); END_IF IF (rTrig_PMPS.Q) THEN fbLogger(sMsg:='AT1K0 switched to PMPS mode.', eSevr:=TcEventSeverity.Info); END_IF IF (rtAction.Q) THEN fbLogger(sMsg:='AT1K0-MAA current aperture size mismatch, change aperture state or switch to local mode', eSevr:=TcEventSeverity.Critical); END_IF END_ACTION ACTION ACT_STATE: IF tExceed.Q THEN eState := E_State.error; stStatus.AtTarget := 0; ELSIF tSettle.Q THEN // ok eState := E_State.ok; // At Target stStatus.AtTarget := 1; stStatus.Moving := 0; ELSIF (rCalculatedTransmissionValue < (TransmissionValue - (TransmissionValue*20/100))) THEN //warning eState := E_State.warning; ELSE eState := E_State.unknown; END_IF // State ok when the Transmission is within the acceptable range and the MAA are not in errors stStatus.OK := (*TRANS_FFO.i_xOK AND*) US_MAA_OK AND DS_MAA_OK AND US_Turbo_Valves_Open AND DS_Turbo_Valves_Open AND US_Turbo_Running AND DS_Turbo_Running; ; bStatus.0 := stStatus.AtTarget; bStatus.1 := stStatus.Moving; bStatus.2 := stStatus.LocalMode; bStatus.3 := stStatus.PMPSMode; bStatus.4 := stStatus.OK; bStatus.5 := stStatus.Toggle; bStatus.6 := stStatus.Include; stStatus.Moving := NOT tMoving.Q; xAtTarget := stStatus.AtTarget; xMoving := stStatus.Moving; xOK := stStatus.OK; IF (TransmissionValue >0) THEN rTransPerc:= rCalculatedTransmissionValue*100/TransmissionValue; END_IF IF (fSetpointValue >0) THEN rPressPerc:= GCM_82.rPRESS*100/fSetpointValue; END_IF tSettle(IN:= (rCalculatedTransmissionValue <= (TransmissionValue + (TransmissionValue*20/100))) AND (rCalculatedTransmissionValue >= (TransmissionValue - (TransmissionValue*20/100))), PT := tSettleTime); tMoving(IN:= (rCalculatedTransmissionValue <= (TransmissionValue + (TransmissionValue*5/100))) AND (rCalculatedTransmissionValue >= (TransmissionValue - (TransmissionValue*10/100))), PT := tMovingTime); tExceed(IN:= (rCalculatedTransmissionValue > (TransmissionValue + (TransmissionValue*20/100))), PT := tExceedTime); END_ACTION Related: * `E_MAA_States`_ * `E_State`_ * `GVL_PMPS`_ PRG_Motion ^^^^^^^^^^ :: PROGRAM PRG_Motion VAR bInit: BOOL := TRUE; nTransitionAssertionRootID: UDINT :=1000; nUnknownAssertionRootID: UDINT :=9000; bAllGo : Bool := false; ///// {attribute 'pytmc' := ' pv: AT1K0:GAS_MAA:01 io: io '} fbMAA_1_States: FB_MAA; {attribute 'pytmc' := ' pv: AT1K0:GAS_MAA:02 io: io '} fbMAA_2_States: FB_MAA; {attribute 'pytmc' := ' pv: AT1K0:GAS_MAA:03 io: io '} fbMAA_3_States: FB_MAA; {attribute 'pytmc' := ' pv: AT1K0:GAS_MAA:04 io: io '} fbMAA_4_States: FB_MAA; END_VAR IF (bInit) THEN bInit := False; /// PMPS //MAA 1 Y //fbMAA_1_States.nTransitionAssertionID := 43536;// nTransitionAssertionRootID+10; //fbMAA_1_States.nUnknownAssertionID := nUnknownAssertionRootID; // Aperture 1 fbMAA_1_States.stAprt1.fPosition := -0.78;//-1.4; // Aperture 2 fbMAA_1_States.stAprt2.fPosition := -16.1; // Aperture 3 fbMAA_1_States.stAprt3.fPosition := -30.93; // Aperture 4 fbMAA_1_States.stAprt4.fPosition := -48.7; // X Cen fbMAA_1_States.stXCen.fPosition := 1;//1.5;// 0;// -2.083; //MAA 2 Y //fbMAA_2_States.nTransitionAssertionID := 43552;//nTransitionAssertionRootID+20; //fbMAA_1_States.nUnknownAssertionID := nUnknownAssertionRootID; // Aperture 1 fbMAA_2_States.stAprt1.fPosition := -1;//-1.4; // Aperture 2 fbMAA_2_States.stAprt2.fPosition := -16.5; // Aperture 3 fbMAA_2_States.stAprt3.fPosition := -30.9; // Aperture 4 fbMAA_2_States.stAprt4.fPosition := -48.96; // X Cen fbMAA_2_States.stXCen.fPosition :=1.5;//0.475;//0;//-0.77; //MAA 3 Y //fbMAA_3_States.nTransitionAssertionID := 43568;//nTransitionAssertionRootID+30; //fbMAA_1_States.nUnknownAssertionID := nUnknownAssertionRootID; // Aperture 1 fbMAA_3_States.stAprt1.fPosition := -0.35;//-1.15; // Aperture 2 fbMAA_3_States.stAprt2.fPosition := -16.2; // Aperture 3 fbMAA_3_States.stAprt3.fPosition := -30.8; // Aperture 4 fbMAA_3_States.stAprt4.fPosition := -48.95; // X Cen fbMAA_3_States.stXCen.fPosition :=1;//-0.4064;//0;//2.031; //MAA 4 Y //fbMAA_4_States.nTransitionAssertionID := 43584;//nTransitionAssertionRootID+40; //fbMAA_1_States.nUnknownAssertionID := nUnknownAssertionRootID; // Aperture 1 fbMAA_4_States.stAprt1.fPosition := 0;//-1; // Aperture 2 fbMAA_4_States.stAprt2.fPosition := -14.5;//-16.6; re align data May 17,2024 // Aperture 3 fbMAA_4_States.stAprt3.fPosition := -30.9; // Aperture 4 fbMAA_4_States.stAprt4.fPosition := -49.06; // X Cen fbMAA_4_States.stXCen.fPosition :=1.0;//0;//-0.9861;//0;//2.0345; END_IF //EBD fbMAA_1_States( fbArbiter := GVL_PMPS.fbArbiter1, i_DevName:= 'AT1K0:GAS_MAA:01', fbFFHWO := GVL_PMPS.g_FastFaultOutput1, sPmpsDeviceName:='AT1K0:GAS_MAA:01', sTransitionKey:='AT1K0:GAS_MAA:01-TRANSITION', stYStage := Main.M2, stXStage := Main.M1); fbMAA_2_States( fbArbiter := GVL_PMPS.fbArbiter1, i_DevName:= 'AT1K0:GAS_MAA:02', sPmpsDeviceName:='AT1K0:GAS_MAA:02', sTransitionKey:='AT1K0:GAS_MAA:02-TRANSITION', fbFFHWO := GVL_PMPS.g_FastFaultOutput1, stYStage := Main.M4, stXStage := Main.M3); //FEE fbMAA_3_States( fbArbiter := GVL_PMPS.fbArbiter1, i_DevName:= 'AT1K0:GAS_MAA:03', sPmpsDeviceName:='AT1K0:GAS_MAA:03', sTransitionKey:='AT1K0:GAS_MAA:03-TRANSITION', fbFFHWO := GVL_PMPS.g_FastFaultOutput1, stYStage := Main.M6, stXStage := Main.M5); fbMAA_4_States( fbArbiter := GVL_PMPS.fbArbiter1, i_DevName:= 'AT1K0:GAS_MAA:04', sPmpsDeviceName:='AT1K0:GAS_MAA:04', sTransitionKey:='AT1K0:GAS_MAA:04-TRANSITION', fbFFHWO := GVL_PMPS.g_FastFaultOutput1, stYStage := Main.M8, stXStage := Main.M7); (*Set global OK bit*) US_MAA_OK := (fbMAA_1_States.fbStates.enumGet = fbMAA_2_States.fbStates.enumGet) AND (fbMAA_2_States.fbStates.enumGet = fbMAA_3_States.fbStates.enumGet)AND( fbMAA_3_States.fbStates.enumGet = fbMAA_4_States.fbStates.enumGet) AND NOT (fbMAA_1_States.fbStates.bError) AND NOT (fbMAA_2_States.fbStates.bError); DS_MAA_OK := (fbMAA_3_States.fbStates.enumGet = fbMAA_4_States.fbStates.enumGet) AND NOT (fbMAA_3_States.fbStates.bError) AND NOT (fbMAA_4_States.fbStates.bError); //change here line103 and 119 IF (US_MAA_OK AND DS_MAA_OK) THEN eSelectedAprt:=fbMAA_4_States.fbStates.enumGet;//was fbMAA_1 ELSE eSelectedAprt:= E_MAA_States.Unknown; END_IF; //////////////////// //Set the right state i.e. apperture based on the current beam size/ ///// IF( rPhotonEnergy >=0.9E3) THEN eSetAprt := E_MAA_States.Aprt1; ELSIF ( rPhotonEnergy >=0.6E3) THEN eSetAprt := E_MAA_States.Aprt2; ELSIF ( rPhotonEnergy >=0.5E3) THEN eSetAprt := E_MAA_States.Aprt3; ELSE eSetAprt := E_MAA_States.Aprt4; END_IF (*Aperture state selection*) IF (xPMPSMode) AND (bChangeAperture) AND (eSelectedAprt <> eSetAprt) THEN fbMAA_1_States.enumSet := eSetAprt; fbMAA_2_States.enumSet := eSetAprt; fbMAA_3_States.enumSet := eSetAprt; fbMAA_4_States.enumSet := eSetAprt; bChangeAperture:=False; fbLogger(sMsg:='AT1K0-MAA moving to correct apperture size', eSevr:=TcEventSeverity.Verbose); ELSE bChangeAperture:=False; END_IF IF NOT (xPMPSMode) AND bChangeAperture AND (eSelectedAprt <> eSetAprt) THEN fbLogger(sMsg:='AT1K0-MAA is not set to correct apperture size', eSevr:=TcEventSeverity.Critical); bChangeAperture:=False; END_IF END_PROGRAM Related: * `E_MAA_States`_ * `FB_MAA`_ * `GVL_PMPS`_ * `Main`_ PRG_Motors_Test ^^^^^^^^^^^^^^^ :: PROGRAM PRG_Motors_Test VAR Y1_Power: MC_Power; Y2_Power: MC_Power; Y3_Power: MC_Power; Y4_Power: MC_Power; X1_Power: MC_Power; X2_Power: MC_Power; X3_Power: MC_Power; X4_Power: MC_Power; Y1_ENC AT%I* :INT; Y2_ENC AT%I* :INT; Y3_ENC AT%I* :INT; Y4_ENC AT%I* :INT; X1_ENC AT%I* :INT; X2_ENC AT%I* :INT; X3_ENC AT%I* :INT; X4_ENC AT%I* :INT; END_VAR X1_Power(//reverse motor direction? Axis:= M1.Axis, Enable:= M1.bBrakeRelease, Enable_Positive:= M1.bLimitForwardEnable, // fix Enable_Negative:= M1.bLimitBackwardEnable, // fix -- verify Override:= , BufferMode:= , Options:= , Status=> , Busy=> , Active=> , Error=> , ErrorID=> ); Y1_Power( Axis:= M2.Axis, Enable:= M2.bBrakeRelease, Enable_Positive:= M2.bLimitForwardEnable, Enable_Negative:= M2.bLimitBackwardEnable, Override:= , BufferMode:= , Options:= , Status=> , Busy=> , Active=> , Error=> , ErrorID=> ); X2_Power( Axis:= M3.Axis, Enable:= M3.bBrakeRelease, Enable_Positive:= M3.bLimitForwardEnable, // fix Enable_Negative:= M3.bLimitBackwardEnable, // fix -- verify Override:= , BufferMode:= , Options:= , Status=> , Busy=> , Active=> , Error=> , ErrorID=> ); Y2_Power( Axis:= M4.Axis, Enable:= M4.bBrakeRelease, Enable_Positive:= M4.bLimitForwardEnable, Enable_Negative:= M4.bLimitBackwardEnable, Override:= , BufferMode:= , Options:= , Status=> , Busy=> , Active=> , Error=> , ErrorID=> ); X3_Power( Axis:= M5.Axis, Enable:= M5.bBrakeRelease, Enable_Positive:= M5.bLimitForwardEnable, Enable_Negative:= M5.bLimitBackwardEnable, Override:= , BufferMode:= , Options:= , Status=> , Busy=> , Active=> , Error=> , ErrorID=> ); Y3_Power( Axis:= M6.Axis, Enable:= M6.bBrakeRelease, Enable_Positive:= M6.bLimitForwardEnable, Enable_Negative:= M6.bLimitBackwardEnable, Override:= , BufferMode:= , Options:= , Status=> , Busy=> , Active=> , Error=> , ErrorID=> ); X4_Power( Axis:= M7.Axis, Enable:= M7.bBrakeRelease, Enable_Positive:= M7.bLimitForwardEnable, Enable_Negative:= M7.bLimitBackwardEnable, Override:= , BufferMode:= , Options:= , Status=> , Busy=> , Active=> , Error=> , ErrorID=> ); Y4_Power( Axis:= M8.Axis, Enable:= M8.bBrakeRelease, Enable_Positive:= M8.bLimitForwardEnable, Enable_Negative:= M8.bLimitBackwardEnable, Override:= , BufferMode:= , Options:= , Status=> , Busy=> , Active=> , Error=> , ErrorID=> ); END_PROGRAM PRG_PMPS ^^^^^^^^ :: PROGRAM PRG_PMPS VAR fbArbiterIO : FB_SubSysToArbiter_IO; ar1 : bool; ar2 : bool; nReqID:UDINT; nReqRM:UDINT; bRemove:bool; rtRemove: R_TRIG; //Testing ID1:DWORD:=43536; ID2:DWORD:=43552;; ID3:DWORD:=43568; ID4:DWORD:=43584; bTrans:BOOL; bAp11:BOOL; bAp12:BOOL; bAp13:BOOL; bAp14:BOOL; bTrans2:BOOL; bTrans3:BOOL; bTrans4:BOOL; bTrans1X:BOOL; bTrans2X:BOOL; bTrans3X:BOOL; bTrans4X:BOOL; bAp1XS:BOOL; bAp2XS:BOOL; bAp3XS:BOOL; bAp4XS:BOOL; bAp21:BOOL; bAp22:BOOL; bAp23:BOOL; bAp24:BOOL; bAp31:BOOL; bAp32:BOOL; bAp33:BOOL; bAp34:BOOL; bAp41:BOOL; bAp42:BOOL; bAp43:BOOL; bAp44:BOOL; iAp:INT; END_VAR (*Fast Fault instantiation*) GVL_PMPS.g_FastFaultOutput1.bAutoReset :=TRUE; GVL_PMPS.g_FastFaultOutput2.bAutoReset :=TRUE; GVL_PMPS.g_FastFaultOutput1.Execute(); GVL_PMPS.g_FastFaultOutput2.Execute(); (* Arbiter Instantiation*) (*Arbiter one responsible for the aperture valves*) fbArbiterIO(Arbiter := GVL_PMPS.fbArbiter1, fbFFHWO := GVL_PMPS.g_FastFaultOutput1); //GVL_ILK.fbArbiter2.ElevateRequest(GVL_ILK.fbArbiter1); (* Photon Energy *) rPhotonEnergy := PMPS_GVL.stCurrentBeamParameters.neV; MOTION_GVL.fbStandardPMPSDB( io_fbFFHWO:=GVL_PMPS.g_FastFaultOutput1, bEnable:=TRUE, sPLCName:='plc-kfe-gatt', ); (*remove*) (*Debugging functions*) bTrans:= fbArbiter1.CheckRequestInPool(ID1);//TransitionID bAp11:= fbArbiter1.CheckRequestInPool(ID1+1); bAp12:= fbArbiter1.CheckRequestInPool(ID1+2); bAp13:= fbArbiter1.CheckRequestInPool(ID1+3); bAp14:= fbArbiter1.CheckRequestInPool(ID1+4); bTrans1X:= fbArbiter1.CheckRequestInPool(ID1+5); bAp1XS:= fbArbiter1.CheckRequestInPool(ID1+6); bTrans2:= fbArbiter1.CheckRequestInPool(ID2);//TransitionID bAp21:= fbArbiter1.CheckRequestInPool(ID2+1); bAp22:= fbArbiter1.CheckRequestInPool(ID2+2); bAp23:= fbArbiter1.CheckRequestInPool(ID2+3); bAp24:= fbArbiter1.CheckRequestInPool(ID2+4); bTrans2X:= fbArbiter1.CheckRequestInPool(ID2+5); bAp2XS:= fbArbiter1.CheckRequestInPool(ID2+6); bTrans3:= fbArbiter1.CheckRequestInPool(ID3);//TransitionID bAp31:= fbArbiter1.CheckRequestInPool(ID3+1); bAp32:= fbArbiter1.CheckRequestInPool(ID3+2); bAp33:= fbArbiter1.CheckRequestInPool(ID3+3); bAp34:= fbArbiter1.CheckRequestInPool(ID3+4); bTrans3X:= fbArbiter1.CheckRequestInPool(ID3+5); bAp3XS:= fbArbiter1.CheckRequestInPool(ID3+6); bTrans4:= fbArbiter1.CheckRequestInPool(ID4);//TransitionID bAp41:= fbArbiter1.CheckRequestInPool(ID4+1); bAp42:= fbArbiter1.CheckRequestInPool(ID4+2); bAp43:= fbArbiter1.CheckRequestInPool(ID4+3); bAp44:= fbArbiter1.CheckRequestInPool(ID4+4); bTrans3X:= fbArbiter1.CheckRequestInPool(ID4+5); bAp4XS:= fbArbiter1.CheckRequestInPool(ID4+6); rtRemove(CLK:= bRemove); if (rtRemove.Q) THEN GVL_PMPS.fbArbiter1.RemoveRequest(nReqRM); //GVL_ILK.fbArbiter2.RemoveRequest(nReqRM); END_IF END_PROGRAM Related: * `GVL_PMPS`_ PRG_Transmission ^^^^^^^^^^^^^^^^ :: PROGRAM PRG_Transmission VAR arr_COEF_Table_Ar : ARRAY[1..50,1..2] OF FLOAT; arr_COEF_Table_N2 : ARRAY[1..40,1..2] OF FLOAT; fbCTRL_LIN_INTERPOLATION_Ar : FB_CTRL_LIN_INTERPOLATION; stCTRL_LIN_INTERPOLATION_PARAMS_Ar : ST_CTRL_LIN_INTERPOLATION_PARAMS; fbCTRL_LIN_INTERPOLATION_N2 : FB_CTRL_LIN_INTERPOLATION; stCTRL_LIN_INTERPOLATION_PARAMS_N2 : ST_CTRL_LIN_INTERPOLATION_PARAMS; eMode : E_CTRL_MODE; bInit: BOOL :=TRUE; FFO : FB_FastFault :=( i_DevName := 'AT1K0-GAS', i_Desc := 'Fault occurs when the PMPS mode is switched off', i_TypeCode := 16#AAFF); END_VAR VAR CONSTANT rGasCellLength : REAL:= 1450.696; iTorr: INT :=750; rR_Ar:REAL := 1.66e-3; rR_N2:REAL := 1.16e-3; END_VAR A_INIT(); (*Calculate current transmission value*) IF ( SelectedGas = E_GasType.Argon) THEN rCalculatedTransmissionValue := EXP(-fbCTRL_LIN_INTERPOLATION_Ar.fOut*(GCM_82.rPRESS/iTorr)*rR_Ar*rGasCellLength); ELSE rCalculatedTransmissionValue := EXP(-fbCTRL_LIN_INTERPOLATION_N2.fOut*(GCM_82.rPRESS/iTorr)*rR_N2*rGasCellLength); END_IF Cur_Trans.nTran:= TO_REAL(rCalculatedTransmissionValue*PMPS_GVL.TRANS_SCALING_FACTOR); (*Calculate Pressure setpoint from requested transmission value*) IF NOT (PMPS_GVL.TRANS_SCALING_FACTOR = 0) THEN rRequestedTransmission := (TO_REAL(Req_Trans.nTran)/PMPS_GVL.TRANS_SCALING_FACTOR); END_IF (*Transmission Request selection*) IF (xPMPSMode) THEN xPressureControlMode := FALSE; IF NOT (PMPS_GVL.TRANS_SCALING_FACTOR = 0) THEN TransmissionValue := (TO_REAL(Req_Trans.nTran)/PMPS_GVL.TRANS_SCALING_FACTOR); END_IF rTransmissionSP := LIMIT(0.00000000001,TransmissionValue,1); ELSE TransmissionValue := LIMIT(0.00000000001,rTransmissionSP,1); END_IF // Set Status to the arbiter stStatus.PMPSMode:= xPMPSMode; stStatus.LocalMode := NOT(xPMPSMode); IF ( SelectedGas = E_GasType.Argon) THEN if (fbCTRL_LIN_INTERPOLATION_Ar.fOut <>0) THEN rRequiredPressureSP := (-LN(TransmissionValue)/(fbCTRL_LIN_INTERPOLATION_Ar.fOut*rR_Ar*rGasCellLength))*iTorr; END_IF ELSE IF (fbCTRL_LIN_INTERPOLATION_N2.fOut <>0) THEN rRequiredPressureSP := (-LN(TransmissionValue)/(fbCTRL_LIN_INTERPOLATION_N2.fOut*rR_N2*rGasCellLength))*iTorr; END_IF END_IF (*FAST FAULT*) FFO(i_xOK := xPMPSMode, i_xReset := , i_xAutoReset := TRUE, io_fbFFHWO := GVL_PMPS.g_FastFaultOutput1); END_PROGRAM ACTION A_INIT: IF bInit THEN (* init array with the interpolation points *) (* fIn (eV) | fOut (mass coefficient) *) (*X-Ray Mass Attenuation Coefficients for N2*) arr_COEF_Table_N2[1,1]:=201.37; arr_COEF_Table_N2[1,2]:=7840.7; arr_COEF_Table_N2[2,1]:=215.2655; arr_COEF_Table_N2[2,2]:=6694.2; arr_COEF_Table_N2[3,1]:=230.1188; arr_COEF_Table_N2[3,2]:=5711.5; arr_COEF_Table_N2[4,1]:=245.997; arr_COEF_Table_N2[4,2]:=4870.1; arr_COEF_Table_N2[5,1]:=262.9708; arr_COEF_Table_N2[5,2]:=4150.6; arr_COEF_Table_N2[6,1]:=281.1158; arr_COEF_Table_N2[6,2]:=3535.8; arr_COEF_Table_N2[7,1]:=300.5128; arr_COEF_Table_N2[7,2]:=3011; arr_COEF_Table_N2[8,1]:=321.2482; arr_COEF_Table_N2[8,2]:=2563.3; arr_COEF_Table_N2[9,1]:=343.4143; arr_COEF_Table_N2[9,2]:=2181.6; arr_COEF_Table_N2[10,1]:=367.1099; arr_COEF_Table_N2[10,2]:=1856.4; arr_COEF_Table_N2[11,1]:=392.4405; arr_COEF_Table_N2[11,2]:=1579.5; arr_COEF_Table_N2[12,1]:=393.568; arr_COEF_Table_N2[12,2]:=1568.6; arr_COEF_Table_N2[13,1]:=399.592; arr_COEF_Table_N2[13,2]:=1511.9; arr_COEF_Table_N2[14,1]:=401.1984; arr_COEF_Table_N2[14,2]:=1497.3; arr_COEF_Table_N2[15,1]:=403.608; arr_COEF_Table_N2[15,2]:=30009; arr_COEF_Table_N2[16,1]:=409.632; arr_COEF_Table_N2[16,2]:=29063; arr_COEF_Table_N2[17,1]:=419.5189; arr_COEF_Table_N2[17,2]:=27603; arr_COEF_Table_N2[18,1]:=448.4657; arr_COEF_Table_N2[18,2]:=23892; arr_COEF_Table_N2[19,1]:=479.4098; arr_COEF_Table_N2[19,2]:=20593; arr_COEF_Table_N2[20,1]:=512.4891; arr_COEF_Table_N2[20,2]:=17652; arr_COEF_Table_N2[21,1]:=547.8508; arr_COEF_Table_N2[21,2]:=15059; arr_COEF_Table_N2[22,1]:=585.6525; arr_COEF_Table_N2[22,2]:=12797; arr_COEF_Table_N2[23,1]:=626.0625; arr_COEF_Table_N2[23,2]:=10838; arr_COEF_Table_N2[24,1]:=669.2609; arr_COEF_Table_N2[24,2]:=9153.6; arr_COEF_Table_N2[25,1]:=715.4399; arr_COEF_Table_N2[25,2]:=7711.4; arr_COEF_Table_N2[26,1]:=764.8052; arr_COEF_Table_N2[26,2]:=6482.3; arr_COEF_Table_N2[27,1]:=817.5768; arr_COEF_Table_N2[27,2]:=5438.6; arr_COEF_Table_N2[28,1]:=873.9896; arr_COEF_Table_N2[28,2]:=4555.2; arr_COEF_Table_N2[29,1]:=934.2948; arr_COEF_Table_N2[29,2]:=3809.4; arr_COEF_Table_N2[30,1]:=998.7612; arr_COEF_Table_N2[30,2]:=3181.2; arr_COEF_Table_N2[31,1]:=1067.676; arr_COEF_Table_N2[31,2]:=2651; arr_COEF_Table_N2[32,1]:=1141.345; arr_COEF_Table_N2[32,2]:=2206.1; arr_COEF_Table_N2[33,1]:=1220.098; arr_COEF_Table_N2[33,2]:=1833.6; arr_COEF_Table_N2[34,1]:=1304.285; arr_COEF_Table_N2[34,2]:=1522.5; arr_COEF_Table_N2[35,1]:=1394.281; arr_COEF_Table_N2[35,2]:=1263.2; arr_COEF_Table_N2[36,1]:=1490.486; arr_COEF_Table_N2[36,2]:=1047.3; arr_COEF_Table_N2[37,1]:=1593.329; arr_COEF_Table_N2[37,2]:=867.89; arr_COEF_Table_N2[38,1]:=1703.269; arr_COEF_Table_N2[38,2]:=715.55; arr_COEF_Table_N2[39,1]:=1820.795; arr_COEF_Table_N2[39,2]:=589.6; arr_COEF_Table_N2[40,1]:=1946.43; arr_COEF_Table_N2[40,2]:=485.83; (* init parameter struct *) stCTRL_LIN_INTERPOLATION_PARAMS_N2.tCtrlCycleTime := T#10ms; stCTRL_LIN_INTERPOLATION_PARAMS_N2.tTaskCycleTime := T#10ms; stCTRL_LIN_INTERPOLATION_PARAMS_N2.nDataTable_NumberOfRows := INT_TO_UINT(40); (* set the addresses *) stCTRL_LIN_INTERPOLATION_PARAMS_N2.pDataTable_ADR := ADR(arr_COEF_Table_N2); stCTRL_LIN_INTERPOLATION_PARAMS_N2.nDataTable_SIZEOF := SIZEOF(arr_COEF_Table_N2); (*X-Ray Mass Attenuation Coefficients for Ar*) arr_COEF_Table_Ar[1,1]:=201.3709; arr_COEF_Table_Ar[1,2]:=6332.4; arr_COEF_Table_Ar[2,1]:=215.2655; arr_COEF_Table_Ar[2,2]:=5911.6; arr_COEF_Table_Ar[3,1]:=230.1188; arr_COEF_Table_Ar[3,2]:=5492.2; arr_COEF_Table_Ar[4,1]:=240.296; arr_COEF_Table_Ar[4,2]:=5153.8; arr_COEF_Table_Ar[5,1]:=242.354; arr_COEF_Table_Ar[5,2]:=5083; arr_COEF_Table_Ar[6,1]:=243.974; arr_COEF_Table_Ar[6,2]:=5028; arr_COEF_Table_Ar[7,1]:=244.9548; arr_COEF_Table_Ar[7,2]:=4995; arr_COEF_Table_Ar[8,1]:=245.997; arr_COEF_Table_Ar[8,2]:=50587; arr_COEF_Table_Ar[9,1]:=246.0635; arr_COEF_Table_Ar[9,2]:=50556; arr_COEF_Table_Ar[10,1]:=246.426; arr_COEF_Table_Ar[10,2]:=50385; arr_COEF_Table_Ar[11,1]:=247.0527; arr_COEF_Table_Ar[11,2]:=50090; arr_COEF_Table_Ar[12,1]:=248.5365; arr_COEF_Table_Ar[12,2]:=71652; arr_COEF_Table_Ar[13,1]:=250.104; arr_COEF_Table_Ar[13,2]:=70616; arr_COEF_Table_Ar[14,1]:=252.246; arr_COEF_Table_Ar[14,2]:=69234; arr_COEF_Table_Ar[15,1]:=262.9708; arr_COEF_Table_Ar[15,2]:=62861; arr_COEF_Table_Ar[16,1]:=281.1158; arr_COEF_Table_Ar[16,2]:=53865; arr_COEF_Table_Ar[17,1]:=300.5128; arr_COEF_Table_Ar[17,2]:=46248; arr_COEF_Table_Ar[18,1]:=313.6; arr_COEF_Table_Ar[18,2]:=41979; arr_COEF_Table_Ar[19,1]:=318.4; arr_COEF_Table_Ar[19,2]:=40556; arr_COEF_Table_Ar[20,1]:=319.68; arr_COEF_Table_Ar[20,2]:=40189; arr_COEF_Table_Ar[21,1]:=321.2482; arr_COEF_Table_Ar[21,2]:=44258; arr_COEF_Table_Ar[22,1]:=321.6; arr_COEF_Table_Ar[22,2]:=44155; arr_COEF_Table_Ar[23,1]:=326.4; arr_COEF_Table_Ar[23,2]:=42786; arr_COEF_Table_Ar[24,1]:=343.4143; arr_COEF_Table_Ar[24,2]:=38407; arr_COEF_Table_Ar[25,1]:=367.1099; arr_COEF_Table_Ar[25,2]:=33319; arr_COEF_Table_Ar[26,1]:=392.4405; arr_COEF_Table_Ar[26,2]:=28856; arr_COEF_Table_Ar[27,1]:=419.5189; arr_COEF_Table_Ar[27,2]:=24938; arr_COEF_Table_Ar[28,1]:=448.4657; arr_COEF_Table_Ar[28,2]:=21501; arr_COEF_Table_Ar[29,1]:=479.4098; arr_COEF_Table_Ar[29,2]:=18493; arr_COEF_Table_Ar[30,1]:=512.4891; arr_COEF_Table_Ar[30,2]:=15863; arr_COEF_Table_Ar[31,1]:=547.8508; arr_COEF_Table_Ar[31,2]:=13574; arr_COEF_Table_Ar[32,1]:=585.6525; arr_COEF_Table_Ar[32,2]:=11589; arr_COEF_Table_Ar[33,1]:=626.0625; arr_COEF_Table_Ar[33,2]:=9873.1; arr_COEF_Table_Ar[34,1]:=669.2609; arr_COEF_Table_Ar[34,2]:=8394.2; arr_COEF_Table_Ar[35,1]:=715.4399; arr_COEF_Table_Ar[35,2]:=7123.6; arr_COEF_Table_Ar[36,1]:=764.8052; arr_COEF_Table_Ar[36,2]:=6035.4; arr_COEF_Table_Ar[37,1]:=817.5768; arr_COEF_Table_Ar[37,2]:=5105.8; arr_COEF_Table_Ar[38,1]:=873.9896; arr_COEF_Table_Ar[38,2]:=4313.6; arr_COEF_Table_Ar[39,1]:=934.2948; arr_COEF_Table_Ar[39,2]:=3639.9; arr_COEF_Table_Ar[40,1]:=998.7612; arr_COEF_Table_Ar[40,2]:=3068.4; arr_COEF_Table_Ar[41,1]:=1067.676; arr_COEF_Table_Ar[41,2]:=2558; arr_COEF_Table_Ar[42,1]:=1141.345; arr_COEF_Table_Ar[42,2]:=2133.7; arr_COEF_Table_Ar[43,1]:=1220.098; arr_COEF_Table_Ar[43,2]:=1781.3; arr_COEF_Table_Ar[44,1]:=1304.285; arr_COEF_Table_Ar[44,2]:=1486.6; arr_COEF_Table_Ar[45,1]:=1394.281; arr_COEF_Table_Ar[45,2]:=1238; arr_COEF_Table_Ar[46,1]:=1490.486; arr_COEF_Table_Ar[46,2]:=1031.9; arr_COEF_Table_Ar[47,1]:=1593.329; arr_COEF_Table_Ar[47,2]:=861.03; arr_COEF_Table_Ar[48,1]:=1703.269; arr_COEF_Table_Ar[48,2]:=719.19; arr_COEF_Table_Ar[49,1]:=1820.795; arr_COEF_Table_Ar[49,2]:=601.34; arr_COEF_Table_Ar[50,1]:=1946.43; arr_COEF_Table_Ar[50,2]:=503.35; (* init parameter struct *) stCTRL_LIN_INTERPOLATION_PARAMS_Ar.tCtrlCycleTime := T#10ms; stCTRL_LIN_INTERPOLATION_PARAMS_Ar.tTaskCycleTime := T#10ms; stCTRL_LIN_INTERPOLATION_PARAMS_Ar.nDataTable_NumberOfRows := INT_TO_UINT(50); (* set the addresses *) stCTRL_LIN_INTERPOLATION_PARAMS_Ar.pDataTable_ADR := ADR(arr_COEF_Table_Ar); stCTRL_LIN_INTERPOLATION_PARAMS_Ar.nDataTable_SIZEOF := SIZEOF(arr_COEF_Table_Ar); (* set the mode to ACTIVE --> normal operation *) eMode := eCTRL_MODE_ACTIVE; (* reset the init flag *) bInit := FALSE; END_IF fbCTRL_LIN_INTERPOLATION_Ar( fIn:= rPhotonEnergy , fManValue:= 1 , bExtrapolate:= TRUE, eMode:= eMode, stParams:= stCTRL_LIN_INTERPOLATION_PARAMS_Ar, fOut=> , bInIsGreaterThanMaxElement=> , bInIsLessThanMinElement=> , eState=> , eErrorId=> , bError=> ); fbCTRL_LIN_INTERPOLATION_N2( fIn:= rPhotonEnergy , fManValue:= 1 , bExtrapolate:= TRUE, eMode:= eMode, stParams:= stCTRL_LIN_INTERPOLATION_PARAMS_N2, fOut=> , bInIsGreaterThanMaxElement=> , bInIsLessThanMinElement=> , eState=> , eErrorId=> , bError=> ); END_ACTION Related: * `E_GasType`_ * `GVL_PMPS`_ PRG_VGP ^^^^^^^ :: PROGRAM PRG_VGP VAR arrTable : ARRAY[1..14,1..2] OF FLOAT; arrTable_ENC : ARRAY[1..14,1..2] OF FLOAT; bInit: BOOL:=true; VGP_REQ_POS: LREAL; VGP_OUT_POS:LREAL; END_VAR IF bInit THEN (* init array with the interpolation points *) (* fIn | fOut *) arrTable[1,1] := 0; arrTable[1,2] := 0; arrTable[2,1] := 5; arrTable[2,2] := 160; arrTable[3,1] := 10; arrTable[3,2] := 270; arrTable[4,1] := 20; arrTable[4,2] := 435; arrTable[5,1] := 30; arrTable[5,2] := 570; arrTable[6,1] := 40; arrTable[6,2] := 720; arrTable[7,1] := 50; arrTable[7,2] := 854; arrTable[8,1] := 60; arrTable[8,2] := 980; arrTable[9,1] := 70; arrTable[9,2] := 1120; arrTable[10,1] := 80; arrTable[10,2] := 1270; arrTable[11,1] := 90; arrTable[11,2] := 1430; arrTable[12,1] := 95; arrTable[12,2] := 1540; arrTable[13,1] := 98; arrTable[13,2] := 1595; arrTable[14,1] := 100; arrTable[14,2] := 1680; (* reset the init flag *) bInit := FALSE; END_IF VGP_80.i_xOpenIlkOK := (fb_AT1K0_GAS_PTM_80.iq_stPtm.eState = pumpRUNNING) ; VGP_80( i_xExtIlkOK:=(fb_AT1K0_GAS_PTM_80.iq_stPtm.eState = pumpRUNNING), i_ReqPos:= , arrTable:= arrTable , q_stVGP=> ); END_PROGRAM