DUTs ---- DUT_01_Channel_NW ^^^^^^^^^^^^^^^^^ :: TYPE DUT_01_Channel_NW : STRUCT header: DUT_Header_NW; channel1: DUT_Channel_NW; END_STRUCT END_TYPE Related: * `DUT_01_Channel_NW`_ * `DUT_Channel_NW`_ * `DUT_Header_NW`_ DUT_Channel_NW ^^^^^^^^^^^^^^ :: TYPE DUT_Channel_NW : STRUCT count: DWORD; // 4 4 timing: DWORD; // 4 8 scale: WORD; // 2 10 hardwareID: ARRAY [0..15] OF BYTE; // 16 26 reserved1: BYTE; // 1 27 channel: BYTE; // 1 28 error: BYTE; // 1 29 mode: BYTE; // 1 30 scale_denominator: WORD; // 2 32 END_STRUCT END_TYPE (* typedef struct { uint32_t encoderValue; // network byte order uint32_t timing; // network byte order uint16_t scale; // network byte order char hardwareID[16]; uint8_t reserved1; uint8_t channel; uint8_t error; uint8_t mode; uint16_t scale_denominator; // network byte order } encoder_channel_t; *) DUT_Header_NW ^^^^^^^^^^^^^ :: TYPE DUT_Header_NW : STRUCT frameCount: WORD; // 2 2 reserved1: WORD; // 2 4 major: WORD; // 2 6 minor: BYTE; // 1 7 micro: BYTE; // 1 8 hardwareID: ARRAY [0..15] OF BYTE; // 16 24 reserved2: BYTE; // 1 25 channelMask: BYTE; // 1 26 errorMask: BYTE; // 1 27 mode: BYTE; // 1 28 reserved3: DWORD; // 4 32 END_STRUCT END_TYPE (* typedef struct { uint16_t frameCount; // network byte order uint8_t reserved1[2]; uint16_t majorVersion; // network byte order uint8_t minorVersion; uint8_t microVersion; char hardwareID[16]; uint8_t reserved2; uint8_t channelMask; uint8_t errorMask; uint8_t mode; uint8_t reserved3[4]; } encoder_header_t; *) E_B4C_Rh_CoatingStates ^^^^^^^^^^^^^^^^^^^^^^ :: {attribute 'qualified_only'} {attribute 'strict'} TYPE E_B4C_Rh_CoatingStates : ( Unknown := 0, B4C := 1, Rh := 2 ) UINT; END_TYPE E_Grating_States ^^^^^^^^^^^^^^^^ :: {attribute 'qualified_only'} {attribute 'strict'} TYPE E_Grating_States : ( Unknown := 0, LRG := 1, Unruled := 2, YAG := 3, MEG := 4, HEG := 5, LEG := 6 ) UINT; END_TYPE E_MR1K1_States ^^^^^^^^^^^^^^ :: {attribute 'qualified_only'} {attribute 'strict'} TYPE E_MR1K1_States : ( Unknown := 0, B4C := 1, OUT := 2 ) UINT; END_TYPE ENUM_XS_YAG_States ^^^^^^^^^^^^^^^^^^ :: {attribute 'qualified_only'} TYPE ENUM_XS_YAG_States : ( Unknown := 0, OUT := 1, YAG1 := 2, YAG2 := 3 ); END_TYPE GVLs ---- GVL_COM_Buffers ^^^^^^^^^^^^^^^ :: VAR_GLOBAL // M1K2 Serial_RXBuffer_M1K2 : ComBuffer; Serial_TXBuffer_M1K2 : ComBuffer; END_VAR GVL_M1K1 ^^^^^^^^ :: {attribute 'qualified_only'} VAR_GLOBAL // Pitch Mechanism:\ // Currently unused {attribute 'TcLinkTo' := '.diEncCnt:=TIIB[EL5042_M1K2_Pitch]^FB Inputs Channel 1^Position'} M1K1_Pitch : HOMS_PitchMechanism := (ReqPosLimHi := 24681, ReqPosLimLo := 24321, diEncPosLimHi := 10139808, diEncPosLimLo := 9950984); // Set to 50 urad before hard limits tripped during SAT END_VAR GVL_M1K1_BENDER_Constants ^^^^^^^^^^^^^^^^^^^^^^^^^ :: {attribute 'qualified_only'} VAR_GLOBAL CONSTANT // Encoder reference values in counts = nm nM1K1bendUS_ENC_REF : ULINT := 21458400; nM1K1bendDS_ENC_REF : ULINT := 21225900; // PMPS Limits for benders nM1K1bendUS_PMPS_UpperLimit : ULINT := 22100000; //21500000;//22100000; As requested by Alex R and RP, switched back again nM1K1bendUS_PMPS_LowerLimit : ULINT := 20900000; //20100000;//20900000; nM1K1bendDS_PMPS_UpperLimit : ULINT := 21800000;//21100000;//21800000; nM1K1bendDS_PMPS_LowerLimit : ULINT := 20600000;// 19800000;//20600000; END_VAR GVL_M1K1_BENDER_RTD ^^^^^^^^^^^^^^^^^^^ :: {attribute 'qualified_only'} VAR_GLOBAL // M1K1 US RTDs {attribute 'TcLinkTo' := 'TIIB[EL3202-0010_M1K1US1_M1K1US2]^RTD Inputs Channel 1^Value'} nM1K1US_RTD_1 AT %I* : INT; {attribute 'TcLinkTo' := 'TIIB[EL3202-0010_M1K1US1_M1K1US2]^RTD Inputs Channel 2^Value'} nM1K1US_RTD_2 AT %I* : INT; {attribute 'TcLinkTo' := 'TIIB[EL3202-0010_M1K1US3_M1K1DS1]^RTD Inputs Channel 1^Value'} nM1K1US_RTD_3 AT %I* : INT; // M1K1 DS RTDs {attribute 'TcLinkTo' := 'TIIB[EL3202-0010_M1K1US3_M1K1DS1]^RTD Inputs Channel 2^Value'} nM1K1DS_RTD_1 AT %I* : INT; {attribute 'TcLinkTo' := 'TIIB[EL3202-0010_M1K1DS2_M1K1DS3]^RTD Inputs Channel 1^Value'} nM1K1DS_RTD_2 AT %I* : INT; {attribute 'TcLinkTo' := 'TIIB[EL3202-0010_M1K1DS2_M1K1DS3]^RTD Inputs Channel 2^Value'} nM1K1DS_RTD_3 AT %I* : INT; END_VAR GVL_M1K1_Constants ^^^^^^^^^^^^^^^^^^ :: {attribute 'qualified_only'} VAR_GLOBAL CONSTANT // Encoder reference values in counts = nm // Enc reference values from Axilon FAT nYUP_ENC_REF : ULINT := 13008545; nYDWN_ENC_REF : ULINT := 11158257; nXUP_ENC_REF : ULINT := 19831295; nXDWN_ENC_REF : ULINT := 19604132; (* previous values nXUP_ENC_REF : ULINT := 19649910; nXDWN_ENC_REF : ULINT := 19609100; *) END_VAR GVL_M1K2 ^^^^^^^^ :: {attribute 'qualified_only'} VAR_GLOBAL // Pitch Mechanism: // Currently Unused {attribute 'TcLinkTo' := '.diEncCnt:=TIIB[EL5042_M1K2_Pitch]^FB Inputs Channel 1^Position'} M1K2_Pitch : HOMS_PitchMechanism := (ReqPosLimHi := 200, ReqPosLimLo := -30, diEncPosLimHi := 10121210, diEncPosLimLo := 10004610); // Set to 50 urad before hard limits tripped during SAT END_VAR GVL_M1K2_Constants ^^^^^^^^^^^^^^^^^^ :: {attribute 'qualified_only'} VAR_GLOBAL CONSTANT // Encoder reference values in counts = nm // Enc reference values after alignment 3-13-20 nYLEFT_ENC_REF : ULINT := 99171678; nYRIGHT_ENC_REF : ULINT := 101371326; nXUP_ENC_REF : ULINT := 19501048; nXDWN_ENC_REF : ULINT := 20872028; // Lever arm for Yright/Yleft -> Roll about Z-axis fRollLeverArm_um : REAL := 717000; // lever arm for Yright/Yleft axes in um END_VAR GVL_M2K2 ^^^^^^^^ :: {attribute 'qualified_only'} VAR_GLOBAL CONSTANT // Encoder reference values in counts = nm // Put encoder reference values for nominal 0 here nM2K2X_ENC_REF : ULINT := 6077000; //these numbers nM2K2Y_ENC_REF : ULINT := 5975460; //are nM2K2rX_ENC_REF : ULINT := 50412360;//real END_VAR GVL_M3K2 ^^^^^^^^ :: {attribute 'qualified_only'} VAR_GLOBAL CONSTANT // Encoder reference values in counts = nm // Put encoder reference values for nominal 0 here nM3K2X_ENC_REF : ULINT := 5951195; nM3K2Y_ENC_REF : ULINT := 5857203; nM3K2rY_ENC_REF : ULINT := 39991700; nM3K2US_ENC_REF : ULINT := 1234567; //these numbers nM3K2DS_ENC_REF : ULINT := 1234567; //are not real!! (* // PMPS Limits for benders - need to identify these nM3K2US_PMPS_UpperLimit : ULINT := 21500000;//22100000; nM3K2US_PMPS_LowerLimit : ULINT := 20100000;//20900000; nM3K2DS_PMPS_UpperLimit : ULINT := 21100000;//21800000; nM3K2DS_PMPS_LowerLimit : ULINT := 19800000;//20600000; *) END_VAR VAR_GLOBAL // M3K2 US RTDs {attribute 'TcLinkTo' := 'TIIB[EL3202-0010_M3K2US1_M3K2US2]^RTD Inputs Channel 1^Value'} nM3K2US_RTD_1 AT %I* : INT; {attribute 'TcLinkTo' := 'TIIB[EL3202-0010_M3K2US1_M3K2US2]^RTD Inputs Channel 2^Value'} nM3K2US_RTD_2 AT %I* : INT; // M3K2 DS RTDs {attribute 'TcLinkTo' := 'TIIB[EL3202-0010_M3K2US3_M3K2DS1]^RTD Inputs Channel 2^Value'} nM3K2DS_RTD_1 AT %I* : INT; {attribute 'TcLinkTo' := 'TIIB[EL3202-0010_M3K2DS2_M3K2DS3]^RTD Inputs Channel 2^Value'} nM3K2DS_RTD_3 AT %I* : INT; END_VAR GVL_M4K2 ^^^^^^^^ :: {attribute 'qualified_only'} VAR_GLOBAL CONSTANT // Encoder reference values in counts = nm // Put encoder reference values for nominal 0 here nM4K2X_ENC_REF : ULINT := 5902073; nM4K2Y_ENC_REF : ULINT := 6000313; nM4K2rX_ENC_REF : ULINT := 50657020; nM4K2US_ENC_REF : ULINT := 1234567; //these numbers nM4K2DS_ENC_REF : ULINT := 1234567; //are not real!! // PMPS Limits for benders - need to identify these nM4K2US_PMPS_UpperLimit : ULINT := 21500000;//22100000; nM4K2US_PMPS_LowerLimit : ULINT := 20100000;//20900000; nM4K2DS_PMPS_UpperLimit : ULINT := 21100000;//21800000; nM4K2DS_PMPS_LowerLimit : ULINT := 19800000;//20600000; END_VAR VAR_GLOBAL // M4K2 US RTDs {attribute 'TcLinkTo' := 'TIIB[EL3202-0010_M4K2US1_M4K2US2]^RTD Inputs Channel 1^Value'} nM4K2US_RTD_1 AT %I* : INT; {attribute 'TcLinkTo' := 'TIIB[EL3202-0010_M4K2US1_M4K2US2]^RTD Inputs Channel 2^Value'} nM4K2US_RTD_2 AT %I* : INT; {attribute 'TcLinkTo' := 'TIIB[EL3202-0010_M4K2US3_M4K2DS1]^RTD Inputs Channel 1^Value'} nM4K2US_RTD_3 AT %I* : INT; // M4K2 DS RTDs {attribute 'TcLinkTo' := 'TIIB[EL3202-0010_M4K2US3_M4K2DS1]^RTD Inputs Channel 2^Value'} nM4K2DS_RTD_1 AT %I* : INT; END_VAR GVL_PMPS ^^^^^^^^ :: {attribute 'qualified_only'} VAR_GLOBAL {attribute 'pytmc' := 'pv: PLC:RIX:OPTICS:ARB:01'} fbArbiter1: FB_Arbiter(1); {attribute 'pytmc' := 'pv: PLC:RIX:OPTICS:ARB:02'} fbArbiter2: FB_Arbiter(2); {attribute 'pytmc' := 'pv: PLC:RIX:OPTICS:FFO:01'} {attribute 'TcLinkTo' := '.q_xFastFaultOut:=TIIB[PMPS_FFO]^Channel 1^Output'} fbFastFaultOutput1: FB_HardwareFFOutput := (bAutoReset := TRUE , i_sNetID:='172.21.42.126.1.1' ); {attribute 'pytmc' := 'pv: PLC:RIX:OPTICS:FFO:02'} {attribute 'TcLinkTo' := '.q_xFastFaultOut:=TIIB[PMPS_FFO]^Channel 2^Output'} fbFastFaultOutput2: FB_HardwareFFOutput := (bAutoReset := TRUE, i_sNetID:='172.21.42.126.1.1'); rPhotonEnergy: REAL; END_VAR GVL_SerialIO ^^^^^^^^^^^^ :: VAR_GLOBAL //Better have your inputs and outputs! // M1K2 Serial_stComIn_M1K2 AT %I* : EL6inData22B (*KL6inData22B*); Serial_stComOut_M1K2 AT %Q* : EL6outData22B (*KL6outData22B*); END_VAR GVL_States ^^^^^^^^^^ :: {attribute 'qualified_only'} VAR_GLOBAL stDefaultOffsetY : ST_PositionState := ( fDelta:=2000, fVelocity:=100, fAccel:=5050, fDecel:=5050, bMoveOk:=TRUE, bValid:=TRUE, bUseRawCounts:=TRUE ); stDefaultOffsetX : ST_PositionState := ( fDelta:=10000, fVelocity:=150, fAccel:=1000, fDecel:=1000, bMoveOk:=TRUE, bValid:=TRUE, bUseRawCounts:=TRUE ); stDefaultKBX : ST_PositionState := ( fDelta:=5, fVelocity:=0.3, fAccel:=100, fDecel:=100, bMoveOk:=TRUE, bValid:=TRUE, bUseRawCounts:=TRUE ); stDefaultKBY : ST_PositionState := ( fDelta:=5, fVelocity:=0.3, fAccel:=10, fDecel:=10, bMoveOk:=TRUE, bValid:=TRUE, bUseRawCounts:=TRUE ); END_VAR Main ^^^^ :: VAR_GLOBAL (* Only includes motor definitions for the IOC These are hard-coded to be Main.M#, but are very convenient to store in a GVL, hence the confusing namespace here This should be refactored once the IOC supports arbitrary ads paths for motors *) (*MR1K2*) // Motors {attribute 'TcLinkTo' := '.bLimitForwardEnable:=TIIB[EL7047_M1K2_Yleft]^STM Status^Status^Digital input 1; .bLimitBackwardEnable:=TIIB[EL7047_M1K2_Yleft]^STM Status^Status^Digital input 2; .nRawEncoderULINT:=TIIB[EL5042_M1K2_Yleftright]^FB Inputs Channel 1^Position'} {attribute 'pytmc' := ' pv: MR1K2:SWITCH:MMS:YLEFT '} M1 : ST_MotionStage := (fVelocity:=100.0, nEnableMode:=ENUM_StageEnableMode.ALWAYS, bPowerSelf:=False); // M1K2 Yleft fbMotionStage_m1 : FB_MotionStage; {attribute 'TcLinkTo' := '.bLimitForwardEnable:=TIIB[EL7047_M1K2_Yright]^STM Status^Status^Digital input 1; .bLimitBackwardEnable:=TIIB[EL7047_M1K2_Yright]^STM Status^Status^Digital input 2; .nRawEncoderULINT:=TIIB[EL5042_M1K2_Yleftright]^FB Inputs Channel 2^Position'} {attribute 'pytmc' := ' pv: MR1K2:SWITCH:MMS:YRIGHT '} M2 : ST_MotionStage := (fVelocity:=100.0, nEnableMode:=ENUM_StageEnableMode.ALWAYS, bPowerSelf:=True); // M1K2 Yright fbMotionStage_m2 : FB_MotionStage; {attribute 'TcLinkTo' := '.bLimitForwardEnable:=TIIB[EL7047_M1K2_Xup]^STM Status^Status^Digital input 1; .bLimitBackwardEnable:=TIIB[EL7047_M1K2_Xup]^STM Status^Status^Digital input 2; .nRawEncoderULINT:=TIIB[EL5042_M1K2_Xupdwn]^FB Inputs Channel 1^Position'} {attribute 'pytmc' := ' pv: MR1K2:SWITCH:MMS:XUP '} M3 : ST_MotionStage := (fVelocity:=150.0, nEnableMode:=ENUM_StageEnableMode.ALWAYS, bPowerSelf:=True); // M1K2 Xup fbMotionStage_m3 : FB_MotionStage; {attribute 'TcLinkTo' := '.bLimitForwardEnable:=TIIB[EL7047_M1K2_Xdwn]^STM Status^Status^Digital input 1; .bLimitBackwardEnable:=TIIB[EL7047_M1K2_Xdwn]^STM Status^Status^Digital input 2; .nRawEncoderULINT:=TIIB[EL5042_M1K2_Xupdwn]^FB Inputs Channel 1^Position'} {attribute 'pytmc' := ' pv: MR1K2:SWITCH:MMS:XDWN '} M4 : ST_MotionStage := (fVelocity:=150.0, nEnableMode:=ENUM_StageEnableMode.ALWAYS, bPowerSelf:=True); // M1K2 Xdwn fbMotionStage_m4 : FB_MotionStage; {attribute 'TcLinkTo' := '.bLimitForwardEnable:=TIIB[EL7047_M1K2_PitchCoarse]^STM Status^Status^Digital input 1; .bLimitBackwardEnable:=TIIB[EL7047_M1K2_PitchCoarse]^STM Status^Status^Digital input 2'} {attribute 'pytmc' := ' pv: MR1K2:SWITCH:MMS:PITCH '} M5 : ST_MotionStage := (fVelocity:=30.0, nEnableMode:=ENUM_StageEnableMode.DURING_MOTION, bPowerSelf:=True); // M1K2 Pitch Stepper (*SP1K1-Mono*) {attribute 'pytmc' := ' pv: SP1K1:MONO:MMS:M_PI '} {attribute 'TcLinkTo' := '.bLimitForwardEnable:=TIIB[m_pi_m]^STM Status^Status^Digital input 1; .bLimitBackwardEnable:=TIIB[m_pi_m]^STM Status^Status^Digital input 2; .nRawEncoderULINT:=TIIB[m_pi_up_dwn_e]^FB Inputs Channel 2^Position'} M6: ST_MotionStage:=(nEnableMode:=ENUM_StageEnableMode.ALWAYS, fVelocity:=200.0, bPowerSelf:=True); // M_PI, urad {attribute 'pytmc' := ' pv: SP1K1:MONO:MMS:G_PI '} {attribute 'TcLinkTo' := '.bLimitForwardEnable:=TIIB[g_pi_m]^STM Status^Status^Digital input 1; .bLimitBackwardEnable:=TIIB[g_pi_m]^STM Status^Status^Digital input 2; .nRawEncoderULINT:=TIIB[g_pi_up_dwn_e]^FB Inputs Channel 1^Position'} M7: ST_MotionStage:=(nEnableMode:=ENUM_StageEnableMode.ALWAYS, fVelocity:=200.0, bPowerSelf:=True); // G_PI, urad {attribute 'pytmc' := ' pv: SP1K1:MONO:MMS:M_H '} {attribute 'TcLinkTo' := '.bLimitForwardEnable:=TIIB[m_h_m]^STM Status^Status^Digital input 1; .bLimitBackwardEnable:=TIIB[m_h_m]^STM Status^Status^Digital input 2; .nRawEncoderULINT:=TIIB[m_h_e-g_h_e]^FB Inputs Channel 1^Position'} M8: ST_MotionStage:=(nEnableMode:=ENUM_StageEnableMode.DURING_MOTION, fVelocity:=500.0, bPowerSelf:=True); // M_H, um {attribute 'pytmc' := ' pv: SP1K1:MONO:MMS:G_H '} {attribute 'TcLinkTo' := '.bLimitForwardEnable:=TIIB[g_h_m]^STM Status^Status^Digital input 1; .bLimitBackwardEnable:=TIIB[g_h_m]^STM Status^Status^Digital input 2; .nRawEncoderULINT:=TIIB[m_h_e-g_h_e]^FB Inputs Channel 2^Position'} M9: ST_MotionStage:=(nEnableMode:=ENUM_StageEnableMode.DURING_MOTION, fVelocity:=1000.0, bPowerSelf:=False); // G_H, um {attribute 'pytmc' := ' pv: SP1K1:MONO:MMS:SD_V '} {attribute 'TcLinkTo' := '.bLimitForwardEnable:=TIIB[s_io_m]^STM Status^Status^Digital input 1; .bLimitBackwardEnable:=TIIB[s_io_m]^STM Status^Status^Digital input 2'} M10: ST_MotionStage:=(nEnableMode:=ENUM_StageEnableMode.DURING_MOTION, fVelocity:=500.0, bPowerSelf:=True); // SD_V, um {attribute 'pytmc' := ' pv: SP1K1:MONO:MMS:SD_ROT '} // no limits on this motion M11: ST_MotionStage:=(nEnableMode:=ENUM_StageEnableMode.DURING_MOTION, fVelocity:=500.0, bPowerSelf:=True); // SD_R, urad (*MR1K1*) // Should move before MR1K2 and re-number each motor, lots of work // need to fix Axis IDs for IOC to work // For now just want functional PLC project // Motors {attribute 'TcLinkTo' := '.bLimitBackwardEnable:=TIIB[EL7047_M1K1_Ydwn]^STM Status^Status^Digital input 2; .bLimitForwardEnable:=TIIB[EL7047_M1K1_Ydwn]^STM Status^Status^Digital input 1; .nRawEncoderULINT:=TIIB[EL5042_M1K1_Yupdwn]^FB Inputs Channel 1^Position'} {attribute 'pytmc' := ' pv: MR1K1:BEND:MMS:YUP '} M12 : ST_MotionStage := (fVelocity:=100.0, nEnableMode:=ENUM_StageEnableMode.ALWAYS, bPowerSelf:=False); // M1K1 Yup fbMotionStage_m12 : FB_MotionStage; {attribute 'TcLinkTo' := '.bLimitForwardEnable:=TIIB[EL7047_M1K1_Ydwn]^STM Status^Status^Digital input 1; .bLimitBackwardEnable:=TIIB[EL7047_M1K1_Ydwn]^STM Status^Status^Digital input 2'} {attribute 'pytmc' := ' pv: MR1K1:BEND:MMS:YDWN '} M13 : ST_MotionStage := (fVelocity:=100.0, nEnableMode:=ENUM_StageEnableMode.ALWAYS, bPowerSelf:=True); // M1K1 Ydwn fbMotionStage_m13 : FB_MotionStage; {attribute 'TcLinkTo' := '.bLimitForwardEnable:=TIIB[EL7047_M1K1_Xup]^STM Status^Status^Digital input 1; .bLimitBackwardEnable:=TIIB[EL7047_M1K1_Xup]^STM Status^Status^Digital input 2; .nRawEncoderULINT:=TIIB[EL5042_M1K1_Xupdwn]^FB Inputs Channel 1^Position'} {attribute 'pytmc' := ' pv: MR1K1:BEND:MMS:XUP '} M14 : ST_MotionStage := (fVelocity:=150.0, nEnableMode:=ENUM_StageEnableMode.ALWAYS, bPowerSelf:=False); // M1K1 Xup fbMotionStage_m14 : FB_MotionStage; {attribute 'TcLinkTo' := '.bLimitForwardEnable:=TIIB[EL7047_M1K1_Xdwn]^STM Status^Status^Digital input 1; .bLimitBackwardEnable:=TIIB[EL7047_M1K1_Xdwn]^STM Status^Status^Digital input 2'} {attribute 'pytmc' := ' pv: MR1K1:BEND:MMS:XDWN '} M15 : ST_MotionStage := (fVelocity:=150.0, nEnableMode:=ENUM_StageEnableMode.ALWAYS, bPowerSelf:=True); // M1K1 Xdwn fbMotionStage_m15 : FB_MotionStage; {attribute 'TcLinkTo' := '.bLimitForwardEnable:=TIIB[EL7047_M1K1_PitchCoarse]^STM Status^Status^Digital input 1; .bLimitBackwardEnable:=TIIB[EL7047_M1K1_PitchCoarse]^STM Status^Status^Digital input 2; .nRawEncoderULINT:=TIIB[EL5042_M1K1_Pitch]^FB Inputs Channel 1^Position'} {attribute 'pytmc' := ' pv: MR1K1:BEND:MMS:PITCH '} M16 : ST_MotionStage := (fVelocity:=30.0, nEnableMode:=ENUM_StageEnableMode.ALWAYS, bPowerSelf:=True); // M1K1 Pitch Stepper {attribute 'TcLinkTo' := '.bLimitBackwardEnable:=TIIB[EL7041_M1K1_BEND_US]^STM Status^Status^Digital input 2; .nRawEncoderULINT := TIIB[EL5042_M1K1_BEND_USDS]^FB Inputs Channel 1^Position'} {attribute 'pytmc' := ' pv: MR1K1:BEND:MMS:US '} // unlinking this .bLimitForwardEnable :=TIIB[EL7041_M1K1_BEND_US]^STM Status^Status^Digital input 1; M17 : ST_MotionStage := (nEnableMode:=ENUM_StageEnableMode.DURING_MOTION, bPowerSelf:=TRUE); //MR1K1 US BEND fbMotionStage_m17 : FB_MotionStage; {attribute 'TcLinkTo' := '.bLimitForwardEnable :=TIIB[EL7041_M1K1_BEND_DS]^STM Status^Status^Digital input 1; .bLimitBackwardEnable:=TIIB[EL7041_M1K1_BEND_DS]^STM Status^Status^Digital input 2; .nRawEncoderULINT := TIIB[EL5042_M1K1_BEND_USDS]^FB Inputs Channel 2^Position'} {attribute 'pytmc' := ' pv: MR1K1:BEND:MMS:DS '} M18 : ST_MotionStage := (nEnableMode:=ENUM_StageEnableMode.DURING_MOTION, bPowerSelf:=TRUE); //MR1K1 DS BEND fbMotionStage_m18 : FB_MotionStage; (*SL1K2*) // Motors {attribute 'TcLinkTo' := '.bLimitForwardEnable:=TIIB[EL7047_SL1K2_PITCH]^STM Status^Status^Digital input 2; .bLimitBackwardEnable:=TIIB[EL7047_SL1K2_PITCH]^STM Status^Status^Digital input 1; .nRawEncoderULINT := TIIB[EL5042_SL1K2_PITCH_VERT]^FB Inputs Channel 1^Position'} {attribute 'pytmc' := ' pv: SL1K2:EXIT:MMS:PITCH '} M19 : ST_MotionStage := (sName:= 'SL1K2:EXIT:MMS:PITCH',fVelocity :=0.12);// Air Pitch {attribute 'TcLinkTo' := '.bLimitForwardEnable:=TIIB[EL7047_SL1K2_VERT]^STM Status^Status^Digital input 1; .bLimitBackwardEnable:=TIIB[EL7047_SL1K2_VERT]^STM Status^Status^Digital input 2; .nRawEncoderULINT := TIIB[EL5042_SL1K2_PITCH_VERT]^FB Inputs Channel 2^Position'} {attribute 'pytmc' := ' pv: SL1K2:EXIT:MMS:VERT '} M20 : ST_MotionStage := (sName:= 'SL1K2:EXIT:MMS:VERT',fVelocity :=0.3); // Air Vertical {attribute 'TcLinkTo' := '.bLimitForwardEnable:=TIIB[EL7047_SL1K2_ROLL]^STM Status^Status^Digital input 2; .bLimitBackwardEnable:=TIIB[EL7047_SL1K2_ROLL]^STM Status^Status^Digital input 1; .nRawEncoderULINT := TIIB[EL5042_SL1K2_ROLL_GAP]^FB Inputs Channel 1^Position'} {attribute 'pytmc' := ' pv: SL1K2:EXIT:MMS:ROLL '} M21 : ST_MotionStage := (sName:= 'SL1K2:EXIT:MMS:ROLL',fVelocity :=0.24); // Air Roll {attribute 'TcLinkTo' := '.bLimitForwardEnable:=TIIB[EL7047_SL1K2_GAP]^STM Status^Status^Digital input 1; .bLimitBackwardEnable:=TIIB[EL7047_SL1K2_GAP]^STM Status^Status^Digital input 2; .nRawEncoderULINT := TIIB[EL5042_SL1K2_ROLL_GAP]^FB Inputs Channel 2^Position'} {attribute 'pytmc' := ' pv: SL1K2:EXIT:MMS:GAP '} M22 : ST_MotionStage := (sName:= 'SL1K2:EXIT:MMS:GAP',fVelocity :=0.1); // GAP {attribute 'TcLinkTo' := '.bLimitForwardEnable:=TIIB[EL7047_SL1K2_YAG]^STM Status^Status^Digital input 2; .bLimitBackwardEnable:=TIIB[EL7047_SL1K2_YAG]^STM Status^Status^Digital input 1; .nRawEncoderULINT := TIIB[EL5042_SL1K2_YAG]^FB Inputs Channel 1^Position'} {attribute 'pytmc' := ' pv: SL1K2:EXIT:MMS:YAG '} M23 : ST_MotionStage := (sName:= 'SL1K2:EXIT:MMS:YAG',fVelocity :=0.5); // YAG // ST1K1-ZOS-MMS {attribute 'pytmc' := 'pv: ST1K1:ZOS:MMS'} {attribute 'TcLinkTo' := '.bLimitForwardEnable := TIIB[ST1K1-EL7041]^STM Status^Status^Digital input 1; .bLimitBackwardEnable := TIIB[ST1K1-EL7041]^STM Status^Status^Digital input 2; .nRawEncoderULINT :=TIIB[ST1K1-EL5042]^FB Inputs Channel 1^Position; .bBrakeRelease := TIIB[ST1K1-EL2008]^Channel 1^Output'} M24: ST_MotionStage := (sName := 'ST1K1:ZOS:MMS'); // MR2K2-FLAT axes {attribute 'pytmc' := 'pv: MR2K2:FLAT:MMS:X'} {attribute 'TcLinkTo' := '.bLimitForwardEnable:=TIIB[EL7041_M2K2X]^STM Status^Status^Digital input 1; .bLimitBackwardEnable:=TIIB[EL7041_M2K2X]^STM Status^Status^Digital input 2; .nRawEncoderULINT:=TIIB[EL5042_M2K2X_M2K2Y]^FB Inputs Channel 1^Position'} M25 : ST_MotionStage := (nEnableMode:=ENUM_StageEnableMode.ALWAYS, bPowerSelf:=FALSE); //X mot fbMotionStageM25 : FB_MotionStage; {attribute 'pytmc' := 'pv: MR2K2:FLAT:MMS:Y'} {attribute 'TcLinkTo' := '.bLimitForwardEnable:=TIIB[EL7041_M2K2Y]^STM Status^Status^Digital input 1; .bLimitBackwardEnable:=TIIB[EL7041_M2K2Y]^STM Status^Status^Digital input 2; .nRawEncoderULINT:=TIIB[EL5042_M2K2X_M2K2Y]^FB Inputs Channel 2^Position'} M26 : ST_MotionStage := (nEnableMode:=ENUM_StageEnableMode.ALWAYS, bPowerSelf:=TRUE); //Y mot fbMotionStageM26 : FB_MotionStage; {attribute 'pytmc' := 'pv: MR2K2:FLAT:MMS:PITCH'} {attribute 'TcLinkTo' := '.bLimitForwardEnable:=TIIB[EL7041_M2K2rX]^STM Status^Status^Digital input 2; .bLimitBackwardEnable:=TIIB[EL7041_M2K2rX]^STM Status^Status^Digital input 1; .nRawEncoderULINT:=TIIB[EL5042_M2K2rX]^FB Inputs Channel 1^Position'} M27 : ST_MotionStage := (nEnableMode:=ENUM_StageEnableMode.ALWAYS, bPowerSelf:=TRUE); //Pitch mot fbMotionStageM27 : FB_MotionStage; // MR3K2-KBH axes {attribute 'pytmc' := 'pv: MR3K2:KBH:MMS:X'} {attribute 'TcLinkTo' := '.bLimitForwardEnable:=TIIB[EL7041_M3K2X]^STM Status^Status^Digital input 1; .bLimitBackwardEnable:=TIIB[EL7041_M3K2X]^STM Status^Status^Digital input 2; .nRawEncoderULINT:=TIIB[EL5042_M3K2X_M3K2Y]^FB Inputs Channel 1^Position'} M28 : ST_MotionStage := (nEnableMode:=ENUM_StageEnableMode.ALWAYS, bPowerSelf:=TRUE); //X mot fbMotionStageM28 : FB_MotionStage; {attribute 'pytmc' := 'pv: MR3K2:KBH:MMS:Y'} {attribute 'TcLinkTo' := '.bLimitForwardEnable:=TIIB[EL7041_M3K2Y]^STM Status^Status^Digital input 1; .bLimitBackwardEnable:=TIIB[EL7041_M3K2Y]^STM Status^Status^Digital input 2; .nRawEncoderULINT:=TIIB[EL5042_M3K2X_M3K2Y]^FB Inputs Channel 2^Position'} M29 : ST_MotionStage := (nEnableMode:=ENUM_StageEnableMode.ALWAYS, bPowerSelf:=FALSE); //Y mot fbMotionStageM29 : FB_MotionStage; {attribute 'pytmc' := 'pv: MR3K2:KBH:MMS:PITCH'} {attribute 'TcLinkTo' := '.bLimitForwardEnable:=TIIB[EL7041_M3K2rY]^STM Status^Status^Digital input 1; .bLimitBackwardEnable:=TIIB[EL7041_M3K2ry]^STM Status^Status^Digital input 2; .nRawEncoderULINT:=TIIB[EL5042_M3K2rY]^FB Inputs Channel 1^Position'} M30 : ST_MotionStage := (nEnableMode:=ENUM_StageEnableMode.ALWAYS, bPowerSelf:=TRUE); //Pitch mot fbMotionStageM30 : FB_MotionStage; {attribute 'pytmc' := ' pv: MR3K2:KBH:MMS:BEND:US'} {attribute 'TcLinkTo' := '.bLimitForwardEnable :=TIIB[EL7041_M3K2_BEND_US]^STM Status^Status^Digital input 1; .bLimitBackwardEnable:=TIIB[EL7041_M3K2_BEND_US]^STM Status^Status^Digital input 2; .nRawEncoderULINT:= TIIB[EL5042_M3K2_BEND_USDS]^FB Inputs Channel 1^Position'} M31 : ST_MotionStage := (nEnableMode:=ENUM_StageEnableMode.DURING_MOTION, bPowerSelf:=TRUE); //MR3K2 US BEND fbMotionStageM31 : FB_MotionStage; {attribute 'pytmc' := 'pv: MR3K2:KBH:MMS:BEND:DS'} {attribute 'TcLinkTo' := '.bLimitForwardEnable :=TIIB[EL7041_M3K2_BEND_DS]^STM Status^Status^Digital input 1; .bLimitBackwardEnable:=TIIB[EL7041_M3K2_BEND_DS]^STM Status^Status^Digital input 2; .nRawEncoderULINT:= TIIB[EL5042_M3K2_BEND_USDS]^FB Inputs Channel 2^Position'} M32 : ST_MotionStage := (nEnableMode:=ENUM_StageEnableMode.DURING_MOTION, bPowerSelf:=TRUE); //MR3K2 DS BEND fbMotionStageM32 : FB_MotionStage; // MR4K2-KBV axes {attribute 'pytmc' := 'pv: MR4K2:KBV:MMS:X'} {attribute 'TcLinkTo' := '.bLimitForwardEnable:=TIIB[EL7041_M4K2X]^STM Status^Status^Digital input 1; .bLimitBackwardEnable:=TIIB[EL7041_M4K2X]^STM Status^Status^Digital input 2; .nRawEncoderULINT:=TIIB[EL5042_M4K2X_M4K2Y]^FB Inputs Channel 1^Position'} M33 : ST_MotionStage := (nEnableMode:=ENUM_StageEnableMode.ALWAYS, bPowerSelf:=FALSE); //X mot fbMotionStageM33 : FB_MotionStage; {attribute 'pytmc' := 'pv: MR4K2:KBV:MMS:Y'} {attribute 'TcLinkTo' := '.bLimitForwardEnable:=TIIB[EL7041_M4K2Y]^STM Status^Status^Digital input 1; .bLimitBackwardEnable:=TIIB[EL7041_M4K2Y]^STM Status^Status^Digital input 2; .nRawEncoderULINT:=TIIB[EL5042_M4K2X_M4K2Y]^FB Inputs Channel 2^Position'} M34 : ST_MotionStage := (nEnableMode:=ENUM_StageEnableMode.ALWAYS, bPowerSelf:=TRUE); //Y mot fbMotionStageM34 : FB_MotionStage; {attribute 'pytmc' := 'pv: MR4K2:KBV:MMS:PITCH'} {attribute 'TcLinkTo' := '.bLimitForwardEnable:=TIIB[EL7041_M4K2rX]^STM Status^Status^Digital input 1; .bLimitBackwardEnable:=TIIB[EL7041_M4K2rX]^STM Status^Status^Digital input 2; .nRawEncoderULINT:=TIIB[EL5042_M4K2rX]^FB Inputs Channel 1^Position'} M35 : ST_MotionStage := (nEnableMode:=ENUM_StageEnableMode.ALWAYS, bPowerSelf:=TRUE); //Pitch mot fbMotionStageM35 : FB_MotionStage; {attribute 'pytmc' := ' pv: MR4K2:KBV:MMS:BEND:US'} {attribute 'TcLinkTo' := '.bLimitForwardEnable :=TIIB[EL7041_M4K2_BEND_US]^STM Status^Status^Digital input 1; .bLimitBackwardEnable:=TIIB[EL7041_M4K2_BEND_US]^STM Status^Status^Digital input 2; .nRawEncoderULINT:= TIIB[EL5042_M4K2_BEND_USDS]^FB Inputs Channel 1^Position'} M36 : ST_MotionStage := (nEnableMode:=ENUM_StageEnableMode.DURING_MOTION, bPowerSelf:=TRUE); //MR4K2 US BEND fbMotionStageM36 : FB_MotionStage; {attribute 'pytmc' := 'pv: MR4K2:KBV:MMS:BEND:DS'} {attribute 'TcLinkTo' := '.bLimitForwardEnable :=TIIB[EL7041_M4K2_BEND_DS]^STM Status^Status^Digital input 1; .bLimitBackwardEnable:=TIIB[EL7041_M4K2_BEND_DS]^STM Status^Status^Digital input 2; .nRawEncoderULINT:= TIIB[EL5042_M4K2_BEND_USDS]^FB Inputs Channel 2^Position'} M37 : ST_MotionStage := (nEnableMode:=ENUM_StageEnableMode.DURING_MOTION, bPowerSelf:=TRUE); //MR4K2 DS BEND fbMotionStageM37 : FB_MotionStage; sio_current AT%I* : UINT; sio_load AT%I* : UINT; dummyBool: BOOL; END_VAR POUs ---- CheckBounds ^^^^^^^^^^^ :: // Implicitly generated code : DO NOT EDIT FUNCTION CheckBounds : DINT VAR_INPUT index, lower, upper: DINT; END_VAR // Implicitly generated code : Only an Implementation suggestion {noflow} IF index < lower THEN CheckBounds := lower; ELSIF index > upper THEN CheckBounds := upper; ELSE CheckBounds := index; END_IF {flow} END_FUNCTION CheckDivDInt ^^^^^^^^^^^^ :: // Implicitly generated code : DO NOT EDIT FUNCTION CheckDivDInt : DINT VAR_INPUT divisor:DINT; END_VAR // Implicitly generated code : Only an Implementation suggestion {noflow} IF divisor = 0 THEN CheckDivDInt:=1; ELSE CheckDivDInt:=divisor; END_IF; {flow} END_FUNCTION CheckDivLInt ^^^^^^^^^^^^ :: // Implicitly generated code : DO NOT EDIT FUNCTION CheckDivLInt : LINT VAR_INPUT divisor:LINT; END_VAR // Implicitly generated code : Only an Implementation suggestion {noflow} IF divisor = 0 THEN CheckDivLInt:=1; ELSE CheckDivLInt:=divisor; END_IF; {flow} END_FUNCTION CheckDivLReal ^^^^^^^^^^^^^ :: // Implicitly generated code : DO NOT EDIT FUNCTION CheckDivLReal : LREAL VAR_INPUT divisor:LREAL; END_VAR // Implicitly generated code : Only an Implementation suggestion {noflow} IF divisor = 0 THEN CheckDivLReal:=1; ELSE CheckDivLReal:=divisor; END_IF; {flow} END_FUNCTION CheckDivReal ^^^^^^^^^^^^ :: // Implicitly generated code : DO NOT EDIT FUNCTION CheckDivReal : REAL VAR_INPUT divisor:REAL; END_VAR // Implicitly generated code : Only an Implementation suggestion {noflow} IF divisor = 0 THEN CheckDivReal:=1; ELSE CheckDivReal:=divisor; END_IF; {flow} END_FUNCTION CheckLRangeSigned ^^^^^^^^^^^^^^^^^ :: // Implicitly generated code : DO NOT EDIT FUNCTION CheckLRangeSigned : LINT VAR_INPUT value, lower, upper: LINT; END_VAR // Implicitly generated code : Only an Implementation suggestion {noflow} IF (value < lower) THEN CheckLRangeSigned := lower; ELSIF(value > upper) THEN CheckLRangeSigned := upper; ELSE CheckLRangeSigned := value; END_IF {flow} END_FUNCTION CheckLRangeUnsigned ^^^^^^^^^^^^^^^^^^^ :: // Implicitly generated code : DO NOT EDIT FUNCTION CheckLRangeUnsigned : ULINT VAR_INPUT value, lower, upper: ULINT; END_VAR // Implicitly generated code : Only an Implementation suggestion {noflow} IF (value < lower) THEN CheckLRangeUnsigned := lower; ELSIF(value > upper) THEN CheckLRangeUnsigned := upper; ELSE CheckLRangeUnsigned := value; END_IF {flow} END_FUNCTION CheckPointer ^^^^^^^^^^^^ :: // Implicitly generated code : DO NOT EDIT FUNCTION CheckPointer : POINTER TO BYTE VAR_INPUT ptToTest : POINTER TO BYTE; // Destination address of the pointer iSize : DINT; // Size of the type the pointer points to. (e.g: 20 for POINTER TO ARRAY [0..9] OF INT) iGran : DINT; // Granularity of the pointer access. This is the size of the biggest non-structured data type in the type the pointer points to. (e.g: 2 for POINTER TO ARRAY [0..9] OF INT) bWrite: BOOL; // Indicates read or write Access. TRUE = write access. END_VAR // No standard way of implementation. Fill your own code here CheckPointer := ptToTest; {flow} END_FUNCTION CheckRangeSigned ^^^^^^^^^^^^^^^^ :: // Implicitly generated code : DO NOT EDIT FUNCTION CheckRangeSigned : DINT VAR_INPUT value, lower, upper: DINT; END_VAR // Implicitly generated code : Only an Implementation suggestion {noflow} IF (value < lower) THEN CheckRangeSigned := lower; ELSIF(value > upper) THEN CheckRangeSigned := upper; ELSE CheckRangeSigned := value; END_IF {flow} END_FUNCTION CheckRangeUnsigned ^^^^^^^^^^^^^^^^^^ :: // Implicitly generated code : DO NOT EDIT FUNCTION CheckRangeUnsigned : UDINT VAR_INPUT value, lower, upper: UDINT; END_VAR // Implicitly generated code : Only an Implementation suggestion {noflow} IF (value < lower) THEN CheckRangeUnsigned := lower; ELSIF(value > upper) THEN CheckRangeUnsigned := upper; ELSE CheckRangeUnsigned := value; END_IF {flow} END_FUNCTION F_AddChannelToHeader ^^^^^^^^^^^^^^^^^^^^ :: FUNCTION F_AddChannelToHeader : BOOL // Adds data about our channel to the header VAR_IN_OUT stHeader: DUT_Header_NW; stChannel: DUT_Channel_NW; END_VAR IF stChannel.channel = 0 THEN F_AddChannelToHeader := FALSE; ELSE stHeader.channelMask := stHeader.channelMask + SHL(1, stChannel.channel - 1); IF stChannel.error > 0 THEN stHeader.errorMask := stHeader.errorMask + SHL(1, stChannel.channel - 1); END_IF F_AddChannelToHeader := TRUE; END_IF END_FUNCTION Related: * `DUT_Channel_NW`_ * `DUT_Header_NW`_ FB_AssembleChannel ^^^^^^^^^^^^^^^^^^ :: FUNCTION_BLOCK FB_AssembleChannel VAR_INPUT // Raw count from the encoder, taken from ST_MotionStage.nEncoderCount nEncCount : UDINT; // Latched rising edge timestamp from EL1252-0050 terminal. nTiming : ULINT; // Scale as reported in ST_MotionStage.stAxisParameters.fEncScaleFactorNumerator fScale : LREAL; // Serial number of the encoder sHardwareID : STRING(15); // Channel number for the data packet nChannel : USINT; // Error code for the data packet nError : USINT; // Selector for acquisition mode (currently unused) nMode : USINT; // Scale denominator as reported in ST_MotionStage.stAxisParameters.fEncScaleFactorDenominator fScaleDenominator: LREAL; END_VAR VAR_OUTPUT // Network-ready encoder channel structure stChannel : DUT_Channel_NW; END_VAR VAR nStringIter : USINT; END_VAR stChannel.count := HOST_TO_BE32(UDINT_TO_DWORD(nEncCount)); stChannel.timing := HOST_TO_BE32(ULINT_TO_DWORD(nTiming)); // Truncate to remove the "seconds" bytes. // Scale may be numerator-only or numerator and denominator IF fScaleDenominator = 1 AND fScale < 0 THEN // Old format stChannel.scale := HOST_TO_BE16(LREAL_TO_WORD(fScale * 1_000_000)); // Send as "nanometers per count" uint (assuming mm scale) stChannel.scale_denominator := 0; ELSE // New format stChannel.scale := HOST_TO_BE16(LREAL_TO_WORD(fScale)); stChannel.scale_denominator := HOST_TO_BE16(LREAL_TO_WORD(fScaleDenominator)); END_IF FOR nStringIter := 0 TO 15 DO stChannel.hardwareID[nStringIter] := sHardwareID[nStringIter]; END_FOR stChannel.channel := nChannel; stChannel.error := nError; stChannel.mode := nMode; END_FUNCTION_BLOCK Related: * `DUT_Channel_NW`_ FB_AssembleHeader ^^^^^^^^^^^^^^^^^ :: FUNCTION_BLOCK FB_AssembleHeader VAR_INPUT // The count of how many frames we've sent, e.g. 1 on the first send, 2 on the second... nFrameCount : UINT; // Protocol version. This is set for you by this function block. nMajor : UINT := 2; nMinor : USINT := 0; nMicro : USINT := 0; // Unambiguous identifier for the PLC sHardwareID : STRING(15); // Selector for acquisition mode (currently unused) nMode : USINT; END_VAR VAR_OUTPUT // Almost ready encoder header structure. See FB_AddChannelToHeader. stHeader : DUT_Header_NW; END_VAR VAR nStringIter : USINT; END_VAR stHeader.frameCount := HOST_TO_BE16(UINT_TO_WORD(nFrameCount)); stHeader.major := HOST_TO_BE16(UINT_TO_WORD(nMajor)); stHeader.minor := USINT_TO_BYTE(nMinor); stHeader.micro := USINT_TO_BYTE(nMicro); FOR nStringIter := 0 TO 15 DO stHeader.hardwareID[nStringIter] := sHardwareID[nStringIter]; END_FOR stHeader.mode := nMode; END_FUNCTION_BLOCK Related: * `DUT_Header_NW`_ FB_BufferedSocketSend ^^^^^^^^^^^^^^^^^^^^^ :: FUNCTION_BLOCK FB_BufferedSocketSend VAR_INPUT stData: DUT_01_Channel_NW; bNewData: BOOL; hSocket: T_HSOCKET; sRemoteHost: STRING; nRemotePort: UDINT; END_VAR VAR_OUTPUT END_VAR VAR CONSTANT BUFFER_SIZE: UINT := 16; END_VAR VAR // Input handling rtNewData: R_TRIG; // Data buffer and iteration arrBuffer: ARRAY[0..BUFFER_SIZE-1] OF DUT_01_Channel_NW; nDataRecvCount: ULINT; nDataSentCount: ULINT; nIndex: UINT; // Actually send the data fbSocketSend: FB_SocketUdpSendTo; bExecuteSend: BOOL; END_VAR rtNewData(CLK:=bNewData); IF rtNewData.Q THEN arrBuffer[nDataRecvCount MOD BUFFER_SIZE] := stData; nDataRecvCount := nDataRecvCount + 1; END_IF IF nDataRecvCount > nDataSentCount AND NOT fbSocketSend.bBusy THEN nIndex := ULINT_TO_UINT(nDataSentCount MOD BUFFER_SIZE); bExecuteSend := TRUE; nDataSentCount := nDataSentCount + 1; END_IF fbSocketSend( hSocket:=hSocket, sRemoteHost:=sRemoteHost, nRemotePort:=nRemotePort, cbLen:=SIZEOF(arrBuffer[nIndex]), pSrc:=ADR(arrBuffer[nIndex]), bExecute:=bExecuteSend, ); fbSocketSend( bExecute:=FALSE, ); bExecuteSend := FALSE; END_FUNCTION_BLOCK Related: * `DUT_01_Channel_NW`_ FB_UDPSocketHandler ^^^^^^^^^^^^^^^^^^^ :: FUNCTION_BLOCK FB_UDPSocketHandler VAR_INPUT bEnable : BOOL; bReset : BOOL; nLocalPort: UDINT; tRetry : TIME := T#1h; sLocalIP : T_IPv4Addr; END_VAR VAR_OUTPUT bReady : BOOL; hSocket : T_HSOCKET; END_VAR VAR rtReset : R_TRIG; tonRetryConnection : TON; // Retry after an hour fbGetAdapterIP : FB_GetAdaptersInfo := (bExecute := TRUE, sNetID := ''); // Acquire IP of the correct adapter fbSocket : FB_ConnectionlessSocket; ctuSocketError : CTU := (PV:=3); bSocketEnable : BOOL; bAdapterSet : BOOL; idxPortFind : UDINT; END_VAR IF sLocalIP <> '' THEN fbSocket.sLocalHost := sLocalIP; bSocketEnable := TRUE; bAdapterSet := TRUE; END_IF IF bEnable AND NOT bAdapterSet THEN fbGetAdapterIP(); IF NOT (fbGetAdapterIP.bBusy or fbGetAdapterIP.bError) THEN FOR idxPortFind := 0 TO MAX_LOCAL_ADAPTERS DO IF FIND(fbGetAdapterIP.arrAdapters[idxPortFind].sIpAddr, GVL_Logger.sIpTidbit) <> 0 THEN fbSocket.sLocalHost := fbGetAdapterIP.arrAdapters[idxPortFind].sIpAddr; bSocketEnable := TRUE; bAdapterSet := TRUE; EXIT; END_IF END_FOR END_IF END_IF (* Ensure the socket is ready for when data is emitted *) rtReset(CLK:=bReset); IF (rtReset.Q AND fbSocket.bEnable) THEN fbSocket(bEnable:=FALSE); END_IF // Disable fbSocket if too many errors occur ctuSocketError(CU:=fbSocket.bError, RESET:=tonRetryConnection.Q OR rtReset.Q); bSocketEnable R= ctuSocketError.Q; // Retry an hour later tonRetryConnection(IN:=ctuSocketError.Q, PT:=tRetry); bSocketEnable S= tonRetryConnection.Q OR rtReset.Q; fbSocket( nLocalPort:=nLocalPort, bEnable:=bSocketEnable AND bEnable, nMode:=CONNECT_MODE_ENABLEDBG, ); bReady := (bAdapterSet AND fbSocket.bEnable AND NOT fbSocket.bError AND fbSocket.eState = E_SocketConnectionlessState.eSOCKET_CREATED); hSocket := fbSocket.hSocket; END_FUNCTION_BLOCK FB_XS_YAG_States ^^^^^^^^^^^^^^^^ :: FUNCTION_BLOCK FB_XS_YAG_States EXTENDS FB_PositionStateBase_WithPMPS VAR_INPUT {attribute 'pytmc' := ' pv: SET io: io '} enumSet: ENUM_XS_YAG_States; stOut: DUT_PositionState; stYag1: DUT_PositionState; stYag2: DUT_PositionState; bStatesLock: BOOL; END_VAR VAR_OUTPUT {attribute 'pytmc' := ' pv: GET io: i '} enumGet: ENUM_XS_YAG_States; END_VAR VAR bXSInit: BOOL :=TRUE; END_VAR VAR CONSTANT fInDelta: LREAL := 2; fOutDelta: LREAL := 2; fInVelocity: LREAL := 0.5; fOutVelocity: LREAL := 0.5; fAccel: LREAL := 100; fOutDecel: LREAL := 25; END_VAR IF bXSInit THEN bXSInit := FALSE; stOut.sName := 'OUT'; stOut.fVelocity := fOutVelocity; stOut.fDelta := fOutDelta; stOut.fAccel := fAccel; stOut.fDecel := fOutDecel; stOut.bMoveOk := TRUE; stYag1.sName := 'YAG1'; stYag1.fVelocity := fInVelocity; stYag1.fDelta := fInDelta; stYag1.fAccel := fAccel; stYag1.fDecel := fAccel; stYag1.bMoveOk := TRUE; stYag2.sName := 'YAG2'; stYag2.fVelocity := fInVelocity; stYag2.fDelta := fInDelta; stYag2.fAccel := fAccel; stYag2.fDecel := fAccel; stYag2.bMoveOk := TRUE; arrStates[1] := stOut; arrStates[2] := stYag1; arrStates[3] := stYag2; END_IF setState := enumSet; Exec(); enumGet := getState; enumSet := setState; END_FUNCTION_BLOCK Related: * `ENUM_XS_YAG_States`_ P_Serial_Com ^^^^^^^^^^^^ :: PROGRAM P_Serial_Com VAR fbSerialLineControl_EL6001_M1K2: SerialLineControl; END_VAR //These are the global IOs...don't forget to copy your data into them (* EL6001 Serial port 0 com function *) fbSerialLineControl_EL6001_M1K2(Mode:= SERIALLINEMODE_EL6_22B (*SERIALLINEMODE_KL6_22B_STANDARD*), pComIn:= ADR(Serial_stComIn_M1K2), pComOut:=ADR(Serial_stComOut_M1K2), SizeComIn:= SIZEOF(Serial_stComIn_M1K2), TxBuffer:= Serial_TXBuffer_M1K2, RxBuffer:= Serial_RXBuffer_M1K2, Error=> , ErrorID=> ); END_PROGRAM PiezoSerial ^^^^^^^^^^^ :: PROGRAM PiezoSerial VAR //PI Serial fbE621SerialDriver_M1K2 : FB_PI_E621_SerialDriver; rtInitParams_M1K2 : R_TRIG; tonTimeoutRst_M1K2 : TON := (PT:=T#2S); //For timeout reset END_VAR //Piezo E-621 /////////////////////// fbE621SerialDriver_M1K2.i_xExecute := TRUE; fbE621SerialDriver_M1K2.i_xExecute R= fbE621SerialDriver_M1K2.q_xDone; fbE621SerialDriver_M1K2(iq_stPiezoAxis:= GVL_M1K2.M1K2_Pitch.Piezo, iq_stSerialRXBuffer:= Serial_RXBuffer_M1K2, iq_stSerialTXBuffer:= Serial_TXBuffer_M1K2); END_PROGRAM Related: * `GVL_M1K2`_ PRG_1_PlcTask ^^^^^^^^^^^^^ :: PROGRAM PRG_1_PlcTask VAR fbLogHandler: FB_LogHandler; END_VAR PRG_MR1K1_BEND(); PRG_MR1K1_BEND_BENDER(); PRG_MR1K2_SWITCH(); PRG_SP1K1_MONO(); PRG_SL1K2_EXIT(); PRG_ST1K1_ZOS(); //PRG_SPO_PMPS(); As per Jira Ticket LCLSECSD-249 PRG_2_PMPS_POST(); fbLogHandler(); PRG_ZeroOrder_PMPS(); PRG_MR2K2_FLAT(); PRG_MR3K2_KBH(); PRG_MR4K2_KBV(); END_PROGRAM Related: * `PRG_2_PMPS_POST`_ * `PRG_MR1K1_BEND`_ * `PRG_MR1K1_BEND_BENDER`_ * `PRG_MR1K2_SWITCH`_ * `PRG_MR2K2_FLAT`_ * `PRG_MR3K2_KBH`_ * `PRG_MR4K2_KBV`_ * `PRG_SL1K2_EXIT`_ * `PRG_SP1K1_MONO`_ * `PRG_SPO_PMPS`_ * `PRG_ST1K1_ZOS`_ * `PRG_ZeroOrder_PMPS`_ PRG_2_PMPS_POST ^^^^^^^^^^^^^^^ :: PROGRAM PRG_2_PMPS_POST VAR fbArbiterIO: FB_SubSysToArbiter_IO; fb_vetoArbiter: FB_VetoArbiter; ff2_ff1_link_optics: FB_FastFault := (i_xAutoReset := TRUE, i_DevName := 'FF2 to FF1 Link Optics', i_Desc := 'This is virtual FF2 fault, Please see faulting optics devices', i_TypeCode := 16#FFFF); //Extra FFOs ffRIX01 : FB_FastFault := ( i_xAutoReset := FALSE, i_DevName := 'RIX Tran 0.1', i_Desc := 'Faults when M1K1 is IN and transmission is above 0.1', i_TypeCode := 16#F509); ffRIX02 : FB_FastFault := ( i_xAutoReset := FALSE, i_DevName := 'RIX Tran 0.2', i_Desc := 'Faults when M1K1 is IN and transmission is above 0.2', i_TypeCode := 16#F510); ffRIX05 : FB_FastFault := ( i_xAutoReset := FALSE, i_DevName := 'RIX Tran 0.5', i_Desc := 'Faults when M1K1 is IN and transmission is above 0.5', i_TypeCode := 16#F511); delta: real:=0.1; END_VAR MOTION_GVL.fbStandardPMPSDB( io_fbFFHWO:= GVL_PMPS.fbFastFaultOutput1, bEnable:= TRUE, sPLCName:='plc-rixs-optics' ); GVL_PMPS.fbFastFaultOutput1.Execute(i_xVeto := (PMPS_GVL.stCurrentBeamParameters.aVetoDevices[PMPS.K_Stopper.MR1K1_OUT]) AND (NOT PMPS_GVL.stCurrentBeamParameters.aVetoDevices[PMPS.K_Stopper.MR1K1_IN])); GVL_PMPS.fbFastFaultOutput2.Execute(i_xVeto := (PMPS_GVL.stCurrentBeamParameters.aVetoDevices[PMPS.K_Stopper.MR1K1_OUT] AND NOT PMPS_GVL.stCurrentBeamParameters.aVetoDevices[PMPS.K_Stopper.MR1K1_IN]) OR PMPS_GVL.stCurrentBeamParameters.aVetoDevices[PMPS.K_Stopper.ST1K2]); fbArbiterIO( Arbiter:=GVL_PMPS.fbArbiter1, fbFFHWO:=GVL_PMPS.fbFastFaultOutput1, i_bVeto := PMPS_GVL.stCurrentBeamParameters.aVetoDevices[PMPS.K_Stopper.MR1K1_OUT] AND NOT PMPS_GVL.stCurrentBeamParameters.aVetoDevices[PMPS.K_Stopper.MR1K1_IN]); fb_vetoArbiter(bVeto:= PMPS_GVL.stCurrentBeamParameters.aVetoDevices[PMPS.K_Stopper.ST1K2], HigherAuthority := GVL_PMPS.fbArbiter1, LowerAuthority := GVL_PMPS.fbArbiter2, FFO := GVL_PMPS.fbFastFaultOutput2); ff2_ff1_link_optics( io_fbFFHWO := GVL_PMPS.fbFastFaultOutput1, i_xOK := GVL_PMPS.fbFastFaultOutput2.q_xFastFaultOut); //Code for Removing arbitration GVL_PMPS.fbArbiter1.AddRequest(nReqID := 47, stReqBp := PMPS_GVL.cstFullBeam, sDevName := 'rixs-optics'); GVL_PMPS.fbArbiter2.AddRequest(nReqID := 48, stReqBp := PMPS_GVL.cstFullBeam, sDevName := 'rixs-optics'); // Extra FFOs ffRIX01.i_xOK := (PMPS_GVL.stCurrentBeamParameters.nTran <=0.1+(0.1*delta)); //0.1 ffRIX01(io_fbFFHWO := GVL_PMPS.fbFastFaultOutput1); ffRIX02.i_xOK := (PMPS_GVL.stCurrentBeamParameters.nTran <=0.2+(0.2*delta)); ffRIX02(io_fbFFHWO := GVL_PMPS.fbFastFaultOutput1); ffRIX05.i_xOK := (PMPS_GVL.stCurrentBeamParameters.nTran <=0.5+(0.5*delta)); ffRIX05(io_fbFFHWO := GVL_PMPS.fbFastFaultOutput1); GVL_PMPS.rPhotonEnergy := PMPS_GVL.stCurrentBeamParameters.neV; END_PROGRAM Related: * `GVL_PMPS`_ PRG_DAQ_ENCODER ^^^^^^^^^^^^^^^ :: PROGRAM PRG_DAQ_ENCODER VAR // Inputs {attribute 'TcLinkTo' := 'TIIB[EVR]^Latch^LatchPos1'} iLatchPos AT %I*: ULINT; {attribute 'TcLinkTo' := 'TIIB[EVR]^Latch^LatchNeg1'} iLatchNeg AT %I*: ULINT; {attribute 'TcLinkTo' := 'TIIB[g_pi_up_dwn_e]^FB Inputs Channel 1^Position'} nEncoderCount AT %I*: ULINT; bSendToDAQ: BOOL := TRUE; bSendToTest: BOOL := FALSE; // rix-daq is the default test host sTestHost: STRING := '172.21.140.21'; bUseHWTriggers: BOOL := TRUE; bUseSWTriggers: BOOL := FALSE; tSWTriggerDelay: TIME := T#8ms; // Outputs iTimeSincePos: ULINT; iMaxTime: ULINT; iMinTime: ULINT := 10000000000; fTimeInS: LREAL; iTriggerWidth: ULINT; {attribute 'pytmc' := ' pv: SP1K1:MONO:DAQ:TRIG_RATE io: i '} fTriggerRate: LREAL; // Internals bNewTrigger: BOOL; tonSWTrigger: TON; iPrevLatchPos: ULINT; fMaxTimeInS: LREAL; fMinTimeInS: LREAL := 10000000; iTimeSinceLast: ULINT; nUpdateCycles: ULINT; {attribute 'pytmc' := ' pv: SP1K1:MONO:DAQ:FRAME_COUNT io: i '} nFrameCount: UINT; stTaskInfo: PlcTaskSystemInfo; iUnderflowCount: ULINT; fUnderflowPercent: LREAL; fEncScale: LREAL; fEncScaleDenominator: LREAL; fbSocketHandler : FB_UDPSocketHandler; fbSocketSend : FB_BufferedSocketSend; fbSocketHandlerTest : FB_UDPSocketHandler; fbSocketSendTest : FB_BufferedSocketSend; payload : DUT_01_Channel_NW; fbHeader : FB_AssembleHeader := (sHardwareID := 'plc-tst-proto6'); fbChannel : FB_AssembleChannel := (nChannel := 1); // Function blocks fbGetTaskIndex: GETCURTASKINDEX; // Temp testing nBusyCycles: UINT; nMaxBusyCycles: UINT; nDroppedFrames: UINT; // EPICS Diagnostics (reduce data size) {attribute 'pytmc' := ' pv: SP1K1:MONO:DAQ:ENC_COUNT io: i '} fEpicsEncCount: DINT; {attribute 'pytmc' := ' pv: SP1K1:MONO:DAQ:TRIG_WIDTH io: i '} fEpicsTrigWidth: DINT; END_VAR IF fEncScale = 0 THEN fEncScale := M7.stAxisParameters.fEncScaleFactorNumerator; fEncScaleDenominator := M7.stAxisParameters.fEncScaleFactorDenominator; END_IF fbGetTaskIndex(); stTaskInfo := _TaskInfo[fbGetTaskIndex.index]; IF bUseHWTriggers THEN bNewTrigger := iLatchPos <> iPrevLatchPos; ELSIF bUseSWTriggers THEN tonSWTrigger( IN:=NOT tonSWTrigger.Q, PT:=tSWTriggerDelay, Q=>bNewTrigger, ); ELSE bNewTrigger := FALSE; END_IF IF bNewTrigger THEN // Core timing check nUpdateCycles := nUpdateCycles + 1; iTimeSincePos := LINT_TO_ULINT(stTaskInfo.DcTaskTime) - iLatchPos - (stTaskInfo.CycleTime * 100) + (stTaskInfo.LastExecTime * 100); IF iTimeSincePos > 9223372036854775800 THEN iTimeSincePos := 0; iUnderflowCount := iUnderflowCount + 1; IF nUpdateCycles > 0 THEN fUnderFlowPercent := 100 * ULINT_TO_LREAL(iUnderflowCount) / ULINT_TO_LREAL(nUpdateCycles); END_IF END_IF // Stats iMaxTime := MAX(iTimeSincePos, iMaxTime); iMinTime := MIN(iTimeSincePos, iMinTime); fTimeInS := ULINT_TO_LREAL(iTimeSincePos) / 1_000_000_000; fMinTimeInS := MIN(fTimeInS, fMinTimeInS); fMaxTimeInS := MAX(fTimeInS, fMaxTimeInS); iTimeSinceLast := iLatchPos - iPrevLatchPos; IF iTimeSinceLast > 0 THEN fTriggerRate := 1_000_000_000/ULINT_TO_LREAL(iTimeSinceLast); END_IF IF iLatchNeg > iLatchPos THEN iTriggerWidth := iLatchNeg - iLatchPos; END_IF // Assemble Packet nFrameCount := ULINT_TO_UINT(nUpdateCycles); fbHeader( nFrameCount := nFrameCount, sHardwareID := 'plc-rixs-optics', stHeader => payload.header ); fbChannel( nEncCount := ULINT_TO_UDINT(nEncoderCount), nTiming := ULINT_TO_UDINT(iTimeSincePos), fScale := fEncScale, nError := UDINT_TO_USINT(M7.nErrorId), sHardwareID := 'SP1K1:G_PITCH', fScaleDenominator := fEncScaleDenominator, stChannel => payload.channel1 ); F_AddChannelToHeader( stHeader := payload.header, stChannel := payload.channel1, ); // Make sure we don't send packets on the same trigger twice iPrevLatchPos := iLatchPos; END_IF // Create our sockets // For the private DAQ network fbSocketHandler( bEnable := TRUE, tRetry := T#30s, nLocalPort := 0, sLocalIP := '192.168.0.3' ); // For the CDS network (testing) fbSocketHandlerTest( bEnable := TRUE, tRetry := T#30s, nLocalPort := 0, sLocalIP := '172.21.140.71' ); // Sent to the DAQ fbSocketSend( stData := payload, bNewData := bSendToDAQ AND bNewTrigger, hSocket := fbSocketHandler.hSocket, sRemoteHost := '192.168.0.8', nRemotePort := 5006, ); // Sent to test host (default: rix-daq) fbSocketSendTest( stData := payload, bNewData := bSendToTest AND bNewTrigger, hSocket := fbSocketHandlerTest.hSocket, sRemoteHost := sTestHost, nRemotePort := 5006, ); // Update EPICS-only vars fEpicsEncCount := ULINT_TO_DINT(nEncoderCount); fEpicsTrigWidth := ULINT_TO_DINT(iTriggerWidth); END_PROGRAM Related: * `DUT_01_Channel_NW`_ * `FB_AssembleChannel`_ * `FB_AssembleHeader`_ * `FB_BufferedSocketSend`_ * `FB_UDPSocketHandler`_ * `F_AddChannelToHeader`_ PRG_MR1K1_BEND ^^^^^^^^^^^^^^ :: PROGRAM PRG_MR1K1_BEND VAR {attribute 'TcLinkTo' := '.fbRunHOMS.bSTOEnable1:=TIIB[EL1004_M1K1_STO]^Channel 1^Input; .fbRunHOMS.bSTOEnable2:=TIIB[EL1004_M1K1_STO]^Channel 2^Input; .fbRunHOMS.stYupEnc.Count:=TIIB[EL5042_M1K1_Yupdwn]^FB Inputs Channel 1^Position; .fbRunHOMS.stYdwnEnc.Count:=TIIB[EL5042_M1K1_Yupdwn]^FB Inputs Channel 2^Position; .fbRunHOMS.stXupEnc.Count:=TIIB[EL5042_M1K1_Xupdwn]^FB Inputs Channel 1^Position; .fbRunHOMS.stXdwnEnc.Count:=TIIB[EL5042_M1K1_Xupdwn]^FB Inputs Channel 2^Position'} {attribute 'pytmc' := ' pv: MR1K1:BEND '} M1K1 : DUT_HOMS; // Encoder Arrays/RMS Watch: {attribute 'pytmc' := ' pv: MR1K1:BEND:ENC:Y '} fbYRMSErrorM1K1 : FB_RMSWatch; fMaxYRMSErrorM1K1 : LREAL; fMinYRMSErrorM1K1 : LREAL; {attribute 'pytmc' := ' pv: MR1K1:BEND:ENC:X '} fbXRMSErrorM1K1 : FB_RMSWatch; fMaxXRMSErrorM1K1 : LREAL; fMinXRMSErrorM1K1 : LREAL; // Pitch Control fbM1K1PitchControl : FB_PitchControl; bM1K1PitchDone : BOOL; bM1K1PitchBusy : BOOL; // 3-15-20 Having issues with pitch control on new Axilon systems (M1K2) // Should test on this one to see if common to all new systems // Using stepper only for now fbMotionStage_m16 : FB_MotionStage; // Raw Encoder Counts {attribute 'pytmc' := ' pv: MR1K1:BEND:ENC:YUP:CNT field: EGU cnt io: i '} nEncCntYupM1K1 : UDINT; {attribute 'pytmc' := ' pv: MR1K1:BEND:ENC:YDWN:CNT field: EGU cnt io: i '} nEncCntYdwnM1K1 : UDINT; {attribute 'pytmc' := ' pv: MR1K1:BEND:ENC:XUP:CNT field: EGU cnt io: i '} nEncCntXupM1K1 : UDINT; {attribute 'pytmc' := ' pv: MR1K1:BEND:ENC:XDWN:CNT field: EGU cnt io: i '} nEncCntXdwnM1K1 : UDINT; {attribute 'pytmc' := ' pv: MR1K1:BEND:ENC:PITCH:CNT field: EGU cnt io: i '} nEncCntPitchM1K1 : UDINT; // Encoder Reference Values {attribute 'pytmc' := ' pv: MR1K1:BEND:ENC:YUP:REF field: EGU cnt io: i '} nEncRefYupM1K1 : UDINT; {attribute 'pytmc' := ' pv: MR1K1:BEND:ENC:YDWN:REF field: EGU cnt io: i '} nEncRefYdwnM1K1 : UDINT; {attribute 'pytmc' := ' pv: MR1K1:BEND:ENC:XUP:REF field: EGU cnt io: i '} nEncRefXupM1K1 : UDINT; {attribute 'pytmc' := ' pv: MR1K1:BEND:ENC:XDWN:REF field: EGU cnt io: i '} nEncRefXdwnM1K1 : UDINT; {attribute 'pytmc' := ' pv: MR1K1:BEND:ENC:PITCH:REF field: EGU cnt io: i '} nEncRefPitchM1K1 : UDINT; mcReadParameterPitchM1K1 : MC_ReadParameter; fEncRefPitchM1K1_urad : LREAL; // Current Pitch encoder offset in urad // Common fEncLeverArm_mm : LREAL := 410.0; // Mirror LEDs {attribute 'pytmc' := ' pv: MR1K1:BEND:LED:01:PWR io: io field: ZNAM OFF field: ONAM ON '} {attribute 'TcLinkTo' := 'TIIB[EL2024-0010_M1K1_BEND_LED1]^Channel 1^Output'} bLEDPower01 AT %Q*: BOOL; {attribute 'pytmc' := ' pv: MR1K1:BEND:LED:02:PWR io: io field: ZNAM OFF field: ONAM ON '} {attribute 'TcLinkTo' := 'TIIB[EL2024-0010_M1K1_BEND_LED1]^Channel 2^Output'} bLEDPower02 AT %Q*: BOOL; {attribute 'pytmc' := ' pv: MR1K1:BEND:LED:03:PWR io: io field: ZNAM OFF field: ONAM ON '} {attribute 'TcLinkTo' := 'TIIB[EL2024-0010_M1K1_BEND_LED1]^Channel 3^Output'} bLEDPower03 AT %Q*: BOOL; {attribute 'pytmc' := ' pv: MR1K1:BEND:LED:04:PWR io: io field: ZNAM OFF field: ONAM ON '} {attribute 'TcLinkTo' := 'TIIB[EL2024-0010_M1K1_BEND_LED1]^Channel 4^Output'} bLEDPower04 AT %Q*: BOOL; // MR1K1 Y Encoder for PMPS Veto Device /////////////////////////////////////// {attribute 'TcLinkTo' := 'TIIB[PMPS_PRE]^IO Outputs^MR1K1_Y_ENC'} nMR1K1_Y_ENC_PMPS AT %Q* : UDINT; {attribute 'TcLinkTo' := 'TIIB[EL5042_M1K1_Yupdwn]^FB Inputs Channel 1^Status^Ready'} bMR1K1_Y_ENC_Ready AT %I* : BOOL; {attribute 'TcLinkTo' := 'TIIB[EL5042_M1K1_Yupdwn]^FB Inputs Channel 1^Status^TxPDO State'} bMR1K1_Y_ENC_TxPDO AT %I* : BOOL; // M1K1 Flow Press Sensors {attribute 'TcLinkTo' := '.iRaw := TIIB[EL3054_M1K1_FWM_PRSM]^AI Standard Channel 1^Value'} fM1K1_Flow_1 : FB_AnalogInput; {attribute 'pytmc' := ' pv: MR1K1:BEND:FWM:1 field: EGU lpm io: i '} fM1K1_Flow_1_val : LREAL; {attribute 'TcLinkTo' := '.iRaw := TIIB[EL3054_M1K1_FWM_PRSM]^AI Standard Channel 2^Value'} fM1K1_Flow_2 : FB_AnalogInput; {attribute 'pytmc' := ' pv: MR1K1:BEND:FWM:2 field: EGU lpm io: i '} fM1K1_Flow_2_val : LREAL; {attribute 'TcLinkTo' := '.iRaw := TIIB[EL3054_M1K1_FWM_PRSM]^AI Standard Channel 3^Value'} fM1K1_Press_1 : FB_AnalogInput; {attribute 'pytmc' := ' pv: MR1K1:BEND:PRSM:1 field: EGU bar io: i '} fM1K1_Press_1_val : LREAL; {attribute 'pytmc' := 'pv: MR1K1:BEND:COATING'} fbCoatingStates: FB_PositionStatePMPS1D; {attribute 'pytmc' := ' pv: MR1K1:BEND:COATING:STATE:SET io: io '} eStateSet: E_MR1K1_States; {attribute 'pytmc' := ' pv: MR1K1:BEND:COATING:STATE:GET io: i '} eStateGet: E_MR1K1_States; fbYSetup: FB_StateSetupHelper; //fbXSetup: FB_StateSetupHelper; astCoatingStatesY: ARRAY[1..GeneralConstants.MAX_STATES] OF ST_PositionState; //astCoatingStatesX: ARRAY[1..GeneralConstants.MAX_STATES] OF ST_PositionState; END_VAR // M1K1 M1K1.fbRunHOMS(stYup:=M12, stYdwn:=M13, stXup:=M14, stXdwn:=M15, stPitch:=M16, nYupEncRef:=GVL_M1K1_Constants.nYUP_ENC_REF, nYdwnEncRef:=GVL_M1K1_Constants.nYDWN_ENC_REF, nXupEncRef:=GVL_M1K1_Constants.nXUP_ENC_REF, nXdwnEncRef:=GVL_M1K1_Constants.nXDWN_ENC_REF, bExecuteCoupleY:=M1K1.bExecuteCoupleY, bExecuteCoupleX:=M1K1.bExecuteCoupleX, bExecuteDecoupleY:=M1K1.bExecuteDecoupleY, bExecuteDecoupleX:=M1K1.bExecuteDecoupleX, bGantryAlreadyCoupledY=>M1K1.bGantryAlreadyCoupledY, bGantryAlreadyCoupledX=>M1K1.bGantryAlreadyCoupledX, nCurrGantryY=>M1K1.nCurrGantryY, nCurrGantryX=>M1K1.nCurrGantryX); // No slave motion through Epics M13.bExecute := FALSE; // M1K1-Ydwn M15.bExecute := FALSE; // M1K1-Xdwn // Convert nCurrGantry to um (smaller number) to read out in epics M1K1.fCurrGantryY_um := LINT_TO_REAL(M1K1.nCurrGantryY) / 1000.0; M1K1.fCurrGantryX_um := LINT_TO_REAL(M1K1.nCurrGantryX) / 1000.0; // FB_MotionStage's for non-piezo axes fbMotionStage_m12(stMotionStage:=M12); fbMotionStage_m13(stMotionStage:=M13); fbMotionStage_m14(stMotionStage:=M14); fbMotionStage_m15(stMotionStage:=M15); // Calculate Pitch RMS Error: fbYRMSErrorM1K1(stMotionStage:=M12, fMaxRMSError=>fMaxYRMSErrorM1K1, fMinRMSError=>fMinYRMSErrorM1K1); fbXRMSErrorM1K1(stMotionStage:=M14, fMaxRMSError=>fMaxXRMSErrorM1K1, fMinRMSError=>fMinXRMSErrorM1K1); (* // Pitch Control fbM1K1PitchControl(Pitch:=GVL_M1K1.M1K1_Pitch, Stepper:=M16, lrCurrentSetpoint:=M16.fPosition, q_bDone=>bM1K1PitchDone, q_bBusy=>bM1K1PitchBusy); // When STO hit, need to reset SP IF NOT M16.bHardwareEnable THEN M16.fPosition := M16.stAxisStatus.fActPosition; END_IF *) // 3-15-20: Having issues with pitch control on new Axilon systems, should test here fbMotionStage_m16(stMotionStage:=M16); // Raw Encoder Counts For Epics nEncCntYupM1K1 := ULINT_TO_UDINT(M1K1.fbRunHOMS.stYupEnc.Count); nEncCntYdwnM1K1 := ULINT_TO_UDINT(M1K1.fbRunHOMS.stYdwnEnc.Count); nEncCntXupM1K1 := ULINT_TO_UDINT(M1K1.fbRunHOMS.stXupEnc.Count); nEncCntXdwnM1K1 := ULINT_TO_UDINT(M1K1.fbRunHOMS.stXdwnEnc.Count); nEncCntPitchM1K1 := LINT_TO_UDINT(GVL_M1K1.M1K1_Pitch.diEncCnt); // Encoder Reference Values For Epics nEncRefYupM1K1 := ULINT_TO_UDINT(GVL_M1K1_Constants.nYUP_ENC_REF); nEncRefYdwnM1K1 := ULINT_TO_UDINT(GVL_M1K1_Constants.nYDWN_ENC_REF); nEncRefXupM1K1 := ULINT_TO_UDINT(GVL_M1K1_Constants.nXUP_ENC_REF); nEncRefXdwnM1K1 := ULINT_TO_UDINT(GVL_M1K1_Constants.nXDWN_ENC_REF); mcReadParameterPitchM1K1(Axis:=M16.Axis, Enable:=TRUE, ParameterNumber:=MC_AxisParameter.AxisEncoderOffset, ReadMode:=READMODE_CYCLIC, Value=>fEncRefPitchM1K1_urad); nEncRefPitchM1K1 := LREAL_TO_UDINT(ABS(fEncRefPitchM1K1_urad) * fEncLeverArm_mm); // Export the Y encoder value for PMPS veto device evaluation IF bMR1K1_Y_ENC_Ready AND NOT bMR1K1_Y_ENC_TxPDO THEN nMR1K1_Y_ENC_PMPS := nEncCntYupM1K1; ELSE nMR1K1_Y_ENC_PMPS := 0; END_IF // LAMP KB Flow Pressure Sensors fM1K1_Flow_1(iTermBits:=15, fTermMax:=5.0427, fTermMin:=0.050472); fM1K1_Flow_1_val := fM1K1_Flow_1.fReal; fM1K1_Flow_2(iTermBits:=15, fTermMax:=5.0427, fTermMin:=0.050472); fM1K1_Flow_2_val := fM1K1_Flow_2.fReal; fM1K1_Press_1(iTermBits:=15, fTermMax:=4.0, fTermMin:=0); fM1K1_Press_1_val := fM1K1_Press_1.fReal; fbYSetup(stPositionState:=GVL_States.stDefaultOffsetY, bSetDefault:=TRUE); //fbXSetup(stPositionState:=GVL_States.stDefaultOffsetX, bSetDefault:=TRUE); fbYSetup(stPositionState:=astCoatingStatesY[E_MR1K1_States.B4C], sName:='B4C', sPmpsState:='MR1K1:BEND-B4C', nEncoderCount:=31911452 ); (*fbXSetup(stPositionState:=astCoatingStatesX[E_MR1K1_States.B4C], sName:='B4C', sPmpsState:='MR1K1:BEND-B4C', nEncoderCount:=19829647 );*) fbYSetup(stPositionState:=astCoatingStatesY[E_MR1K1_States.OUT], sName:='OUT', sPmpsState:='MR1K1:BEND-OUT', nEncoderCount:=13412630, fDelta:=50 ); (* // Out position determined solely by Y Axis fbXSetup(stPositionState:=astCoatingStatesX[E_MR1K1_States.OUT], sName:='OUT', sPmpsState:='MR1K1:BEND-OUT', nEncoderCount:=ULINT_TO_UDINT(M14.nRawEncoderULINT) ); *) fbCoatingStates( stMotionStage:=Main.M12, astPositionState:=astCoatingStatesY, eEnumSet:=eStateSet, eEnumGet:=eStateGet, fbFFHWO:=GVL_PMPS.fbFastFaultOutput1, fbArbiter:=GVL_PMPS.fbArbiter1, bEnableMotion:=TRUE, bEnableBeamParams:=TRUE, sDeviceName:='MR1K1:BEND', sTransitionKey:='MR1K1:BEND-TRANSITION', ); END_PROGRAM Related: * `E_MR1K1_States`_ * `GVL_M1K1`_ * `GVL_M1K1_Constants`_ * `GVL_PMPS`_ * `GVL_States`_ * `Main`_ PRG_MR1K1_BEND_BENDER ^^^^^^^^^^^^^^^^^^^^^ :: PROGRAM PRG_MR1K1_BEND_BENDER VAR // Encoder Arrays/RMS Watch: //MR1K1 US BENDER ENC RMS {attribute 'pytmc' := ' pv: MR1K1:BEND:ENC:US '} fbBendUSRMSErrorM1K1 : FB_RMSWatch; fMaxBendUSRMSErrorM1K1 : LREAL; fMinBendUSRMSErrorM1K1 : LREAL; //MR1K1 DS BENDER ENC RMS {attribute 'pytmc' := ' pv: MR1K1:BEND:ENC:DS '} fbBendDSRMSErrorM1K1 : FB_RMSWatch; fMaxBendDSRMSErrorM1K1 : LREAL; fMinBendDSRMSErrorM1K1 : LREAL; // Encoder Reference Values //MR1K1 BEND US ENC REF {attribute 'pytmc' := ' pv: MR1K1:BEND:ENC:US:REF field: EGU cnt io: i '} nEncRefBendUSM1K1 : UDINT; //MR1K1 BEND DS ENC REF {attribute 'pytmc' := ' pv: MR1K1:BEND:ENC:DS:REF field: EGU cnt io: i '} nEncRefBendDSM1K1 : UDINT; // Encoder raw counts //M1K1 BEND US ENC CNT {attribute 'pytmc' := ' pv: MR1K1:BEND:ENC:US:CNT field: EGU cnt io: i '} nEncCntBendUSM1K1 : UDINT; //M1K1 BEND DS ENC CNT {attribute 'pytmc' := ' pv: MR1K1:BEND:ENC:DS:CNT field: EGU cnt io: i '} nEncCntBendDSM1K1 : UDINT; //Emergency Stop for MR1K1 //Emergency Stop for MR1K1 {attribute 'TcLinkTo' := 'TIID^Device 1 (EtherCAT)^Term 1 (EK1200)^Term 5 (EK1122)^EK1100_MR1K1_BEND^EL1004_M1K1_BENDER_STO^Channel 1^Input'} M1K1BENDbSTOEnable1 AT %I* : BOOL; {attribute 'TcLinkTo' := 'TIID^Device 1 (EtherCAT)^Term 1 (EK1200)^Term 5 (EK1122)^EK1100_MR1K1_BEND^EL1004_M1K1_BENDER_STO^Channel 2^Input'} M1K1BENDbSTOEnable2 AT %I* : BOOL; // MR1K1 Bender RTDs // MR1K1 US RTDs {attribute 'pytmc' := ' pv: MR1K1:BEND:RTD:US:1 field: ASLO 0.01 field: EGU C io: i '} fM1K1US_RTD_1 : REAL; {attribute 'pytmc' := ' pv: MR1K1:BEND:RTD:US:2 field: ASLO 0.01 field: EGU C io: i '} fM1K1US_RTD_2 : REAL; {attribute 'pytmc' := ' pv: MR1K1:BEND:RTD:US:3 field: ASLO 0.01 field: EGU C io: i '} fM1K1US_RTD_3 : REAL; // M1K1 DS RTDs {attribute 'pytmc' := ' pv: MR1K1:BEND:RTD:DS:1 field: ASLO 0.01 field: EGU C io: i '} fM1K1DS_RTD_1 : REAL; {attribute 'pytmc' := ' pv: MR1K1:BEND:RTD:DS:2 field: ASLO 0.01 field: EGU C io: i '} fM1K1DS_RTD_2 : REAL; {attribute 'pytmc' := ' pv: MR1K1:BEND:RTD:DS:3 field: ASLO 0.01 field: EGU C io: i '} fM1K1DS_RTD_3 : REAL; // RTD error bit bM1K1US_RTD_1_Err AT %I*: BOOL; bM1K1US_RTD_2_Err AT %I*: BOOL; bM1K1US_RTD_3_Err AT %I*: BOOL; bM1K1DS_RTD_1_Err AT %I*: BOOL; bM1K1DS_RTD_2_Err AT %I*: BOOL; bM1K1DS_RTD_3_Err AT %I*: BOOL; // Logging fbLogHandler : FB_LogHandler; fbBendUSRMSErrorMR1K1: INT; // PMPS ffBenderRange : FB_FastFault := ( i_xAutoReset := TRUE, i_DevName := 'MR1K1 Bender', i_Desc := 'Benders have moved out of range, monochromator beam may be focused where it can damage the BCS. Adjust bender to be within limits to clear fault', i_TypeCode := 16#402); END_VAR //FB_Motion stages for MR1K1 Benders //MR1K1 BEND fbMotionStage_m17(stMotionStage:=M17); fbMotionStage_m18(stMotionStage:=M18); // Calculate Pitch RMS Error for MR1K1 Benders: //MR1K1 US BENDER ENC RMS fbBendUSRMSErrorM1K1(stMotionStage:=M17, fMaxRMSError=>fMaxBendUSRMSErrorM1K1, fMinRMSError=>fMinBendUSRMSErrorM1K1); //MR1K1 DS BENDER ENC RMS fbBendDSRMSErrorM1K1(stMotionStage:=M18, fMaxRMSError=>fMaxBendDSRMSErrorM1K1, fMinRMSError=>fMinBendDSRMSErrorM1K1); //STO for MR1K1 Benders M17.bHardwareEnable := M1K1BENDbSTOEnable1 AND M1K1BENDbSTOEnable2; M18.bHardwareEnable := M1K1BENDbSTOEnable1 AND M1K1BENDbSTOEnable2; //Encoder reference positions for MR1K1 nEncRefBendUSM1K1 := ULINT_TO_UDINT(GVL_M1K1_BENDER_Constants.nM1K1bendUS_ENC_REF); nEncRefBendDSM1K1 := ULINT_TO_UDINT(GVL_M1K1_BENDER_Constants.nM1K1bendDS_ENC_REF); // M1K1 Bender Encoder Count Values For Epics nEncCntBendUSM1K1 := ULINT_TO_UDINT(M17.nRawEncoderULINT); nEncCntBendDSM1K1 := ULINT_TO_UDINT(M18.nRawEncoderULINT); // MR1K1 Bender RTDs fM1K1US_RTD_1 := INT_TO_REAL(GVL_M1K1_BENDER_RTD.nM1K1US_RTD_1); fM1K1US_RTD_2 := INT_TO_REAL(GVL_M1K1_BENDER_RTD.nM1K1US_RTD_2); fM1K1US_RTD_3 := INT_TO_REAL(GVL_M1K1_BENDER_RTD.nM1K1US_RTD_3); fM1K1DS_RTD_1 := INT_TO_REAL(GVL_M1K1_BENDER_RTD.nM1K1DS_RTD_1); fM1K1DS_RTD_2 := INT_TO_REAL(GVL_M1K1_BENDER_RTD.nM1K1DS_RTD_2); fM1K1DS_RTD_3 := INT_TO_REAL(GVL_M1K1_BENDER_RTD.nM1K1DS_RTD_3); // RTD not connected if T=0 bM1K1US_RTD_1_Err := fM1K1US_RTD_1 = 0; bM1K1US_RTD_2_Err := fM1K1DS_RTD_2 = 0; bM1K1US_RTD_3_Err := fM1K1US_RTD_3 = 0; bM1K1DS_RTD_1_Err := fM1K1DS_RTD_1 = 0; bM1K1DS_RTD_2_Err := fM1K1DS_RTD_2 = 0; bM1K1DS_RTD_3_Err := fM1K1DS_RTD_3 = 0; // M1K1 Bender RTD interlocks M17.bHardwareEnable R= fM1K1US_RTD_1 > 10000 OR bM1K1US_RTD_1_Err; M18.bHardwareEnable R= fM1K1DS_RTD_1 > 10000 OR bM1K1DS_RTD_1_Err; ffBenderRange.i_xOK := GVL_M1K1_BENDER_Constants.nM1K1bendUS_PMPS_LowerLimit < nEncCntBendUSM1K1 AND nEncCntBendUSM1K1 < GVL_M1K1_BENDER_Constants.nM1K1bendUS_PMPS_UpperLimit AND GVL_M1K1_BENDER_Constants.nM1K1bendDS_PMPS_LowerLimit < nEncCntBendDSM1K1 AND nEncCntBendDSM1K1 < GVL_M1K1_BENDER_Constants.nM1K1bendDS_PMPS_UpperLimit; ffBenderRange(io_fbFFHWO := GVL_PMPS.fbFastFaultOutput1); M17.bLimitForwardEnable := TRUE; END_PROGRAM Related: * `GVL_M1K1_BENDER_Constants`_ * `GVL_M1K1_BENDER_RTD`_ * `GVL_PMPS`_ PRG_MR1K2_SWITCH ^^^^^^^^^^^^^^^^ :: PROGRAM PRG_MR1K2_SWITCH VAR {attribute 'TcLinkTo' := '.fbRunHOMS.bSTOEnable1:=TIIB[EL1004_M1K2_STO]^Channel 1^Input; .fbRunHOMS.bSTOEnable2:=TIIB[EL1004_M1K2_STO]^Channel 2^Input; .fbRunHOMS.stYupEnc.Count:=TIIB[EL5042_M1K2_Yleftright]^FB Inputs Channel 1^Position; .fbRunHOMS.stYdwnEnc.Count:=TIIB[EL5042_M1K2_Yleftright]^FB Inputs Channel 2^Position; .fbRunHOMS.stXupEnc.Count:=TIIB[EL5042_M1K2_Xupdwn]^FB Inputs Channel 1^Position; .fbRunHOMS.stXdwnEnc.Count:=TIIB[EL5042_M1K2_Xupdwn]^FB Inputs Channel 2^Position'} {attribute 'pytmc' := ' pv: MR1K2:SWITCH '} M1K2 : DUT_HOMS; // Encoder Arrays/RMS Watch: {attribute 'pytmc' := ' pv: MR1K2:SWITCH:ENC:Y '} fbYRMSErrorM1K2 : FB_RMSWatch; fMaxYRMSErrorM1K2 : LREAL; fMinYRMSErrorM1K2 : LREAL; {attribute 'pytmc' := ' pv: MR1K2:SWITCH:ENC:X '} fbXRMSErrorM1K2 : FB_RMSWatch; fMaxXRMSErrorM1K2 : LREAL; fMinXRMSErrorM1K2 : LREAL; {attribute 'pytmc' := ' pv: MR1K2:SWITCH:ENC:PITCH '} fbPitchRMSErrorM1K2 : FB_RMSWatch; fMaxPitchRMSErrorM1K2 : LREAL; fMinPitchRMSErrorM1K2 : LREAL; // Pitch Control fbM1K2PitchControl : FB_PitchControl; bM1K2PitchDone : BOOL; bM1K2PitchBusy : BOOL; // 3-15-20 Having issues with pitch control on new Axilon systems // Using stepper only for now fbMotionStage_m5 : FB_MotionStage; // Roll (Rotation about Z axis) induced from Ygantry: {attribute 'pytmc' := ' pv: MR1K2:SWITCH:ENC:ROLL field: EGU urad io: i '} fYRoll_urad : LREAL; // Roll about Z axis in urad // Raw Encoder Counts {attribute 'pytmc' := ' pv: MR1K2:SWITCH:ENC:YLEFT:CNT field: EGU cnt io: i '} nEncCntYleftM1K2 : UDINT; {attribute 'pytmc' := ' pv: MR1K2:SWITCH:ENC:YRIGHT:CNT field: EGU cnt io: i '} nEncCntYrightM1K2 : UDINT; {attribute 'pytmc' := ' pv: MR1K2:SWITCH:ENC:XUP:CNT field: EGU cnt io: i '} nEncCntXupM1K2 : UDINT; {attribute 'pytmc' := ' pv: MR1K2:SWITCH:ENC:XDWN:CNT field: EGU cnt io: i '} nEncCntXdwnM1K2 : UDINT; {attribute 'pytmc' := ' pv: MR1K2:SWITCH:ENC:PITCH:CNT field: EGU cnt io: i '} nEncCntPitchM1K2 : UDINT; // Encoder Reference Values {attribute 'pytmc' := ' pv: MR1K2:SWITCH:ENC:YLEFT:REF field: EGU cnt io: i '} nEncRefYleftM1K2 : UDINT; {attribute 'pytmc' := ' pv: MR1K2:SWITCH:ENC:YRIGHT:REF field: EGU cnt io: i '} nEncRefYrightM1K2 : UDINT; {attribute 'pytmc' := ' pv: MR1K2:SWITCH:ENC:XUP:REF field: EGU cnt io: i '} nEncRefXupM1K2 : UDINT; {attribute 'pytmc' := ' pv: MR1K2:SWITCH:ENC:XDWN:REF field: EGU cnt io: i '} nEncRefXdwnM1K2 : UDINT; {attribute 'pytmc' := ' pv: MR1K2:SWITCH:ENC:PITCH:REF field: EGU cnt io: i '} nEncRefPitchM1K2 : UDINT; mcReadParameterPitchM1K2 : MC_ReadParameter; fEncRefPitchM1K2_urad : LREAL; // Current Pitch encoder offset in urad // Common fEncLeverArm_mm : LREAL := 391.0; // MR1K2 Flow Press Sensors {attribute 'TcLinkTo' := '.iRaw := TIIB[EL3054_M1K2_FWM_PRSM]^AI Standard Channel 1^Value'} fM1K2_Flow_1 : FB_AnalogInput; {attribute 'pytmc' := ' pv: MR1K2:SWITCH:FWM:1 field: EGU lpm io: i '} fM1K2_Flow_1_val : LREAL; {attribute 'TcLinkTo' := '.iRaw := TIIB[EL3054_M1K2_FWM_PRSM]^AI Standard Channel 2^Value'} fM1K2_Flow_2 : FB_AnalogInput; {attribute 'pytmc' := ' pv: MR1K2:SWITCH:FWM:2 field: EGU lpm io: i '} fM1K2_Flow_2_val : LREAL; {attribute 'TcLinkTo' := '.iRaw := TIIB[EL3054_M1K2_FWM_PRSM]^AI Standard Channel 3^Value'} fM1K2_Press_1 : FB_AnalogInput; {attribute 'pytmc' := ' pv: MR1K2:SWITCH:PRSM:1 field: EGU bar io: i '} fM1K2_Press_1_val : LREAL; {attribute 'pytmc' := 'pv: MR1K2:SWITCH:COATING'} fbCoatingStates: FB_PositionStatePMPS1D; {attribute 'pytmc' := ' pv: MR1K2:SWITCH:COATING:STATE:SET io: io '} eStateSet: E_B4C_Rh_CoatingStates; {attribute 'pytmc' := ' pv: MR1K2:SWITCH:COATING:STATE:GET io: i '} eStateGet: E_B4C_Rh_CoatingStates; fbYSetup: FB_StateSetupHelper; astCoatingStatesY: ARRAY[1..GeneralConstants.MAX_STATES] OF ST_PositionState; END_VAR // M1K2 M1K2.fbRunHOMS(stYup:=M1, stYdwn:=M2, stXup:=M3, stXdwn:=M4, stPitch:=M5, nYupEncRef:=GVL_M1K2_Constants.nYLEFT_ENC_REF, nYdwnEncRef:=GVL_M1K2_Constants.nYRIGHT_ENC_REF, nXupEncRef:=GVL_M1K2_Constants.nXUP_ENC_REF, nXdwnEncRef:=GVL_M1K2_Constants.nXDWN_ENC_REF, bExecuteCoupleY:=M1K2.bExecuteCoupleY, bExecuteCoupleX:=M1K2.bExecuteCoupleX, bExecuteDecoupleY:=M1K2.bExecuteDecoupleY, bExecuteDecoupleX:=M1K2.bExecuteDecoupleX, bGantryAlreadyCoupledY=>M1K2.bGantryAlreadyCoupledY, bGantryAlreadyCoupledX=>M1K2.bGantryAlreadyCoupledX, nCurrGantryY=>M1K2.nCurrGantryY, nCurrGantryX=>M1K2.nCurrGantryX); // No slave motion through Epics M2.bExecute := FALSE; // M1K2-Yright M4.bExecute := FALSE; // M1K2-Xdwn //Forcing limit switches for M1K2 pitch as the limit switches are no longer installed per ME they aren't able to install them precisely M5.bLimitBackwardEnable := TRUE; M5.bLimitForwardEnable := TRUE; // Convert nCurrGantry to um (smaller number) to read out in epics M1K2.fCurrGantryY_um := LINT_TO_REAL(M1K2.nCurrGantryY) / 1000.0; M1K2.fCurrGantryX_um := LINT_TO_REAL(M1K2.nCurrGantryX) / 1000.0; fYRoll_urad := (REAL_TO_LREAL(ATAN(M1K2.fCurrGantryY_um / GVL_M1K2_Constants.fRollLeverArm_um))) * EXPT(10, 6); // FB_MotionStage's for non-piezo axes fbMotionStage_m1(stMotionStage:=M1); fbMotionStage_m2(stMotionStage:=M2); fbMotionStage_m3(stMotionStage:=M3); fbMotionStage_m4(stMotionStage:=M4); // Calculate Pitch RMS Error: fbYRMSErrorM1K2(stMotionStage:=M1, fMaxRMSError=>fMaxYRMSErrorM1K2, fMinRMSError=>fMinYRMSErrorM1K2); fbXRMSErrorM1K2(stMotionStage:=M3, fMaxRMSError=>fMaxXRMSErrorM1K2, fMinRMSError=>fMinXRMSErrorM1K2); fbPitchRMSErrorM1K2(stMotionStage:=M5, fMaxRMSError=>fMaxPitchRMSErrorM1K2, fMinRMSError=>fMinPitchRMSErrorM1K2); (* // Pitch Control fbM1K2PitchControl(Pitch:=GVL_M1K2.M1K2_Pitch, Stepper:=M5, lrCurrentSetpoint:=M5.fPosition, q_bDone=>bM1K2PitchDone, q_bBusy=>bM1K2PitchBusy); // When STO hit, need to reset SP IF NOT M5.bHardwareEnable THEN M5.fPosition := M5.stAxisStatus.fActPosition; END_IF *) // 3-15-20: Having issues with pitch control on new Axilon systems fbMotionStage_m5(stMotionStage:=M5); // Raw Encoder Counts For Epics nEncCntYleftM1K2 := ULINT_TO_UDINT(M1K2.fbRunHOMS.stYupEnc.Count); nEncCntYrightM1K2 := ULINT_TO_UDINT(M1K2.fbRunHOMS.stYdwnEnc.Count); nEncCntXupM1K2 := ULINT_TO_UDINT(M1K2.fbRunHOMS.stXupEnc.Count); nEncCntXdwnM1K2 := ULINT_TO_UDINT(M1K2.fbRunHOMS.stXdwnEnc.Count); nEncCntPitchM1K2 := LINT_TO_UDINT(GVL_M1K2.M1K2_Pitch.diEncCnt); // Encoder Reference Values For Epics nEncRefYleftM1K2 := ULINT_TO_UDINT(GVL_M1K2_Constants.nYLEFT_ENC_REF); nEncRefYrightM1K2 := ULINT_TO_UDINT(GVL_M1K2_Constants.nYRIGHT_ENC_REF); nEncRefXupM1K2 := ULINT_TO_UDINT(GVL_M1K2_Constants.nXUP_ENC_REF); nEncRefXdwnM1K2 := ULINT_TO_UDINT(GVL_M1K2_Constants.nXDWN_ENC_REF); mcReadParameterPitchM1K2(Axis:=M5.Axis, Enable:=TRUE, ParameterNumber:=MC_AxisParameter.AxisEncoderOffset, ReadMode:=READMODE_CYCLIC, Value=>fEncRefPitchM1K2_urad); nEncRefPitchM1K2 := LREAL_TO_UDINT(ABS(fEncRefPitchM1K2_urad) * fEncLeverArm_mm); //FLOW AND PRESSURE SENSOR // MR1K2 Flow Pressure Sensors fM1K2_Flow_1(iTermBits:=15, fTermMax:=5.0427, fTermMin:=0.050472); fM1K2_Flow_1_val := fM1K2_Flow_1.fReal; fM1K2_Flow_2(iTermBits:=15, fTermMax:=5.0427, fTermMin:=0.050472); fM1K2_Flow_2_val := fM1K2_Flow_2.fReal; fM1K2_Press_1(iTermBits:=15, fTermMax:=4.0, fTermMin:=0); fM1K2_Press_1_val := fM1K2_Press_1.fReal; fbYSetup(stPositionState:=GVL_States.stDefaultOffsetY, bSetDefault:=TRUE); fbYSetup(stPositionState:=astCoatingStatesY[E_B4C_Rh_CoatingStates.B4C], sName:='B4C', sPmpsState:='MR1K2:SWITCH-B4C', nEncoderCount:=91672358, fDelta:=5000 ); fbYSetup(stPositionState:=astCoatingStatesY[E_B4C_Rh_CoatingStates.Rh], sName:='Rh', sPmpsState:='MR1K2:SWITCH-RHODIUM', nEncoderCount:=106672361, fDelta:=5000 ); fbCoatingStates( stMotionStage:=Main.M1, astPositionState:=astCoatingStatesY, eEnumSet:=eStateSet, eEnumGet:=eStateGet, fbFFHWO:=GVL_PMPS.fbFastFaultOutput1, fbArbiter:=GVL_PMPS.fbArbiter1, bEnableMotion:=TRUE, bEnableBeamParams:=TRUE, sDeviceName:='MR1K2:SWITCH', sTransitionKey:='MR1K2:SWITCH-TRANSITION', ); END_PROGRAM Related: * `E_B4C_Rh_CoatingStates`_ * `GVL_M1K2`_ * `GVL_M1K2_Constants`_ * `GVL_PMPS`_ * `GVL_States`_ * `Main`_ PRG_MR2K2_FLAT ^^^^^^^^^^^^^^ :: PROGRAM PRG_MR2K2_FLAT VAR // Encoder Arrays/RMS Watch: //MR2K2 X ENC RMS {attribute 'pytmc' := ' pv: MR2K2:FLAT:ENC:X'} fbXRMSErrorM2K2 : FB_RMSWatch; fMaxXRMSErrorM2K2 : LREAL; fMinXRMSErrorM2K2 : LREAL; //MR2K2 Y ENC RMS {attribute 'pytmc' := ' pv: MR2K2:FLAT:ENC:Y'} fbYRMSErrorM2K2 : FB_RMSWatch; fMaxYRMSErrorM2K2 : LREAL; fMinYRMSErrorM2K2 : LREAL; //MR2K2 rX ENC RMS {attribute 'pytmc' := ' pv: MR2K2:FLAT:ENC:PITCH'} fbrXRMSErrorM2K2 : FB_RMSWatch; fMaxrXRMSErrorM2K2 : LREAL; fMinrXRMSErrorM2K2 : LREAL; // Encoder Reference Values //MR2K2 X ENC REF {attribute 'pytmc' := ' pv: MR2K2:FLAT:ENC:X:REF field: EGU cnt io: i '} nEncRefXM2K2 : UDINT; //MR2K2 Y ENC REF {attribute 'pytmc' := ' pv: MR2K2:FLAT:ENC:Y:REF field: EGU cnt io: i '} nEncRefYM2K2 : UDINT; //MR2K2 rX ENC REF {attribute 'pytmc' := ' pv: MR2K2:FLAT:ENC:PITCH:REF field: EGU cnt io: i '} nEncRefrXM2K2 : UDINT; // Encoder raw counts //M2K2 FLAT X ENC CNT {attribute 'pytmc' := ' pv: MR2K2:FLAT:ENC:X:CNT field: EGU cnt io: i '} nEncCntXM2K2 : UDINT; //M2K2 FLAT Y ENC CNT {attribute 'pytmc' := ' pv: MR2K2:FLAT:ENC:Y:CNT field: EGU cnt io: i '} nEncCntYM2K2 : UDINT; //M2K2 FLAT rX ENC CNT {attribute 'pytmc' := ' pv: MR2K2:FLAT:ENC:PITCH:CNT field: EGU cnt io: i '} nEncCntrXM2K2 : UDINT; //Emergency Stop for MR2K2 //M2K2 needs an EL1004 term and an ESTOP added, not listed in I/O either {attribute 'TcLinkTo' := 'TIID^Device 1 (EtherCAT)^Term 1 (EK1200)^Term 79 (EK1521-0010)^Term 306 (EK1501-0010)^Term 310 (EK1122)^EK1100_MR2K2^EL1004_M2K2_STO^Channel 1^Input'} M2K2FLATbSTOEnable1 AT %I* : BOOL; {attribute 'TcLinkTo' := 'TIID^Device 1 (EtherCAT)^Term 1 (EK1200)^Term 79 (EK1521-0010)^Term 306 (EK1501-0010)^Term 310 (EK1122)^EK1100_MR2K2^EL1004_M2K2_STO^Channel 2^Input'} M2K2FLATbSTOEnable2 AT %I* : BOOL; {attribute 'TcLinkTo' := '.fbFlow_1.iRaw := TIIB[EL3054_MR2K2_FWM_PRSM]^AI Standard Channel 1^Value; .fbFlow_2.iRaw := TIIB[EL3054_MR2K2_FWM_PRSM]^AI Standard Channel 3^Value; .fbPress_1.iRaw := TIIB[EL3054_MR2K2_FWM_PRSM]^AI Standard Channel 2^Value '} {attribute 'pytmc' := ' pv: MR2K2:FLAT '} fbCoolingPanel : FB_Axilon_Cooling_2f1p; {attribute 'pytmc' := 'pv: MR2K2:FLAT:COATING'} fbCoatingStates: FB_PositionStatePMPS1D; {attribute 'pytmc' := ' pv: MR2K2:FLAT:COATING:STATE:SET io: io '} eStateSet: E_B4C_Rh_CoatingStates; {attribute 'pytmc' := ' pv: MR2K2:FLAT:COATING:STATE:GET io: i '} eStateGet: E_B4C_Rh_CoatingStates; fbXSetup: FB_StateSetupHelper; astCoatingStatesX: ARRAY[1..GeneralConstants.MAX_STATES] OF ST_PositionState; END_VAR //FB_Motion stages for MR2K2 Axes //MR2K2 FLAT fbMotionStageM25(stMotionStage:=M25); fbMotionStageM26(stMotionStage:=M26); fbMotionStageM27(stMotionStage:=M27); // Calculate Pitch RMS Error for MR2K2 Axes: //MR2K2 X ENC RMS fbXRMSErrorM2K2(stMotionStage:=M25, fMaxRMSError=>fMaxXRMSErrorM2K2, fMinRMSError=>fMinXRMSErrorM2K2); //MR2K2 X ENC RMS fbYRMSErrorM2K2(stMotionStage:=M26, fMaxRMSError=>fMaxYRMSErrorM2K2, fMinRMSError=>fMinYRMSErrorM2K2); //MR2K2 rX ENC RMS fbrXRMSErrorM2K2(stMotionStage:=M27, fMaxRMSError=>fMaxrXRMSErrorM2K2, fMinRMSError=>fMinrXRMSErrorM2K2); //STO for MR2K2 Benders M25.bHardwareEnable := M2K2FLATbSTOEnable1 AND M2K2FLATbSTOEnable2; M26.bHardwareEnable := M2K2FLATbSTOEnable1 AND M2K2FLATbSTOEnable2; M27.bHardwareEnable := M2K2FLATbSTOEnable1 AND M2K2FLATbSTOEnable2; //Encoder reference positions for MR2K2 nEncRefXM2K2 := ULINT_TO_UDINT(GVL_M2K2.nM2K2X_ENC_REF); nEncRefYM2K2 := ULINT_TO_UDINT(GVL_M2K2.nM2K2Y_ENC_REF); nEncRefrXM2K2 := ULINT_TO_UDINT(GVL_M2K2.nM2K2rX_ENC_REF); // M2K2 Bender Encoder Count Values For Epics nEncCntXM2K2 := ULINT_TO_UDINT(M25.nRawEncoderULINT); nEncCntYM2K2 := ULINT_TO_UDINT(M26.nRawEncoderULINT); nEncCntrXM2K2 := ULINT_TO_UDINT(M27.nRawEncoderULINT); // Axilon Cooling Panel fbCoolingPanel(); fbXSetup(stPositionState:=GVL_States.stDefaultKBX, bSetDefault:=TRUE); fbXSetup(stPositionState:=astCoatingStatesX[E_B4C_Rh_CoatingStates.B4C], sName:='B4C', sPmpsState:='MR2K2:FLAT-B4C', nEncoderCount:=ULINT_TO_UDINT(18446744073704980246), fDelta:=5 ); fbXSetup(stPositionState:=astCoatingStatesX[E_B4C_Rh_CoatingStates.Rh], sName:='Rh', sPmpsState:='MR2K2:FLAT-RHODIUM', nEncoderCount:=ULINT_TO_UDINT(18446744073701980417), fDelta:=5 ); fbCoatingStates( stMotionStage:=Main.M25, astPositionState:=astCoatingStatesX, eEnumSet:=eStateSet, eEnumGet:=eStateGet, fbFFHWO:=GVL_PMPS.fbFastFaultOutput2, fbArbiter:=GVL_PMPS.fbArbiter2, bEnableMotion:=TRUE, bEnableBeamParams:=TRUE, sDeviceName:='MR2K2:FLAT', sTransitionKey:='MR2K2:FLAT-TRANSITION', ); END_PROGRAM Related: * `E_B4C_Rh_CoatingStates`_ * `GVL_M2K2`_ * `GVL_PMPS`_ * `GVL_States`_ * `Main`_ PRG_MR3K2_KBH ^^^^^^^^^^^^^ :: PROGRAM PRG_MR3K2_KBH VAR // Encoder Arrays/RMS Watch: //MR3K2 X ENC RMS {attribute 'pytmc' := ' pv: MR3K2:KBH:ENC:X'} fbXRMSErrorM3K2 : FB_RMSWatch; fMaxXRMSErrorM3K2 : LREAL; fMinXRMSErrorM3K2 : LREAL; //MR3K2 Y ENC RMS {attribute 'pytmc' := ' pv: MR3K2:KBH:ENC:Y'} fbYRMSErrorM3K2 : FB_RMSWatch; fMaxYRMSErrorM3K2 : LREAL; fMinYRMSErrorM3K2 : LREAL; //MR3K2 rY ENC RMS {attribute 'pytmc' := ' pv: MR3K2:KBH:ENC:PITCH'} fbrYRMSErrorM3K2 : FB_RMSWatch; fMaxrYRMSErrorM3K2 : LREAL; fMinrYRMSErrorM3K2 : LREAL; //MR3K2 US ENC RMS {attribute 'pytmc' := ' pv: MR3K2:KBH:ENC:BEND:US'} fbUSRMSErrorM3K2 : FB_RMSWatch; fMaxUSRMSErrorM3K2 : LREAL; fMinUSRMSErrorM3K2 : LREAL; //MR3K2 DS ENC RMS {attribute 'pytmc' := ' pv: MR3K2:KBH:ENC:BEND:DS'} fbdSRMSErrorM3K2 : FB_RMSWatch; fMaxDSRMSErrorM3K2 : LREAL; fMinDSRMSErrorM3K2 : LREAL; // Encoder Reference Values //MR3K2 X ENC REF {attribute 'pytmc' := ' pv: MR3K2:KBH:ENC:X:REF field: EGU cnt io: i '} nEncRefXM3K2 : UDINT; //MR3K2 Y ENC REF {attribute 'pytmc' := ' pv: MR3K2:KBH:ENC:Y:REF field: EGU cnt io: i '} nEncRefYM3K2 : UDINT; //MR3K2 rY ENC REF {attribute 'pytmc' := ' pv: MR3K2:KBH:ENC:PITCH:REF field: EGU cnt io: i '} nEncRefrYM3K2 : UDINT; //MR3K2 US ENC REF {attribute 'pytmc' := ' pv: MR3K2:KBH:ENC:BEND:US:REF field: EGU cnt io: i '} nEncRefUSM3K2 : UDINT; //MR3K2 DS ENC REF {attribute 'pytmc' := ' pv: MR3K2:KBH:ENC:BEND:DS:REF field: EGU cnt io: i '} nEncRefDSM3K2 : UDINT; // Encoder raw counts //M3K2 KBH X ENC CNT {attribute 'pytmc' := ' pv: MR3K2:KBH:ENC:X:CNT field: EGU cnt io: i '} nEncCntXM3K2 : UDINT; //M3K2 KBH Y ENC CNT {attribute 'pytmc' := ' pv: MR3K2:KBH:ENC:Y:CNT field: EGU cnt io: i '} nEncCntYM3K2 : UDINT; //M3K2 KBH rY ENC CNT {attribute 'pytmc' := ' pv: MR3K2:KBH:ENC:PITCH:CNT field: EGU cnt io: i '} nEncCntrYM3K2 : UDINT; //M3K2 KBH US ENC CNT {attribute 'pytmc' := ' pv: MR3K2:KBH:ENC:BEND:US:CNT field: EGU cnt io: i '} nEncCntUSM3K2 : UDINT; //M3K2 KBH DS ENC CNT {attribute 'pytmc' := ' pv: MR3K2:KBH:ENC:BEND:DS:CNT field: EGU cnt io: i '} nEncCntDSM3K2 : UDINT; // MR3K2 Bender RTDs // MR3K2 US RTDs {attribute 'pytmc' := ' pv: MR3K2:KBH:RTD:BEND:US:1 field: ASLO 0.01 field: EGU C io: i '} fM3K2US_RTD_1 : REAL; {attribute 'pytmc' := ' pv: MR3K2:KBH:RTD:BEND:US:2 field: ASLO 0.01 field: EGU C io: i '} fM3K2US_RTD_2 : REAL; // M3K2 DS RTDs {attribute 'pytmc' := ' pv: MR3K2:KBH:RTD:BEND:DS:1 field: ASLO 0.01 field: EGU C io: i '} fM3K2DS_RTD_1 : REAL; {attribute 'pytmc' := ' pv: MR3K2:KBH:RTD:BEND:DS:3 field: ASLO 0.01 field: EGU C io: i '} fM3K2DS_RTD_3 : REAL; // RTD error bit bM3K2US_RTD_1_Err AT %I*: BOOL; bM3K2US_RTD_2_Err AT %I*: BOOL; bM3K2DS_RTD_1_Err AT %I*: BOOL; bM3K2DS_RTD_3_Err AT %I*: BOOL; //Emergency Stop for MR3K2 {attribute 'TcLinkTo' := 'TIIB[EL1004_M3K2_STO]^Channel 1^Input'} M3K2KBHbSTOEnable1 AT %I* : BOOL; {attribute 'TcLinkTo' := 'TIIB[EL1004_M3K2_STO]^Channel 2^Input'} M3K2KBHbSTOEnable2 AT %I* : BOOL; {attribute 'TcLinkTo' := '.fbFlow_1.iRaw := TIIB[EL3054_MR3_4K2_FWM_PRSM]^AI Standard Channel 1^Value; .fbPress_1.iRaw := TIIB[EL3054_MR3_4K2_FWM_PRSM]^AI Standard Channel 2^Value '} {attribute 'pytmc' := ' pv: MR3K2:KBH '} // MR3K2 Flow Sensors fbCoolingPanel : FB_Axilon_Cooling_1f1p; (* // PMPS ffBenderRange : FB_FastFault := ( i_xAutoReset := TRUE, i_DevName := 'MR3K2 Bender', i_Desc := 'Benders have moved out of range. Adjust bender to be within limits to clear fault', i_TypeCode := 16#???); *) {attribute 'pytmc' := 'pv: MR3K2:KBH:COATING'} fbCoatingStates: FB_PositionStatePMPS1D; {attribute 'pytmc' := ' pv: MR3K2:KBH:COATING:STATE:SET io: io '} eStateSet: E_B4C_Rh_CoatingStates; {attribute 'pytmc' := ' pv: MR3K2:KBH:COATING:STATE:GET io: i '} eStateGet: E_B4C_Rh_CoatingStates; fbYSetup: FB_StateSetupHelper; astCoatingStatesY: ARRAY[1..GeneralConstants.MAX_STATES] OF ST_PositionState; {attribute 'TcLinkTo' := '.iRaw := TIIB[EL3202-0010_M3K2DS2_M3K2DS3]^RTD Inputs Channel 1^Value; .bUnderrange := TIIB[EL3202-0010_M3K2DS2_M3K2DS3]^RTD Inputs Channel 1^Status^Underrange; .bOverrange := TIIB[EL3202-0010_M3K2DS2_M3K2DS3]^RTD Inputs Channel 1^Status^Overrange; .bError := TIIB[EL3202-0010_M3K2DS2_M3K2DS3]^RTD Inputs Channel 1^Status^Error'} {attribute 'pytmc' := ' pv: MR3K2:KBH:RTD:CHIN:R field: EGU C io: i '} fbM3K2_Chin_Right_RTD : FB_TempSensor; {attribute 'TcLinkTo' := '.iRaw := TIIB[EL3202-0010_M3K2US3_M3K2DS1]^RTD Inputs Channel 1^Value; .bUnderrange := TIIB[EL3202-0010_M3K2US3_M3K2DS1]^RTD Inputs Channel 1^Status^Underrange; .bOverrange := TIIB[EL3202-0010_M3K2US3_M3K2DS1]^RTD Inputs Channel 1^Status^Overrange; .bError := TIIB[EL3202-0010_M3K2US3_M3K2DS1]^RTD Inputs Channel 1^Status^Error'} {attribute 'pytmc' := ' pv: MR3K2:KBH:RTD:CHIN:L field: EGU C io: i '} fbM3K2_Chin_Left_RTD : FB_TempSensor; END_VAR //FB_Motion stages for MR3K2 Axes //MR3K2 KBH fbMotionStageM28(stMotionStage:=M28); fbMotionStageM29(stMotionStage:=M29); fbMotionStageM30(stMotionStage:=M30); fbMotionStageM31(stMotionStage:=M31); fbMotionStageM32(stMotionStage:=M32); // Calculate Pitch RMS Error for MR3K2 Axes: //MR3K2 X ENC RMS fbXRMSErrorM3K2(stMotionStage:=M28, fMaxRMSError=>fMaxXRMSErrorM3K2, fMinRMSError=>fMinXRMSErrorM3K2); //MR3K2 X ENC RMS fbYRMSErrorM3K2(stMotionStage:=M29, fMaxRMSError=>fMaxYRMSErrorM3K2, fMinRMSError=>fMinYRMSErrorM3K2); //MR3K2 rY ENC RMS fbrYRMSErrorM3K2(stMotionStage:=M30, fMaxRMSError=>fMaxrYRMSErrorM3K2, fMinRMSError=>fMinrYRMSErrorM3K2); //MR3K2 US ENC RMS fbUSRMSErrorM3K2(stMotionStage:=M31, fMaxRMSError=>fMaxUSRMSErrorM3K2, fMinRMSError=>fMinUSRMSErrorM3K2); //MR3K2 DS ENC RMS fbDSRMSErrorM3K2(stMotionStage:=M32, fMaxRMSError=>fMaxDSRMSErrorM3K2, fMinRMSError=>fMinDSRMSErrorM3K2); //STO for MR3K2 Benders M28.bHardwareEnable := M3K2KBHbSTOEnable1;// AND M3K2KBHbSTOEnable2; M29.bHardwareEnable := M3K2KBHbSTOEnable1;// AND M3K2KBHbSTOEnable2; M30.bHardwareEnable := M3K2KBHbSTOEnable1;// AND M3K2KBHbSTOEnable2; M31.bHardwareEnable := M3K2KBHbSTOEnable1;// AND M3K2KBHbSTOEnable2; M32.bHardwareEnable := M3K2KBHbSTOEnable1;// AND M3K2KBHbSTOEnable2; //Encoder reference positions for MR3K2 nEncRefXM3K2 := ULINT_TO_UDINT(GVL_M3K2.nM3K2X_ENC_REF); nEncRefYM3K2 := ULINT_TO_UDINT(GVL_M3K2.nM3K2Y_ENC_REF); nEncRefrYM3K2 := ULINT_TO_UDINT(GVL_M3K2.nM3K2rY_ENC_REF); nEncRefUSM3K2 := ULINT_TO_UDINT(GVL_M3K2.nM3K2US_ENC_REF); nEncRefDSM3K2 := ULINT_TO_UDINT(GVL_M3K2.nM3K2DS_ENC_REF); // M3K2 Bender Encoder Count Values For Epics nEncCntXM3K2 := ULINT_TO_UDINT(M28.nRawEncoderULINT); nEncCntYM3K2 := ULINT_TO_UDINT(M29.nRawEncoderULINT); nEncCntrYM3K2 := ULINT_TO_UDINT(M30.nRawEncoderULINT); nEncCntUSM3K2 := ULINT_TO_UDINT(M31.nRawEncoderULINT); nEncCntDSM3K2 := ULINT_TO_UDINT(M32.nRawEncoderULINT); // MR3K2 Bender RTDs fM3K2US_RTD_1 := INT_TO_REAL(GVL_M3K2.nM3K2US_RTD_1); fM3K2US_RTD_2 := INT_TO_REAL(GVL_M3K2.nM3K2US_RTD_2); fM3K2DS_RTD_1 := INT_TO_REAL(GVL_M3K2.nM3K2DS_RTD_1); fM3K2DS_RTD_3 := INT_TO_REAL(GVL_M3K2.nM3K2DS_RTD_3); // RTD not connected if T=0 bM3K2US_RTD_1_Err := fM3K2US_RTD_1 = 0; bM3K2US_RTD_2_Err := fM3K2US_RTD_2 = 0; bM3K2DS_RTD_1_Err := fM3K2DS_RTD_1 = 0; bM3K2DS_RTD_3_Err := fM3K2DS_RTD_3 = 0; // M3K2 Bender RTD interlocks M31.bHardwareEnable R= fM3K2US_RTD_1 > 9000 OR bM3K2US_RTD_1_Err; M32.bHardwareEnable R= fM3K2DS_RTD_1 > 9000 OR bM3K2DS_RTD_1_Err; // Axilon Cooling Panel fbCoolingPanel(); (* //PMPS ffBenderRange.i_xOK := GVL_M3K2.nM3K2US_PMPS_LowerLimit < nEncCntUSM3K2 AND nEncCntUSM3K2 < GVL_M3K2.nM3K2US_PMPS_UpperLimit AND GVL_M3K2.nM3K2DS_PMPS_LowerLimit < nEncCntDSM3K2 AND nEncCntUSM3K2 < GVL_M3K2.nM3K2DS_PMPS_UpperLimit; ffBenderRange(io_fbFFHWO := GVL_PMPS.fbFastFaultOutput1); *) fbYSetup(stPositionState:=GVL_States.stDefaultKBY, bSetDefault:=TRUE); fbYSetup(stPositionState:=astCoatingStatesY[E_B4C_Rh_CoatingStates.B4C], sName:='B4C', sPmpsState:='MR3K2:KBH-B4C', nEncoderCount:=6357520, fDelta:=5 ); fbYSetup(stPositionState:=astCoatingStatesY[E_B4C_Rh_CoatingStates.Rh], sName:='Rh', sPmpsState:='MR3K2:KBH-RHODIUM', nEncoderCount:=3857540, fDelta:=2.5 ); fbCoatingStates( stMotionStage:=Main.M29, astPositionState:=astCoatingStatesY, eEnumSet:=eStateSet, eEnumGet:=eStateGet, fbFFHWO:=GVL_PMPS.fbFastFaultOutput2, fbArbiter:=GVL_PMPS.fbArbiter2, bEnableMotion:=TRUE, bEnableBeamParams:=TRUE, sDeviceName:='MR3K2:KBH', sTransitionKey:='MR3K2:KBH-TRANSITION', ); fbM3K2_Chin_Right_RTD(fResolution:=0.01); fbM3K2_Chin_Left_RTD(fResolution:=0.01); END_PROGRAM Related: * `E_B4C_Rh_CoatingStates`_ * `GVL_M3K2`_ * `GVL_PMPS`_ * `GVL_States`_ * `Main`_ PRG_MR4K2_KBV ^^^^^^^^^^^^^ :: PROGRAM PRG_MR4K2_KBV VAR // Encoder Arrays/RMS Watch: //MR4K2 X ENC RMS {attribute 'pytmc' := ' pv: MR4K2:KBV:ENC:X'} fbXRMSErrorM4K2 : FB_RMSWatch; fMaxXRMSErrorM4K2 : LREAL; fMinXRMSErrorM4K2 : LREAL; //MR4K2 Y ENC RMS {attribute 'pytmc' := ' pv: MR4K2:KBV:ENC:Y'} fbYRMSErrorM4K2 : FB_RMSWatch; fMaxYRMSErrorM4K2 : LREAL; fMinYRMSErrorM4K2 : LREAL; //MR4K2 rX ENC RMS {attribute 'pytmc' := ' pv: MR4K2:KBV:ENC:PITCH'} fbrXRMSErrorM4K2 : FB_RMSWatch; fMaxrXRMSErrorM4K2 : LREAL; fMinrXRMSErrorM4K2 : LREAL; //MR4K2 US ENC RMS {attribute 'pytmc' := ' pv: MR4K2:KBV:ENC:BEND:US'} fbUSRMSErrorM4K2 : FB_RMSWatch; fMaxUSRMSErrorM4K2 : LREAL; fMinUSRMSErrorM4K2 : LREAL; //MR4K2 DS ENC RMS {attribute 'pytmc' := ' pv: MR4K2:KBV:ENC:BEND:DS'} fbdSRMSErrorM4K2 : FB_RMSWatch; fMaxDSRMSErrorM4K2 : LREAL; fMinDSRMSErrorM4K2 : LREAL; // Encoder Reference Values //MR4K2 X ENC REF {attribute 'pytmc' := ' pv: MR4K2:KBV:ENC:X:REF field: EGU cnt io: i '} nEncRefXM4K2 : UDINT; //MR4K2 Y ENC REF {attribute 'pytmc' := ' pv: MR4K2:KBV:ENC:Y:REF field: EGU cnt io: i '} nEncRefYM4K2 : UDINT; //MR4K2 rX ENC REF {attribute 'pytmc' := ' pv: MR4K2:KBV:ENC:PITCH:REF field: EGU cnt io: i '} nEncRefrXM4K2 : UDINT; //MR4K2 US ENC REF {attribute 'pytmc' := ' pv: MR4K2:KBV:ENC:BEND:US:REF field: EGU cnt io: i '} nEncRefUSM4K2 : UDINT; //MR4K2 DS ENC REF {attribute 'pytmc' := ' pv: MR4K2:KBV:ENC:BEND:DS:REF field: EGU cnt io: i '} nEncRefDSM4K2 : UDINT; // Encoder raw counts //M4K2 KBV X ENC CNT {attribute 'pytmc' := ' pv: MR4K2:KBV:ENC:X:CNT field: EGU cnt io: i '} nEncCntXM4K2 : UDINT; //M4K2 KBV Y ENC CNT {attribute 'pytmc' := ' pv: MR4K2:KBV:ENC:Y:CNT field: EGU cnt io: i '} nEncCntYM4K2 : UDINT; //M4K2 KBV rX ENC CNT {attribute 'pytmc' := ' pv: MR4K2:KBV:ENC:PITCH:CNT field: EGU cnt io: i '} nEncCntrXM4K2 : UDINT; //M4K2 KBV US ENC CNT {attribute 'pytmc' := ' pv: MR4K2:KBV:ENC:BEND:US:CNT field: EGU cnt io: i '} nEncCntUSM4K2 : UDINT; //M4K2 KBV DS ENC CNT {attribute 'pytmc' := ' pv: MR4K2:KBV:ENC:BEND:DS:CNT field: EGU cnt io: i '} nEncCntDSM4K2 : UDINT; // MR4K2 Bender RTDs // MR4K2 US RTDs {attribute 'pytmc' := ' pv: MR4K2:KBV:RTD:BEND:US:1 field: ASLO 0.01 field: EGU C io: i '} fM4K2US_RTD_1 : REAL; {attribute 'pytmc' := ' pv: MR4K2:KBV:RTD:BEND:US:2 field: ASLO 0.01 field: EGU C io: i '} fM4K2US_RTD_2 : REAL; {attribute 'pytmc' := ' pv: MR4K2:KBV:RTD:BEND:US:3 field: ASLO 0.01 field: EGU C io: i '} fM4K2US_RTD_3 : REAL; // M4K2 DS RTDs {attribute 'pytmc' := ' pv: MR4K2:KBV:RTD:BEND:DS:1 field: ASLO 0.01 field: EGU C io: i '} fM4K2DS_RTD_1 : REAL; {attribute 'TcLinkTo' := '.iRaw := TIIB[EL3204_M4K2_CHIN]^RTD Inputs Channel 1^Value; .bUnderrange := TIIB[EL3204_M4K2_CHIN]^RTD Inputs Channel 1^Status^Underrange; .bOverrange := TIIB[EL3204_M4K2_CHIN]^RTD Inputs Channel 1^Status^Overrange; .bError := TIIB[EL3204_M4K2_CHIN]^RTD Inputs Channel 1^Status^Error'} {attribute 'pytmc' := ' pv: MR4K2:KBV:RTD:CHIN:R field: EGU C io: i '} fbM4K2_Chin_Right_RTD : FB_TempSensor; {attribute 'TcLinkTo' := '.iRaw := TIIB[EL3204_M4K2_CHIN]^RTD Inputs Channel 2^Value; .bUnderrange := TIIB[EL3204_M4K2_CHIN]^RTD Inputs Channel 2^Status^Underrange; .bOverrange := TIIB[EL3204_M4K2_CHIN]^RTD Inputs Channel 2^Status^Overrange; .bError := TIIB[EL3204_M4K2_CHIN]^RTD Inputs Channel 2^Status^Error'} {attribute 'pytmc' := ' pv: MR4K2:KBV:RTD:CHIN:L field: EGU C io: i '} fbM4K2_Chin_Left_RTD : FB_TempSensor; // RTD error bit bM4K2US_RTD_1_Err AT %I*: BOOL; bM4K2US_RTD_2_Err AT %I*: BOOL; bM4K2US_RTD_3_Err AT %I*: BOOL; bM4K2DS_RTD_1_Err AT %I*: BOOL; bM4K2DS_RTD_2_Err AT %I*: BOOL; bM4K2DS_RTD_3_Err AT %I*: BOOL; //Emergency Stop for MR4K2 {attribute 'TcLinkTo' := 'TIID^Device 1 (EtherCAT)^Term 1 (EK1200)^Term 79 (EK1521-0010)^Term 306 (EK1501-0010)^Term 322 (EK1122)^EK1100_MR4K2_BENDER^EL1004_M4K2_STO^Channel 1^Input'} M4K2KBVbSTOEnable1 AT %I* : BOOL; {attribute 'TcLinkTo' := 'TIID^Device 1 (EtherCAT)^Term 1 (EK1200)^Term 79 (EK1521-0010)^Term 306 (EK1501-0010)^Term 322 (EK1122)^EK1100_MR4K2_BENDER^EL1004_M4K2_STO^Channel 2^Input'} M4K2KBVbSTOEnable2 AT %I* : BOOL; // MR4K2 Flow Sensors {attribute 'TcLinkTo' := '.fbFlow_1.iRaw := TIIB[EL3054_MR3_4K2_FWM_PRSM]^AI Standard Channel 3^Value; .fbPress_1.iRaw := TIIB[EL3054_MR3_4K2_FWM_PRSM]^AI Standard Channel 2^Value '} {attribute 'pytmc' := ' pv: MR4K2:KBV '} fbCoolingPanel : FB_Axilon_Cooling_1f1p; (* // PMPS ffBenderRange : FB_FastFault := ( i_xAutoReset := TRUE, i_DevName := 'MR4K2 Bender', i_Desc := 'Benders have moved out of range. Adjust bender to be within limits to clear fault', i_TypeCode := 16#???); *) {attribute 'pytmc' := 'pv: MR4K2:KBV:COATING'} fbCoatingStates: FB_PositionStatePMPS1D; {attribute 'pytmc' := ' pv: MR4K2:KBV:COATING:STATE:SET io: io '} eStateSet: E_B4C_Rh_CoatingStates; {attribute 'pytmc' := ' pv: MR4K2:KBV:COATING:STATE:GET io: i '} eStateGet: E_B4C_Rh_CoatingStates; fbXSetup: FB_StateSetupHelper; astCoatingStatesX: ARRAY[1..GeneralConstants.MAX_STATES] OF ST_PositionState; END_VAR //FB_Motion stages for MR4K2 Axes //MR4K2 KBV fbMotionStageM33(stMotionStage:=M33); fbMotionStageM34(stMotionStage:=M34); fbMotionStageM35(stMotionStage:=M35); fbMotionStageM36(stMotionStage:=M36); fbMotionStageM37(stMotionStage:=M37); // Calculate Pitch RMS Error for MR4K2 Axes: //MR4K2 X ENC RMS fbXRMSErrorM4K2(stMotionStage:=M33, fMaxRMSError=>fMaxXRMSErrorM4K2, fMinRMSError=>fMinXRMSErrorM4K2); //MR4K2 X ENC RMS fbYRMSErrorM4K2(stMotionStage:=M34, fMaxRMSError=>fMaxYRMSErrorM4K2, fMinRMSError=>fMinYRMSErrorM4K2); //MR4K2 rX ENC RMS fbrXRMSErrorM4K2(stMotionStage:=M35, fMaxRMSError=>fMaxrXRMSErrorM4K2, fMinRMSError=>fMinrXRMSErrorM4K2); //MR4K2 US ENC RMS fbUSRMSErrorM4K2(stMotionStage:=M36, fMaxRMSError=>fMaxUSRMSErrorM4K2, fMinRMSError=>fMinUSRMSErrorM4K2); //MR4K2 DS ENC RMS fbDSRMSErrorM4K2(stMotionStage:=M37, fMaxRMSError=>fMaxDSRMSErrorM4K2, fMinRMSError=>fMinDSRMSErrorM4K2); //STO for MR4K2 Benders M33.bHardwareEnable := M4K2KBVbSTOEnable1 AND M4K2KBVbSTOEnable2; M34.bHardwareEnable := M4K2KBVbSTOEnable1 AND M4K2KBVbSTOEnable2; M35.bHardwareEnable := M4K2KBVbSTOEnable1 AND M4K2KBVbSTOEnable2; M36.bHardwareEnable := M4K2KBVbSTOEnable1 AND M4K2KBVbSTOEnable2; M37.bHardwareEnable := M4K2KBVbSTOEnable1 AND M4K2KBVbSTOEnable2; //Encoder reference positions for MR4K2 nEncRefXM4K2 := ULINT_TO_UDINT(GVL_M4K2.nM4K2X_ENC_REF); nEncRefYM4K2 := ULINT_TO_UDINT(GVL_M4K2.nM4K2Y_ENC_REF); nEncRefrXM4K2 := ULINT_TO_UDINT(GVL_M4K2.nM4K2rX_ENC_REF); nEncRefUSM4K2 := ULINT_TO_UDINT(GVL_M4K2.nM4K2US_ENC_REF); nEncRefDSM4K2 := ULINT_TO_UDINT(GVL_M4K2.nM4K2DS_ENC_REF); // M4K2 Bender Encoder Count Values For Epics nEncCntXM4K2 := ULINT_TO_UDINT(M33.nRawEncoderULINT); nEncCntYM4K2 := ULINT_TO_UDINT(M34.nRawEncoderULINT); nEncCntrXM4K2 := ULINT_TO_UDINT(M35.nRawEncoderULINT); nEncCntUSM4K2 := ULINT_TO_UDINT(M36.nRawEncoderULINT); nEncCntDSM4K2 := ULINT_TO_UDINT(M37.nRawEncoderULINT); // MR4K2 Bender RTDs fM4K2US_RTD_1 := INT_TO_REAL(GVL_M4K2.nM4K2US_RTD_1); fM4K2US_RTD_2 := INT_TO_REAL(GVL_M4K2.nM4K2US_RTD_2); fM4K2US_RTD_3 := INT_TO_REAL(GVL_M4K2.nM4K2US_RTD_3); fM4K2DS_RTD_1 := INT_TO_REAL(GVL_M4K2.nM4K2DS_RTD_1); // RTD not connected if T=0 bM4K2US_RTD_1_Err := fM4K2US_RTD_1 = 0; bM4K2US_RTD_2_Err := fM4K2US_RTD_2 = 0; bM4K2US_RTD_3_Err := fM4K2US_RTD_3 = 0; bM4K2DS_RTD_1_Err := fM4K2DS_RTD_1 = 0; // M4K2 Bender RTD interlocks M36.bHardwareEnable R= fM4K2US_RTD_1 > 9000 OR bM4K2US_RTD_1_Err; M37.bHardwareEnable R= fM4K2DS_RTD_1 > 9000 OR bM4K2DS_RTD_1_Err; fbM4K2_Chin_Right_RTD(fResolution:=0.01); fbM4K2_Chin_Left_RTD(fResolution:=0.01); // Axilon Cooling Panel fbCoolingPanel(); (* //PMPS ffBenderRange.i_xOK := GVL_M4K2.nM4K2US_PMPS_LowerLimit < nEncCntUSM4K2 AND nEncCntUSM4K2 < GVL_M4K2.nM4K2US_PMPS_UpperLimit AND GVL_M4K2.nM4K2DS_PMPS_LowerLimit < nEncCntDSM4K2 AND nEncCntUSM4K2 < GVL_M4K2.nM4K2DS_PMPS_UpperLimit; ffBenderRange(io_fbFFHWO := GVL_PMPS.fbFastFaultOutput1); *) fbXSetup(stPositionState:=GVL_States.stDefaultKBX, bSetDefault:=TRUE); fbXSetup(stPositionState:=astCoatingStatesX[E_B4C_Rh_CoatingStates.B4C], sName:='B4C', sPmpsState:='MR4K2:KBV-B4C', nEncoderCount:=5824240, fDelta:=5 ); fbXSetup(stPositionState:=astCoatingStatesX[E_B4C_Rh_CoatingStates.Rh], sName:='Rh', sPmpsState:='MR4K2:KBV-RHODIUM', nEncoderCount:=3524222, fDelta:=1.5 ); fbCoatingStates( stMotionStage:=Main.M33, astPositionState:=astCoatingStatesX, eEnumSet:=eStateSet, eEnumGet:=eStateGet, fbFFHWO:=GVL_PMPS.fbFastFaultOutput2, fbArbiter:=GVL_PMPS.fbArbiter2, bEnableMotion:=TRUE, bEnableBeamParams:=TRUE, sDeviceName:='MR4K2:KBV', sTransitionKey:='MR4K2:KBV-TRANSITION', ); END_PROGRAM Related: * `E_B4C_Rh_CoatingStates`_ * `GVL_M4K2`_ * `GVL_PMPS`_ * `GVL_States`_ * `Main`_ PRG_SL1K2_EXIT ^^^^^^^^^^^^^^ :: PROGRAM PRG_SL1K2_EXIT VAR FFO : FB_FastFault :=( i_DevName := 'SL1K2-EXIT', i_Desc := 'Fault occurs when device is in an usafe state', i_TypeCode := 16#E50); fbPitch: FB_MotionStage; fbRoll: FB_MotionStage; fbVertical: FB_MotionStage; fbGap: FB_MotionStage; fbYag: FB_MotionStage; {attribute 'pytmc' := ' pv: SL1K2:EXIT:YAG:STATE io: i '} fbStates: FB_XS_YAG_States; {attribute 'pytmc' := ' pv: SL1K2:EXIT:RTD:CRYSTAL_TOP '} {attribute 'TcLinkTo' := '.iRaw := TIIB[EL3201_SL1K2_1]^RTD^Value; .bError := TIIB[EL3201_SL1K2_1]^RTD^Status^Error; .bUnderrange := TIIB[EL3201_SL1K2_1]^RTD^Status^Underrange; .bOverrange := TIIB[EL3201_SL1K2_1]^RTD^Status^Overrange'} RTD_Crystal_TOP: FB_TempSensor; {attribute 'pytmc' := ' pv: SL1K2:EXIT:RTD:CRYSTAL_BOTTOM '} {attribute 'TcLinkTo' := '.iRaw := TIIB[EL3201_SL1K2_2]^RTD^Value; .bError := TIIB[EL3201_SL1K2_2]^RTD^Status^Error; .bUnderrange := TIIB[EL3201_SL1K2_2]^RTD^Status^Underrange; .bOverrange := TIIB[EL3201_SL1K2_2]^RTD^Status^Overrange'} RTD_Crystal_BOTTOM: FB_TempSensor; {attribute 'pytmc' := ' pv: SL1K2:EXIT:RTD:YAG '} {attribute 'TcLinkTo' := '.iRaw := TIIB[EL3201_SL1K2_4]^RTD^Value; .bError := TIIB[EL3201_SL1K2_4]^RTD^Status^Error; .bUnderrange := TIIB[EL3201_SL1K2_4]^RTD^Status^Underrange; .bOverrange := TIIB[EL3201_SL1K2_4]^RTD^Status^Overrange'} RTD_YAG: FB_TempSensor; {attribute 'pytmc' := ' pv: SL1K2:EXIT:RTD:HeatSync '} {attribute 'TcLinkTo' := '.iRaw := TIIB[EL3201_SL1K2_3]^RTD^Value; .bError := TIIB[EL3201_SL1K2_3]^RTD^Status^Error; .bUnderrange := TIIB[EL3201_SL1K2_3]^RTD^Status^Underrange; .bOverrange := TIIB[EL3201_SL1K2_3]^RTD^Status^Overrange'} RTD_HeatSync: FB_TempSensor; {attribute 'pytmc' := ' pv: SL1K2:EXIT:FAN:PWR field: ZNAM OFF ; field: ONAM ON ; '} {attribute 'TcLinkTo' := 'TIIB[EL2004_SL1K2]^Channel 1^Output'} bFanOn AT %Q*:BOOL; {attribute 'pytmc' := ' pv: SL1K2:EXIT:LED:PWR io: io field: ZNAM OFF field: ONAM ON '} {attribute 'TcLinkTo' := 'TIIB[EL2004_SL1K2]^Channel 2^Output'} bLEDPower AT %Q*: BOOL; {attribute 'pytmc' := ' pv: SL1K2:EXIT:CAM '} {attribute 'TcLinkTo' := '.iIlluminatorINT := TIIB[EL4004_SL1K2]^AO Outputs Channel 1^Analog output; .bGigePower := TIIB[EL2004_SL1K2]^Channel 3^Output'} fbGige: FB_PPM_Gige; {attribute 'pytmc' :='pv: SL1K2:EXIT:FWM'} {attribute 'TcLinkTo' := '.iRaw := TIIB[EL3052_SL1K2_FWM]^AI Standard Channel 1^Value'} fbFlowMeter: FB_AnalogInput := (iTermBits:=15, fTermMax:=60, fTermMin:=0); bInit : BOOL:=TRUE; (*Motion Parameters*) fSmallDelta: LREAL := 0.01; fBigDelta: LREAL := 10; fMaxVelocity: LREAL := 0.5; fHighAccel: LREAL := 0.8; fLowAccel: LREAL := 0.1; END_VAR // init the motion stages parameters IF ( bInit) THEN bInit := FALSE; FFO.i_DevName := 'SL1K2-EXIT'; //Pitch Main.M19.bHardwareEnable := TRUE; Main.M19.bPowerSelf :=TRUE; Main.M19.nBrakeMode := ENUM_StageBrakeMode.NO_BRAKE; Main.M19.nEnableMode := ENUM_StageEnableMode.DURING_MOTION; //Vert Main.M20.bHardwareEnable := TRUE; Main.M20.bPowerSelf :=TRUE; Main.M20.nBrakeMode := ENUM_StageBrakeMode.NO_BRAKE; Main.M20.nEnableMode := ENUM_StageEnableMode.DURING_MOTION; //ROLL Main.M21.bHardwareEnable := TRUE; Main.M21.bPowerSelf :=TRUE; Main.M21.nBrakeMode := ENUM_StageBrakeMode.NO_BRAKE; Main.M21.nEnableMode := ENUM_StageEnableMode.DURING_MOTION; //GAP Main.M22.bHardwareEnable := TRUE; Main.M22.bPowerSelf :=TRUE; Main.M22.nBrakeMode := ENUM_StageBrakeMode.NO_BRAKE; Main.M22.nEnableMode := ENUM_StageEnableMode.DURING_MOTION; //YAG Main.M23.bHardwareEnable := TRUE; Main.M23.bPowerSelf :=FALSE; Main.M23.nBrakeMode := ENUM_StageBrakeMode.NO_BRAKE; Main.M23.nEnableMode := ENUM_StageEnableMode.DURING_MOTION; // YAG STATES Parameters //fbStates.nTransitionAssertionID := 16#E510; //fbStates.nUnknownAssertionID := 16#E500; //Out fbStates.stOut.fPosition := 0; fbStates.stOut.bUseRawCounts := FALSE; fbStates.stOut.bValid := TRUE; fbStates.stOut.stPMPS.sPmpsState := 'SL1K2:EXIT:YAG-OUT'; //Yag1 fbStates.stYag1.fPosition := 21; fbStates.stYag1.bUseRawCounts := FALSE; fbStates.stYag1.bValid := TRUE; fbStates.stYag1.stPMPS.sPmpsState := 'SL1K2:EXIT:YAG-YAG1'; //Yag2 fbStates.stYag2.fPosition := 40; fbStates.stYag2.bUseRawCounts := FALSE; fbStates.stYag2.bValid := TRUE; fbStates.stYag2.stPMPS.sPmpsState := 'SL1K2:EXIT:YAG-YAG2'; //Turn on Fan by default bFanOn := TRUE; END_IF // Instantiate Function block for all the motion fbPitch(stMotionStage:=Main.M19);//in Air fbRoll(stMotionStage:=Main.M20);//in Air fbVertical(stMotionStage:=Main.M21);//in Air Main.M22.bLimitBackwardEnable := TRUE; fbGap(stMotionStage:=Main.M22);//in vacuum fbYag(stMotionStage:=Main.M23);//in vacuum //States with PMPS fbStates( fbArbiter:=GVL_PMPS.fbArbiter1, fbFFHWO:=GVL_PMPS.fbFastFaultOutput1, sPmpsDeviceName:='SL1K2:EXIT:YAG', sTransitionKey:='SL1K2:EXIT:YAG-TRANSITION', stMotionStage:=Main.M23, bEnable:=TRUE, stOut:=, stYag1:=, stYag2:=); //Camera and Ilumination fbGige(); //RTDs RTD_Crystal_TOP(fResolution:=0.01); RTD_Crystal_BOTTOM(fResolution:=0.01); RTD_YAG(fResolution:=0.01); RTD_HeatSync(fResolution:=0.01); //Cooling fbFlowMeter(); END_PROGRAM Related: * `FB_XS_YAG_States`_ * `GVL_PMPS`_ * `Main`_ PRG_SP1K1_MONO ^^^^^^^^^^^^^^ :: PROGRAM PRG_SP1K1_MONO VAR // Where is the STO {attribute 'TcLinkTo' := 'TIID^Device 1 (EtherCAT)^Term 1 (EK1200)^E5 (EK1122)^X1 SP1K1-MONO(EK1100)^SP1K1-EL1004-E17^Channel 1^Input'} bSTOEnable1 AT %I*: BOOL; {attribute 'TcLinkTo' := 'TIID^Device 1 (EtherCAT)^Term 1 (EK1200)^E5 (EK1122)^X1 SP1K1-MONO(EK1100)^SP1K1-EL1004-E17^Channel 2^Input'} bSTOEnable2 AT %I*: BOOL; fbMotionStage_m_pi :FB_MotionStage; fbMotionStage_g_pi :FB_MotionStage; fbMotionStage_m_h :FB_MotionStage; fbMotionStage_g_h :FB_MotionStage; fbMotionStage_s_r :FB_MotionStage; fbMotionStage_s_io :FB_MotionStage; {attribute 'TcLinkTo' := '.Count:=TIIB[m_pi_up_dwn_e]^FB Inputs Channel 1^Position'} mpi_upe AT %I*: ST_RenishawAbsEnc:=(ref:=0); {attribute 'TcLinkTo' := '.Count:=TIIB[g_pi_up_dwn_e]^FB Inputs Channel 1^Position'} gpi_upe AT %I*: ST_RenishawAbsEnc:=(ref:=0); {attribute 'pytmc' := ' pv: SP1K1:MONO:ENC:M_PI:02 io: o '} mpi_upeurad: LREAL; {attribute 'pytmc' := ' pv: SP1K1:MONO:ENC:G_PI:02 io: o '} gpi_upeurad: LREAL; (*RTDs*) {attribute 'pytmc' := ' pv: SP1K1:MONO:RTD:01 io: o '} {attribute 'TcLinkTo' := '.iRaw := TIIB[SP1K1-EP3204-0002-EP2]^RTD RTDInputs Channel 1^Value; .bError := TIIB[SP1K1-EP3204-0002-EP2]^RTD RTDInputs Channel 1^Status^Error; .bUnderrange := TIIB[SP1K1-EP3204-0002-EP2]^RTD RTDInputs Channel 1^Status^Underrange; .bOverrange := TIIB[SP1K1-EP3204-0002-EP2]^RTD RTDInputs Channel 1^Status^Overrange'} RTD1 : FB_TempSensor; {attribute 'pytmc' := ' pv: SP1K1:MONO:RTD:02 io: o '} {attribute 'TcLinkTo' := '.iRaw := TIIB[SP1K1-EP3204-0002-EP2]^RTD RTDInputs Channel 2^Value; .bError := TIIB[SP1K1-EP3204-0002-EP2]^RTD RTDInputs Channel 2^Status^Error; .bUnderrange := TIIB[SP1K1-EP3204-0002-EP2]^RTD RTDInputs Channel 2^Status^Underrange; .bOverrange := TIIB[SP1K1-EP3204-0002-EP2]^RTD RTDInputs Channel 2^Status^Overrange'} RTD2 : FB_TempSensor; {attribute 'pytmc' := ' pv: SP1K1:MONO:RTD:03 io: o '} {attribute 'TcLinkTo' := '.iRaw := TIIB[SP1K1-EP3204-0002-EP2]^RTD RTDInputs Channel 3^Value; .bError := TIIB[SP1K1-EP3204-0002-EP2]^RTD RTDInputs Channel 3^Status^Error; .bUnderrange := TIIB[SP1K1-EP3204-0002-EP2]^RTD RTDInputs Channel 3^Status^Underrange; .bOverrange := TIIB[SP1K1-EP3204-0002-EP2]^RTD RTDInputs Channel 3^Status^Overrange'} RTD3 : FB_TempSensor; {attribute 'pytmc' := ' pv: SP1K1:MONO:RTD:04 io: o '} {attribute 'TcLinkTo' := '.iRaw := TIIB[SP1K1-EP3204-0002-EP2]^RTD RTDInputs Channel 4^Value; .bError := TIIB[SP1K1-EP3204-0002-EP2]^RTD RTDInputs Channel 4^Status^Error; .bUnderrange := TIIB[SP1K1-EP3204-0002-EP2]^RTD RTDInputs Channel 4^Status^Underrange; .bOverrange := TIIB[SP1K1-EP3204-0002-EP2]^RTD RTDInputs Channel 4^Status^Overrange'} RTD4 : FB_TempSensor; {attribute 'pytmc' := ' pv: SP1K1:MONO:RTD:05 io: o '} {attribute 'TcLinkTo' := '.iRaw := TIIB[SP1K1-EL3204-E15]^RTD Inputs Channel 1^Value; .bError := TIIB[SP1K1-EL3204-E15]^RTD Inputs Channel 1^Status^Error; .bUnderrange := TIIB[SP1K1-EL3204-E15]^RTD Inputs Channel 1^Status^Underrange; .bOverrange := TIIB[SP1K1-EL3204-E15]^RTD Inputs Channel 1^Status^Overrange'} RTD5 :FB_TempSensor; {attribute 'pytmc' := ' pv: SP1K1:MONO:RTD:06 io: o '} {attribute 'TcLinkTo' := '.iRaw := TIIB[SP1K1-EL3204-E15]^RTD Inputs Channel 2^Value; .bError := TIIB[SP1K1-EL3204-E15]^RTD Inputs Channel 2^Status^Error; .bUnderrange := TIIB[SP1K1-EL3204-E15]^RTD Inputs Channel 2^Status^Underrange; .bOverrange := TIIB[SP1K1-EL3204-E15]^RTD Inputs Channel 2^Status^Overrange'} RTD6 :FB_TempSensor; {attribute 'pytmc' := ' pv: SP1K1:MONO:RTD:07 io: o '} {attribute 'TcLinkTo' := '.iRaw := TIIB[SP1K1-EL3204-E15]^RTD Inputs Channel 3^Value; .bError := TIIB[SP1K1-EL3204-E15]^RTD Inputs Channel 3^Status^Error; .bUnderrange := TIIB[SP1K1-EL3204-E15]^RTD Inputs Channel 3^Status^Underrange; .bOverrange := TIIB[SP1K1-EL3204-E15]^RTD Inputs Channel 3^Status^Overrange'} RTD7 :FB_TempSensor; {attribute 'pytmc' := ' pv: SP1K1:MONO:RTD:08 io: o '} {attribute 'TcLinkTo' := '.iRaw := TIIB[SP1K1-EL3204-E15]^RTD Inputs Channel 4^Value; .bError := TIIB[SP1K1-EL3204-E15]^RTD Inputs Channel 4^Status^Error; .bUnderrange := TIIB[SP1K1-EL3204-E15]^RTD Inputs Channel 4^Status^Underrange; .bOverrange := TIIB[SP1K1-EL3204-E15]^RTD Inputs Channel 4^Status^Overrange'} RTD8 :FB_TempSensor; {attribute 'pytmc' := ' pv: SP1K1:MONO:RTD:09 io: o '} {attribute 'TcLinkTo' := '.iRaw := TIIB[SP1K1-EL3204-E16]^RTD Inputs Channel 1^Value; .bError := TIIB[SP1K1-EL3204-E16]^RTD Inputs Channel 1^Status^Error; .bUnderrange := TIIB[SP1K1-EL3204-E16]^RTD Inputs Channel 1^Status^Underrange; .bOverrange := TIIB[SP1K1-EL3204-E16]^RTD Inputs Channel 1^Status^Overrange'} RTD9 :FB_TempSensor; {attribute 'pytmc' := ' pv: SP1K1:MONO:RTD:10 io: o '} {attribute 'TcLinkTo' := '.iRaw := TIIB[SP1K1-EL3204-E16]^RTD Inputs Channel 2^Value; .bError := TIIB[SP1K1-EL3204-E16]^RTD Inputs Channel 2^Status^Error; .bUnderrange := TIIB[SP1K1-EL3204-E16]^RTD Inputs Channel 2^Status^Underrange; .bOverrange := TIIB[SP1K1-EL3204-E16]^RTD Inputs Channel 2^Status^Overrange'} RTD10 :FB_TempSensor; {attribute 'pytmc' := ' pv: SP1K1:MONO:RTD:11 io: o '} {attribute 'TcLinkTo' := '.iRaw := TIIB[SP1K1-EL3204-E16]^RTD Inputs Channel 3^Value; .bError := TIIB[SP1K1-EL3204-E16]^RTD Inputs Channel 3^Status^Error; .bUnderrange := TIIB[SP1K1-EL3204-E16]^RTD Inputs Channel 3^Status^Underrange; .bOverrange := TIIB[SP1K1-EL3204-E16]^RTD Inputs Channel 3^Status^Overrange'} RTD11 :FB_TempSensor; {attribute 'pytmc' := ' pv: SP1K1:MONO:RTD:12 io: o '} {attribute 'TcLinkTo' := '.iRaw := TIIB[SP1K1-EL3204-E16]^RTD Inputs Channel 4^Value; .bError := TIIB[SP1K1-EL3204-E16]^RTD Inputs Channel 4^Status^Error; .bUnderrange := TIIB[SP1K1-EL3204-E16]^RTD Inputs Channel 4^Status^Underrange; .bOverrange := TIIB[SP1K1-EL3204-E16]^RTD Inputs Channel 4^Status^Overrange'} RTD12 :FB_TempSensor; //////////TODO {attribute 'pytmc' := ' pv: GM:PITCH:fipi_read io: i '} fipi_read: LREAL; {attribute 'pytmc' := ' pv: GM:PITCH:fipi_set io: o '} fipi_set: LREAL; {attribute 'pytmc' := ' pv: SP1K1:MONO:LED:01:PWR io: io field: ZNAM OFF field: ONAM ON '} {attribute 'TcLinkTo' := 'TIID^Device 1 (EtherCAT)^Term 1 (EK1200)^E5 (EK1122)^Box 84 (EP2338-0002)^Channel 10^Output'} bLEDPower01 AT %Q*: BOOL; {attribute 'pytmc' := ' pv: SP1K1:MONO:LED:02:PWR io: io field: ZNAM OFF field: ONAM ON '} {attribute 'TcLinkTo' := 'TIID^Device 1 (EtherCAT)^Term 1 (EK1200)^E5 (EK1122)^Box 84 (EP2338-0002)^Channel 12^Output'} bLEDPower02 AT %Q*: BOOL; {attribute 'pytmc' := ' pv: SP1K1:MONO:LED:03:PWR io: io field: ZNAM OFF field: ONAM ON '} {attribute 'TcLinkTo' := 'TIID^Device 1 (EtherCAT)^Term 1 (EK1200)^E5 (EK1122)^Box 84 (EP2338-0002)^Channel 14^Output'} bLEDPower03 AT %Q*: BOOL; sd_io_FFO : FB_FastFault :=( i_DevName := 'SP1K1-MONO', i_Desc := 'Fault occurs When SP1K1-MONO screw driver motor is not in the out position', i_TypeCode := 16#1110); sd_io_e_pmps : LREAL:= 74000.29; // SP1K1 Flow Press Sensors {attribute 'TcLinkTo' := '.iRaw := TIIB[EL3054_SP1K1_FWM_PRSM]^AI Standard Channel 1^Value'} fSP1K1_Flow_1 : FB_AnalogInput; {attribute 'pytmc' := ' pv: SP1K1:MONO:FWM:1 field: EGU lpm io: i '} fSP1K1_Flow_1_val : LREAL; {attribute 'TcLinkTo' := '.iRaw := TIIB[EL3054_SP1K1_FWM_PRSM]^AI Standard Channel 2^Value'} fSP1K1_Flow_2 : FB_AnalogInput; {attribute 'pytmc' := ' pv: SP1K1:MONO:FWM:2 field: EGU lpm io: i '} fSP1K1_Flow_2_val : LREAL; {attribute 'TcLinkTo' := '.iRaw := TIIB[EL3054_SP1K1_FWM_PRSM]^AI Standard Channel 3^Value'} fSP1K1_Press_1 : FB_AnalogInput; {attribute 'pytmc' := ' pv: SP1K1:MONO:PRSM:1 field: EGU bar io: i '} fSP1K1_Press_1_val : LREAL; stDefaultGH : ST_PositionState := ( fDelta:=2000, fVelocity:=875.0, fAccel:=6923, fDecel:=6923, bMoveOk:=TRUE, bValid:=TRUE, bUseRawCounts:=TRUE ); {attribute 'pytmc' := 'pv: SP1K1:MONO:GRATING'} fbGratingStates: FB_PositionStatePMPS1D; {attribute 'pytmc' := ' pv: SP1K1:MONO:GRATING:STATE:SET io: io '} eStateSet: E_Grating_States; {attribute 'pytmc' := ' pv: SP1K1:MONO:GRATING:STATE:GET io: i '} eStateGet: E_Grating_States; fbGHSetup: FB_StateSetupHelper; astGratingStates: ARRAY[1..GeneralConstants.MAX_STATES] OF ST_PositionState; END_VAR // SP1K1-MONO M6.bHardwareEnable := bSTOEnable1 AND bSTOEnable2; M7.bHardwareEnable := bSTOEnable1 AND bSTOEnable2; M8.bHardwareEnable := bSTOEnable1 AND bSTOEnable2; M9.bHardwareEnable := bSTOEnable1 AND bSTOEnable2; M10.bHardwareEnable := bSTOEnable1 AND bSTOEnable2; M11.bHardwareEnable := bSTOEnable1 AND bSTOEnable2; fbMotionStage_m_pi (stMotionStage:=M6); fbMotionStage_g_pi (stMotionStage:=M7); fbMotionStage_m_h (stMotionStage:=M8); fbMotionStage_g_h (stMotionStage:=M9); fbMotionStage_s_io (stMotionStage:=M10); fbMotionStage_s_r (stMotionStage:=M11); //S_R with no hardware limit switched M11.bLimitBackwardEnable := TRUE; M11.bLimitForwardEnable := TRUE; mpi_upeurad := ULINT_TO_LREAL(mpi_upe.Count)*0.004505; gpi_upeurad := ULINT_TO_LREAL(gpi_upe.Count)*0.0066667; (*RTDs*) RTD1(fResolution:=0.01); RTD2(fResolution:=0.01); RTD3(fResolution:=0.01); RTD4(fResolution:=0.01); RTD5(); RTD6(); RTD7(); RTD8(); RTD9(); RTD10(); RTD11(); RTD12(); //Evaluate the encoder reading for the screw driver encoder. Fast fault when it is not out. // i.e. encoder value must be greater than the out position (75000.29 - 1000u) IF( M10.Axis.NcToPlc.ActPos < sd_io_e_pmps) THEN sd_io_FFO.i_xOK := FALSE; ELSE sd_io_FFO.i_xOK := TRUE; END_IF (*FAST FAULT*) sd_io_FFO(i_xOK := , i_xReset := , i_xAutoReset :=TRUE, io_fbFFHWO := GVL_PMPS.fbFastFaultOutput1); fSP1K1_Flow_1(iTermBits:=15, fTermMax:=5.0427, fTermMin:=0.050472); fSP1K1_Flow_1_val := fSP1K1_Flow_1.fReal; fSP1K1_Flow_2(iTermBits:=15, fTermMax:=5.0427, fTermMin:=0.050472); fSP1K1_Flow_2_val := fSP1K1_Flow_2.fReal; fSP1K1_Press_1(iTermBits:=15, fTermMax:=4.0, fTermMin:=0); fSP1K1_Press_1_val := fSP1K1_Press_1.fReal; fbGHSetup(stPositionState:=stDefaultGH, bSetDefault:=TRUE); fbGHSetup(stPositionState:=astGratingStates[E_Grating_States.LRG], sName:='LRG', sPmpsState:='SP1K1:MONO-LRG', nEncoderCount:=7599807, ); fbGHSetup(stPositionState:=astGratingStates[E_Grating_States.Unruled], sName:='UNRULED', sPmpsState:='SP1K1:MONO-UNRULED', nEncoderCount:=10000269, ); fbGHSetup(stPositionState:=astGratingStates[E_Grating_States.YAG], sName:='YAG', sPmpsState:='SP1K1:MONO-YAG', nEncoderCount:=16000506, ); fbGHSetup(stPositionState:=astGratingStates[E_Grating_States.MEG], sName:='MEG', sPmpsState:='SP1K1:MONO-MEG', nEncoderCount:=25420841, ); fbGHSetup(stPositionState:=astGratingStates[E_Grating_States.HEG], sName:='HEG', sPmpsState:='SP1K1:MONO-HEG', nEncoderCount:=42600635, ); fbGHSetup(stPositionState:=astGratingStates[E_Grating_States.LEG], sName:='LEG', sPmpsState:='SP1K1:MONO-LEG', nEncoderCount:=59802448, ); fbGratingStates( stMotionStage:=Main.M9, astPositionState:=astGratingStates, eEnumSet:=eStateSet, eEnumGet:=eStateGet, fbFFHWO:=GVL_PMPS.fbFastFaultOutput1, fbArbiter:=GVL_PMPS.fbArbiter1, bEnableMotion:=TRUE, bEnableBeamParams:=TRUE, sDeviceName:='SP1K1:MONO', sTransitionKey:='SP1K1:MONO-TRANSITION' ); END_PROGRAM Related: * `E_Grating_States`_ * `GVL_PMPS`_ * `Main`_ PRG_SPO_PMPS ^^^^^^^^^^^^ :: PROGRAM PRG_SPO_PMPS VAR // PMPS ffMR1K1Height : FB_FastFault := ( i_xAutoReset := TRUE, i_DevName := 'MR1K1 Height', i_Desc := 'MR1K1 Height is out of Single Point Operation safe range', i_TypeCode := 16#F501); ffMR1K1Pitch : FB_FastFault := ( i_xAutoReset := TRUE, i_DevName := 'MR1K1 Pitch', i_Desc := 'MR1K1 Pitch is out of Single Point Operation safe range', i_TypeCode := 16#F502); ffSP1K1MPitch : FB_FastFault := ( i_xAutoReset := TRUE, i_DevName := 'SP1K1 Mirror Pitch', i_Desc := 'SP1K1 Mirror Pitch is out of Single Point Operation safe range', i_TypeCode := 16#F503); ffSP1K1GPitch : FB_FastFault := ( i_xAutoReset := TRUE, i_DevName := 'SP1K1 Grating Pitch', i_Desc := 'SP1K1 Grating Pitch is out of Single Point Operation safe range', i_TypeCode := 16#F504); ffSP1K1GHorisontal : FB_FastFault := ( i_xAutoReset := TRUE, i_DevName := 'SP1K1 Grating horizontal', i_Desc := 'SP1K1 horizontal Pitch is out of Single Point Operation safe range', i_TypeCode := 16#F505); ffZos : FB_FastFault := ( i_xAutoReset := TRUE, i_DevName := 'T1K1 ZOS', i_Desc := 'ST1K1 ZOS is out of Single Point Operation safe range', i_TypeCode := 16#F506); END_VAR VAR CONSTANT nUpperMR1K1Height : UDINT := 32961458; //POS 32911458+ Delta 50000; nLowerMR1K1Height : UDINT := 32861458; //POS 32911458- Delta 50000; nUpperMR1K1Pitch : UDINT := 10114377;// 10093885 + 20491; nLowerMR1K1Pitch : UDINT := 10073393; //10093885 - 20491; nUpperSP1K1MPitch : UDINT := 31769145;// 31758046 + 11098; nLowerSP1K1MPitch : UDINT := 31746947;//31758046 - 11098; nUpperSP1K1MPitch_400 : UDINT := 31285238; nLowerSP1K1MPitch_400 : UDINT := 31263041; nUpperSP1K1MPitch_1000 : UDINT := 31809544; nLowerSP1K1MPitch_1000 : UDINT := 31787347; nUpperSP1K1GPitch_700 : UDINT := 23624881; nUpperSP1K1GPitch_400 : UDINT := 23204883; nUpperSP1K1GPitch_1000 : UDINT := 23564882; nUpperSP1K1GH: UDINT := 40000000; nLowerSP1K1GH: UDINT := 24000000; nZOSLower : UDINT := 22926596; // value still needs to be verified END_VAR IF (GVL_PMPS.rPhotonEnergy < 715) AND (GVL_PMPS.rPhotonEnergy >685) THEN ffSP1K1MPitch.i_xOK := PRG_MR1K1_BEND_BENDER.ffBenderRange.i_xOK OR ((M6.nEncoderCount > nLowerSP1K1MPitch) AND (M6.nEncoderCount < nUpperSP1K1MPitch)); ffSP1K1GPitch.i_xOK := PRG_MR1K1_BEND_BENDER.ffBenderRange.i_xOK OR ((M7.nEncoderCount < nUpperSP1K1GPitch_700)); ELSIF (GVL_PMPS.rPhotonEnergy < 410) AND (GVL_PMPS.rPhotonEnergy >390) THEN ffSP1K1MPitch.i_xOK := PRG_MR1K1_BEND_BENDER.ffBenderRange.i_xOK OR ((M6.nEncoderCount > nLowerSP1K1MPitch_400) AND (M6.nEncoderCount < nUpperSP1K1MPitch_400)); ffSP1K1GPitch.i_xOK := PRG_MR1K1_BEND_BENDER.ffBenderRange.i_xOK OR ((M7.nEncoderCount < nUpperSP1K1GPitch_400)); ELSIF (GVL_PMPS.rPhotonEnergy < 1020) AND (GVL_PMPS.rPhotonEnergy >980) THEN ffSP1K1MPitch.i_xOK := PRG_MR1K1_BEND_BENDER.ffBenderRange.i_xOK OR ((M6.nEncoderCount > nLowerSP1K1MPitch_1000) AND (M6.nEncoderCount < nUpperSP1K1MPitch_1000)); ffSP1K1GPitch.i_xOK := PRG_MR1K1_BEND_BENDER.ffBenderRange.i_xOK OR ((M7.nEncoderCount < nUpperSP1K1GPitch_1000)); ELSE ffSP1K1MPitch.i_xOK := PRG_MR1K1_BEND_BENDER.ffBenderRange.i_xOK; ffSP1K1GPitch.i_xOK := PRG_MR1K1_BEND_BENDER.ffBenderRange.i_xOK; END_IF //MR1K1 height ffMR1K1Height.i_xOK := PRG_MR1K1_BEND_BENDER.ffBenderRange.i_xOK OR ((M12.nEncoderCount > nLowerMR1K1Height ) AND (M12.nEncoderCount < nUpperMR1K1Height )); ffMR1K1Height(io_fbFFHWO := GVL_PMPS.fbFastFaultOutput1); //MR1K1 pitch ffMR1K1Pitch.i_xOK := PRG_MR1K1_BEND_BENDER.ffBenderRange.i_xOK OR ( (M16.nEncoderCount > nLowerMR1K1Pitch) AND ( M16.nEncoderCount < nUpperMR1K1Pitch)); ffMR1K1Pitch(io_fbFFHWO := GVL_PMPS.fbFastFaultOutput1); //SP1K1 mirror pitch ffSP1K1MPitch(io_fbFFHWO := GVL_PMPS.fbFastFaultOutput1); //SP1K1 grating pitch ffSP1K1GPitch(io_fbFFHWO := GVL_PMPS.fbFastFaultOutput1); //SP1K1 Grating horizontal ffSP1K1GHorisontal.i_xOK := PRG_MR1K1_BEND_BENDER.ffBenderRange.i_xOK OR ((M9.nEncoderCount > nLowerSP1K1GH) AND (M9.nEncoderCount < nUpperSP1K1GH)); ffSP1K1GHorisontal(io_fbFFHWO := GVL_PMPS.fbFastFaultOutput1); //ST1K1 ZOS ffZos.i_xOK := PRG_MR1K1_BEND_BENDER.ffBenderRange.i_xOK OR (M24.nEncoderCount <= nZOSLower); //encoder counts decreases as value in mm increases ffZos(io_fbFFHWO := GVL_PMPS.fbFastFaultOutput1); END_PROGRAM Related: * `GVL_PMPS`_ * `PRG_MR1K1_BEND_BENDER`_ PRG_ST1K1_ZOS ^^^^^^^^^^^^^ :: PROGRAM PRG_ST1K1_ZOS VAR fbZOS: FB_MotionStage; END_VAR Main.M24.bPowerSelf := TRUE; Main.M24.bHardwareEnable := TRUE; fbZOS(stMotionStage:=Main.M24); END_PROGRAM Related: * `Main`_ PRG_Stats ^^^^^^^^^ :: PROGRAM PRG_Stats VAR // SP1K1 Grating Mono Vibration Stats fGpiEncoderPosDiff: LREAL; afGpiPosDiffBuffer: ARRAY[1..1000] OF LREAL; afGpiExtraBuffer: ARRAY[1..1000] OF LREAL; fbGpiPosDiffCollect: FB_DataBuffer; {attribute 'pytmc' := ' pv: SP1K1:MONO:MMS:G_PI:ENCDIFF '} fbGpiPosDiffStats: FB_BasicStats; fGpiRangeMax: LREAL; rtNewGpiMove: R_TRIG; tonNewGpiMove: TON; // SP1K1 Mirror Pitch Mono Vibration Stats fMpiEncoderPosDiff: LREAL; afMpiPosDiffBuffer: ARRAY[1..1000] OF LREAL; afMpiExtraBuffer: ARRAY[1..1000] OF LREAL; fbMpiPosDiffCollect: FB_DataBuffer; {attribute 'pytmc' := ' pv: SP1K1:MONO:MMS:M_PI:ENCDIFF '} fbMpiPosDiffStats: FB_BasicStats; // MR1K1 Pitch Vibration Stats fMR1K1PiEncoderPosDiff: LREAL; afMR1K1PiPosDiffBuffer: ARRAY[1..1000] OF LREAL; afMR1K1PiExtraBuffer: ARRAY[1..1000] OF LREAL; fbMR1K1PiPosDiffCollect: FB_DataBuffer; {attribute 'pytmc' := ' pv: MR1K1:BEND:MMS:PITCH:ENCDIFF '} fbMR1K1PiPosDiffStats: FB_BasicStats; END_VAR IF rtNewGpiMove.Q THEN // Reset before a move fGpiRangeMax := 0; ELSIF tonNewGpiMove.Q AND ABS(M7.fPosition - M7.stAxisStatus.fActPosition) > 5 THEN // Update only during moves, not at the start or end fGpiRangeMax := MAX(fGpiRangeMax, fbGpiPosDiffStats.fRange); END_IF fGpiEncoderPosDiff := ((UDINT_TO_LREAL(M7.nEncoderCount) / 150.0) - (M7.Axis.NcToPlc.SetPos - M7.stAxisParameters.fEncOffset)) * 1000; fbGpiPosDiffCollect( bExecute:=TRUE, pInputAdr:=ADR(fGpiEncoderPosDiff), iInputSize:=SIZEOF(fGpiEncoderPosDiff), iElemCount:=1000, pPartialAdr:=ADR(afGpiPosDiffBuffer), pOutputAdr:=ADR(afGpiExtraBuffer), ); fbGpiPosDiffStats( aSignal:=afGpiPosDiffBuffer, bAlwaysCalc:=TRUE, ); rtNewGpiMove(CLK:=M7.bExecute); tonNewGpiMove( IN:=M7.bExecute, PT:=T#15s, ); fMpiEncoderPosDiff := ((UDINT_TO_LREAL(M6.nEncoderCount) * 0.004505) - (M6.Axis.NcToPlc.SetPos - M6.stAxisParameters.fEncOffset)) * 1000; fbMpiPosDiffCollect( bExecute:=TRUE, pInputAdr:=ADR(fMpiEncoderPosDiff), iInputSize:=SIZEOF(fMpiEncoderPosDiff), iElemCount:=1000, pPartialAdr:=ADR(afMpiPosDiffBuffer), pOutputAdr:=ADR(afMpiExtraBuffer), ); fbMpiPosDiffStats( aSignal:=afMpiPosDiffBuffer, bAlwaysCalc:=TRUE, ); fMR1K1PiEncoderPosDiff := ((UDINT_TO_LREAL(M16.nEncoderCount) * 0.00244) - (M16.Axis.NcToPlc.SetPos - M16.stAxisParameters.fEncOffset)) * 1000; fbMR1K1PiPosDiffCollect( bExecute:=TRUE, pInputAdr:=ADR(fMR1K1PiEncoderPosDiff), iInputSize:=SIZEOF(fMR1K1PiEncoderPosDiff), iElemCount:=1000, pPartialAdr:=ADR(afMR1K1PiPosDiffBuffer), pOutputAdr:=ADR(afMR1K1PiExtraBuffer), ); fbMR1K1PiPosDiffStats( aSignal:=afMR1K1PiPosDiffBuffer, bAlwaysCalc:=TRUE, ); END_PROGRAM PRG_ZeroOrder_PMPS ^^^^^^^^^^^^^^^^^^ :: PROGRAM PRG_ZeroOrder_PMPS VAR // PMPS ffZeroOrderBeam : FB_FastFault := ( i_xAutoReset := TRUE, i_DevName := 'Zero Order Beam', i_Desc := 'Faults when Zero order beam safe conditions are not met', i_TypeCode := 16#F506); {attribute 'pytmc' := ' pv: @(PREFIX)SafeBenderRange field: ZNAM FALSE field: ONAM TRUE '} bSafeBenderRange : BOOL; {attribute 'pytmc' := ' pv: @(PREFIX)LRG_Grating_IN field: ZNAM FALSE field: ONAM TRUE '} bLRG_Grating_IN : BOOL; {attribute 'pytmc' := ' pv: @(PREFIX)MEG_Grating_IN field: ZNAM FALSE field: ONAM TRUE '} bMEG_Grating_IN : BOOL; {attribute 'pytmc' := ' pv: @(PREFIX)HEG_Grating_IN field: ZNAM FALSE field: ONAM TRUE '} bHEG_Grating_IN : BOOL; {attribute 'pytmc' := ' pv: @(PREFIX)LEG_Grating_IN field: ZNAM FALSE field: ONAM TRUE '} bLEG_Grating_IN : BOOL; {attribute 'pytmc' := ' pv: @(PREFIX)ZOS_IN field: ZNAM FALSE field: ONAM TRUE '} bZOS_IN : BOOL; {attribute 'pytmc' := ' pv: @(PREFIX)ZOB_on_Lower_Stopper field: ZNAM FALSE field: ONAM TRUE '} bZOB_on_Lower_Stopper : BOOL; {attribute 'pytmc' := ' pv: @(PREFIX)MR1K1_Inserted field: ZNAM FALSE field: ONAM TRUE '} bMR1K1_Inserted : BOOL; {attribute 'pytmc' := ' pv: @(PREFIX)MachineMode field: ZRST NC field: ONST SC field: TWST Misconfig field: THST UnInit '} nMachineMode : INT; {attribute 'pytmc' := ' pv: @(PREFIX)BeamPermitted field: ZNAM FALSE field: ONAM TRUE '} bBeamPermitted : BOOL; Pm3 : LREAL; Pm2: LREAL; Pm1: LREAL; Hm1: LREAL; HZos:LREAL; Zbm1: LREAL; Zbm2: LREAL; Zbm3: LREAL; Hbm1: LREAL; Hbm2: LREAL; Hbm3: LREAL; Hb0m3:LREAL; //fixed calc Hm3 : LREAL; Hpiv : LREAL; Theta_m1: LREAL; Theta_m2: LREAL; Theta_m3: LREAL; {attribute 'pytmc' := ' pv: @(PREFIX)Delta '} Delta : LREAL; {attribute 'pytmc' := ' pv: @(PREFIX)ZOEQ '} Ans : LREAL; ffZeroOrderBeamExitSlits : FB_FastFault := ( i_xAutoReset := TRUE, i_DevName := 'Zero Order Beam and Exit Slits', i_Desc := 'Faults when Zero order beam is aligned and exit slits are closed', i_TypeCode := 16#F506); mm: INT; eV: INT; END_VAR VAR CONSTANT Hi2 :LREAL:=1.4;//m Zi2: LREAL :=731.613;//m Theta0 : LREAL:=0; Zm1 : LREAL:=733.772;//m Zmon : LREAL:=739.622;//m Zpiv : LREAL:= 739.762 ; //m Zzos : LREAL:= 741.422;//m Pm1Offset: LREAL:= 18081.1; Pm2Offset: LREAL:= -90603; Pm3Offset: LREAL:= -63300;//urad, could depend on the inserted grating END_VAR //Diagnostics bSafeBenderRange := SafeBenderRange(); nMachineMode := PMPS_GVL.stCurrentBeamParameters.nMachineMode; bMR1K1_Inserted := MR1K1_Inserted(); ACT_Grating_IN(); ACT_CALC(); ACT_ZOS_IN(); ACT_ExitSlitsGap(); //Is the ZO beam on the stopper? TRUE if Hzos - hb0m3(Zzoz) > Δ (* Δ=2.0 mm for LRG @ >1000 eV Δ=2.5 mm for LRG @ <1000 eV Δ=3.0 mm for LRG @ <550 eV Δ=6.0 mm for LEG, MEG, HEG *) Ans := (Hzos*1E3) - Hb0m3; //um IF bLRG_Grating_IN AND GVL_PMPS.rPhotonEnergy <550 THEN Delta := 3*1E3(*um*); ELSIF bLRG_Grating_IN AND GVL_PMPS.rPhotonEnergy <1000 THEN Delta := 2.5*1E3(*um*); ELSIF bLRG_Grating_IN AND GVL_PMPS.rPhotonEnergy >=1000 THEN Delta := 2*1E3(*um*); ELSIF (bMEG_Grating_IN OR bHEG_Grating_IN OR bLEG_Grating_IN) THEN Delta := 6*1E3(*um*); ELSE Delta := Ans; END_IF bZOB_on_Lower_Stopper := Ans > Delta; ffZeroOrderBeam.i_xOK := (SafeBenderRange() AND (((PMPS_GVL.stCurrentBeamParameters.nMachineMode =1(*SC*)) AND (PMPS_GVL.stCurrentBeamParameters.nBeamClass <=6)) OR (PMPS_GVL.stCurrentBeamParameters.nMachineMode =0(*NC*)))) OR (bLRG_Grating_IN AND bZOS_IN AND bZOB_on_Lower_Stopper AND MR1K1_Inserted()(*NC or SC Any Beamclass with beam at ZOS*)) OR ((bMEG_Grating_IN OR bHEG_Grating_IN OR bLEG_Grating_IN) AND bZOS_IN AND bZOB_on_Lower_Stopper AND MR1K1_Inserted()(*NC or SC Any Beamclass with beam at ZOS*)); ffZeroOrderBeam(io_fbFFHWO := GVL_PMPS.fbFastFaultOutput1); bBeamPermitted := ffZeroOrderBeam.i_xOK; // END_PROGRAM ACTION ACT_CALC: ///calc //Hm1 = 1400000+mr1k1 ben Y up Hm1:= 1400000+M12.stAxisStatus.fActPosition; //um //Pm1 = Pm1Offset + mr1k1 bend pitch Pm1 := Pm1Offset + Main.M16.stAxisStatus.fActPosition; //urad //Hpiv = 1.625427 is correction from nominal Hpiv:= (1.625247)*1E6; //um //Pm2 = mono mirror pitch + Pm2Offset urad Pm2 := Main.M6.stAxisStatus.fActPosition + Pm2Offset;//urad //Hm3 = Hpiv + 0.006 m Hm3:= Hpiv + (0.006*1E6); //um //Pm3 = mono grating pitch + Pm3Offset urad Pm3 := Main.M7.stAxisStatus.fActPosition + Pm3Offset; //urad //Hzos = 1824.3 + st1k1_zos mm Hzos:= 1824.3 + M24.stAxisStatus.fActPosition; //mm //urad Theta_m1 := 2*Pm1 - Theta0; Theta_m2 := 2*Pm2 - Theta_m1; Theta_m3 := 2 *Pm3 - 2 * Pm2 + 2* Pm1 - Theta0; // fix units //um Zbm1 := (Hm1 - TAN(Pm1*1E-6)* (Zm1*1E6) - (Hi2*1E6) + TAN(Theta0*1E-6) *(Zi2*1E6))/(TAN(Theta0*1E-6) - TAN(Pm1*1E-6)); hbm1 := TAN(Pm1*1E-6)*Zbm1 + Hm1 - TAN(Pm1*1E-6)*(Zm1*1E6); //u? Zbm2 := (Hbm1 - TAN(Theta_m1*1E-6)*Zbm1 - Hpiv + TAN(Pm2*1E-6)*(Zpiv*1E6))/ (TAN(Pm2*1E-6) - TAN(Theta_m1*1E-6)); Hbm2 := TAN(Pm2*1E-6)*Zbm2 + Hpiv - TAN(Pm2*1E-6)*(Zpiv*1E6); Zbm3 := (Hbm2 - TAN(Theta_m2*1E-6)*Zbm2 - Hm3 + TAN(Pm3*1E-6)*(Zpiv*1E6))/ (TAN(Pm3*1E-6) - TAN(Theta_m2*1E-6)); Hbm3 := TAN(Pm3*1E-6) * Zbm3 + Hm3 - TAN(Pm3*1E-6)*(Zpiv*1E6); Hb0m3 := TAN(Theta_m3*1E-6)*(Zzos*1E6) + Hbm3 - TAN(Theta_m3*1E-6)*Zbm3; END_ACTION ACTION ACT_ExitSlitsGap: // FAULT condition: Hzos -1.0mm <= Hb0m3) AND sl1k2 gap <= 8.0 mm ffZeroOrderBeamExitSlits.i_xOK := NOT( (( (Hzos*1E3) - 1) <= Hb0m3) AND ( M22.stAxisStatus.fActPosition <= 8000(*um*))); ffZeroOrderBeamExitSlits(io_fbFFHWO := GVL_PMPS.fbFastFaultOutput1); END_ACTION ACTION ACT_Grating_IN: bLRG_Grating_IN := PRG_SP1K1_MONO.eStateGet = E_Grating_States.LRG; bMEG_Grating_IN := PRG_SP1K1_MONO.eStateGet = E_Grating_States.MEG; bHEG_Grating_IN := PRG_SP1K1_MONO.eStateGet = E_Grating_States.HEG; bLEG_Grating_IN := PRG_SP1K1_MONO.eStateGet = E_Grating_States.LEG; END_ACTION ACTION ACT_ZOS_IN: IF GVL_PMPS.rPhotonEnergy >1500 THEN bZOS_IN:= FALSE; ELSIF (GVL_PMPS.rPhotonEnergy >1000 AND M24.stAxisStatus.fActPosition>= 8.5) THEN bZOS_IN:= TRUE; ELSIF (GVL_PMPS.rPhotonEnergy <=1000 AND GVL_PMPS.rPhotonEnergy >550 AND M24.stAxisStatus.fActPosition>= 7.9) THEN bZOS_IN:= TRUE; ELSIF (GVL_PMPS.rPhotonEnergy <=550 AND GVL_PMPS.rPhotonEnergy >200 AND M24.stAxisStatus.fActPosition>= 6.9) THEN bZOS_IN:= TRUE; ELSE bZOS_IN:= FALSE; END_IF END_ACTION METHOD MR1K1_Inserted : BOOL VAR_INPUT END_VAR MR1K1_Inserted := PMPS_GVL.stCurrentBeamParameters.aVetoDevices[PMPS.K_Stopper.MR1K1_IN] AND NOT PMPS_GVL.stCurrentBeamParameters.aVetoDevices[PMPS.K_Stopper.MR1K1_OUT]; END_METHOD METHOD SafeBenderRange : BOOL VAR_INPUT END_VAR SafeBenderRange := GVL_M1K1_BENDER_Constants.nM1K1bendUS_PMPS_LowerLimit < M17.nEncoderCount AND M17.nEncoderCount < GVL_M1K1_BENDER_Constants.nM1K1bendUS_PMPS_UpperLimit AND GVL_M1K1_BENDER_Constants.nM1K1bendDS_PMPS_LowerLimit < M18.nEncoderCount AND M18.nEncoderCount < GVL_M1K1_BENDER_Constants.nM1K1bendDS_PMPS_UpperLimit; END_METHOD Related: * `E_Grating_States`_ * `GVL_M1K1_BENDER_Constants`_ * `GVL_PMPS`_ * `Main`_ * `PRG_SP1K1_MONO`_