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_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
Global_Version
{attribute 'TcGenerated'}
{attribute 'no-analysis'}
{attribute 'linkalways'}
// This function has been automatically generated from the project information.
VAR_GLOBAL CONSTANT
{attribute 'const_non_replaced'}
stLibVersion_rix_optics : ST_LibVersion := (iMajor := 3, iMinor := 7, iBuild := 0, iRevision := 0, nFlags := 1, sVersion := '3.7.0');
END_VAR
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:
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:
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:
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:
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:
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:
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
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:
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
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;
{attribute 'pytmc' := '
pv: MR1K1:BEND:ENC:PITCH
'}
fbPitchRMSErrorM1K1 : FB_RMSWatch;
fMaxPitchRMSErrorM1K1 : LREAL;
fMinPitchRMSErrorM1K1 : 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);
fbPitchRMSErrorM1K1(stMotionStage:=M16,
fMaxRMSError=>fMaxPitchRMSErrorM1K1,
fMinRMSError=>fMinPitchRMSErrorM1K1);
(*
// 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
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
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
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:
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:
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:
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:1'}
{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:
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:
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:
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:
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..10000] OF LREAL;
afMpiExtraBuffer: ARRAY[1..10000] OF LREAL;
fbMpiPosDiffCollect: FB_DataBuffer;
{attribute 'pytmc' := '
pv: SP1K1:MONO:MMS:M_PI:ENCDIFF
'}
fbMpiPosDiffStats: 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 := M7.nEncoderCount - (M7.Axis.NcToPlc.SetPos - M7.stAxisParameters.fEncOffset) * 150;
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 := M6.nEncoderCount - (M6.Axis.NcToPlc.SetPos - M6.stAxisParameters.fEncOffset) / 0.004505;
fbMpiPosDiffCollect(
bExecute:=TRUE,
pInputAdr:=ADR(fMpiEncoderPosDiff),
iInputSize:=SIZEOF(fMpiEncoderPosDiff),
iElemCount:=1000,
pPartialAdr:=ADR(afMpiPosDiffBuffer),
pOutputAdr:=ADR(afMpiExtraBuffer),
);
fbMpiPosDiffStats(
aSignal:=afMpiPosDiffBuffer,
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)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
field: ZNAM FALSE
field: ONAM TRUE
'}
Delta : LREAL;
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);
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();
//TRUE if Hzos - hb0m3(Zzoz) > D
Ans := (Hzos*1E3) - Hb0m3; //um
Delta := Ans;
IF GVL_PMPS.rPhotonEnergy <550 THEN
bZOB_on_Lower_Stopper := Ans > 3*1E3;
ELSIF GVL_PMPS.rPhotonEnergy <1000 THEN
bZOB_on_Lower_Stopper := Ans > 2.5*1E3;
ELSIF GVL_PMPS.rPhotonEnergy >=1000 THEN
bZOB_on_Lower_Stopper := Ans > 2*1E3;
END_IF
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*));
ffZeroOrderBeam(io_fbFFHWO := GVL_PMPS.fbFastFaultOutput1);
bBeamPermitted := ffZeroOrderBeam.i_xOK;
//
ACT_CALC();
ACT_ZOS_IN();
ACT_LRG_Grating_IN();
ACT_ExitSlitsGap();
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_LRG_Grating_IN:
bLRG_Grating_IN := ((M9.stAxisStatus.fActPosition) >= 36000) AND ((M9.stAxisStatus.fActPosition) <= 43000);
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: