测试共有13个轴,前10个轴包含基本功能,后3个轴包含独有功能。
方法一
定义每个轴的基本功能,包括上电、下电、走相对、走绝对、读位置、读状态、复位、停止等。
在Axis_Base_PTP中定义变量:
1 FUNCTION_BLOCK Axis_Base_PTP
2
3 VAR
4 REF: AXIS_REF;
5 mcMoveRela: MC_MoveRelative;
6 mcPower: MC_Power;
7 mcStop: MC_Stop;
8 mcMoveAbs: MC_MoveAbsolute;
9 mcReset: MC_Reset;
10 mcReadPosition: MC_ReadActualPosition;
11 mcReadStatus: MC_ReadStatus;
12 mcHalt: MC_Halt;
13
14 AxisPara:ST_AxisPara;
15 END_VAR
M_PowerOn方法代码:
1 METHOD M_PowerOn : BOOL
2 VAR_INPUT
3 bExcute : BOOL;
4 END_VAR
5
6 VAR_OUTPUT
7 bStatus : BOOL; (* B *)
8 bBusy : BOOL; (* V *)
9 bActive : BOOL; (* V *)
10 bError : BOOL; (* B *)
11 dErrorID : UDINT; (* E *)
12 END_VAR
1 IF bExcute THEN
2 mcPower(
3 Axis:= REF,
4 Enable:= TRUE,
5 Enable_Positive:= TRUE,
6 Enable_Negative:= TRUE,
7 Override:= AxisPara.rOverride,
8 BufferMode:= ,
9 Options:= ,
10 Status=> bStatus,
11 Busy=> bBusy,
12 Active=> bActive,
13 Error=> bError,
14 ErrorID=> dErrorID);
15 END_IF
M_MoveRela方法代码:
1 METHOD M_MoveRela : BOOL
2 VAR_INPUT
3 bLimit_1 : BOOL;
4 bLimit_2 : BOOL;
5 rDistance : REAL;
6 rVelocity : REAL;
7 bExcute : BOOL;
8 END_VAR
9
10 VAR_OUTPUT
11 bDone : BOOL; (* B *)
12 bBusy : BOOL; (* V *)
13 bActive : BOOL; (* V *)
14 bError : BOOL; (* B *)
15 dErrorID : UDINT; (* E *)
16 END_VAR
1 IF rDistance>0 THEN
2 mcHalt(
3 Axis:= REF,
4 Execute:= bLimit_1,
5 Deceleration:= AxisPara.Deceleration,
6 Jerk:= ,
7 BufferMode:= ,
8 Options:= ,
9 Done=> ,
10 Busy=> ,
11 Active=> ,
12 CommandAborted=> ,
13 Error=> ,
14 ErrorID=> );
15 IF NOT bLimit_1 THEN
16 mcMoveRela(
17 Axis:= REF,
18 Execute:= bExcute,
19 Distance:= rDistance,
20 Velocity:= rVelocity,
21 Acceleration:= AxisPara.Acceleration,
22 Deceleration:= AxisPara.Deceleration,
23 Jerk:= ,
24 BufferMode:= ,
25 Options:= ,
26 Done=> bDone,
27 Busy=> bBusy,
28 Active=> bActive,
29 CommandAborted=> ,
30 Error=> bError,
31 ErrorID=> dErrorID);
32 END_IF
33
34 ELSIF rDistance<0 THEN
35 mcHalt(
36 Axis:= REF,
37 Execute:= bLimit_2,
38 Deceleration:= AxisPara.Deceleration,
39 Jerk:= ,
40 BufferMode:= ,
41 Options:= ,
42 Done=> ,
43 Busy=> ,
44 Active=> ,
45 CommandAborted=> ,
46 Error=> ,
47 ErrorID=> );
48 IF NOT bLimit_2 THEN
49 mcMoveRela(
50 Axis:= REF,
51 Execute:= bExcute,
52 Distance:= rDistance,
53 Velocity:= rVelocity,
54 Acceleration:= AxisPara.Acceleration,
55 Deceleration:= AxisPara.Deceleration,
56 Jerk:= ,
57 BufferMode:= ,
58 Options:= ,
59 Done=> bDone,
60 Busy=> bBusy,
61 Active=> bActive,
62 CommandAborted=> ,
63 Error=> bError,
64 ErrorID=> dErrorID);
65 END_IF
66 END_IF
对于附加功能的轴11,继承Axis_Base_PTP,独有的方法M_TurnInOut另外添加。
Axis_Base_PTP继承自基类并定义变量:
1 FUNCTION_BLOCK Axis11_PTP EXTENDS Axis_Base_PTP
2 VAR_INPUT
3 END_VAR
4
5 VAR_OUTPUT
6 bMagnet_1 AT%Q* : BOOL;
7 bMagnet_2 AT%Q* : BOOL;
8 END_VAR
9
10 VAR
11 bIn : BOOL :=FALSE;
12 bOut: BOOL :=FALSE;
13
14 TON_0: TON;
15 TON_1: TON;
16
17 bTemp1: BOOL;
18 bTemp2: BOOL;
19
20 MC_MoveRelative_0: MC_MoveRelative;
21 mcHaltChange_0: MC_Halt;
22
23 END_VAR
M_TurnInOut方法代码:
1 METHOD M_TurnInOut : BOOL
2 VAR_INPUT
3 bTurnIn : BOOL;
4 bTurnOut : BOOL;
5 bLimit1 : BOOL;
6 END_VAR
7
8 VAR_OUTPUT
9 END_VAR
轴12、13等同理,省略。
在Main函数中定义变量:
1 //定义接口及继承关系
2 Axis : ARRAY[1..10] OF Axis_Base_PTP;
3 Axis11 : Axis11_PTP;
4 Axis12 : Axis12_PTP;
5 Axis13 : Axis13_PTP;
6
7 //选择电机轴号
8 iAxisNum AT%I* : UINT;(*电机轴号*)
9
10 //定义电机运行相对距离参数
11 rDistance AT%I* : REAL;(*运动距离*)
12 rVelocity AT%I* : REAL;(*运动速度*)
13
14 //定义结构体
15 AxisPara:ST_AxisPara;(*轴参数结构体*)
16 AxisStatus:ST_AxisStatus;(*轴状态结构体*)
17 PoweronStatus:ST_PoweronStatus; (*上电模块结构体*)
18 PoweroffStatus:ST_PoweroffStatus;(*下电模块结构体*)
19 MoveAbsStatus:ST_MoveAbsStatus; (*绝对运动模式结构体*)
20 MoveRelaStatus:ST_MoveRelaStatus;(*相对运动模式结构体*)
21 StopStatus:ST_StopStatus;(*停止模块结构体*)
22 ResetStatus:ST_ResetStatus;(*复位模块结构体*)
23 ReadPosStatus:ST_ReadPosStatus;(*读取轴位置结构体*)
24 HomeStatus:ST_HomeStatus;(*寻参模块结构体*)
25 LimitStatus:ST_LimitStatus;(*限位开关状态*)
26
27 //定义指令
28 bComPowerOn AT%I* : BOOL;(*上电命令*)
29 bComPowerOff AT%I* : BOOL;(*下电命令*)
30 bComMoveRela AT%I* : BOOL;(*相对位置指令*)
31 bComStop AT%I* : BOOL;(*停止指令*)
32 bComMoveAbs AT%I* : BOOL;(*绝对位置指令*)
33 bComRest AT%I* : BOOL;(*复位指令*)
34 bComReadPos AT%I* : BOOL;(*读取当前位置指令*)
35 bComReadStatus AT%I* : BOOL;(*读取电机状态指令*)
36 bHome AT%I* : BOOL;(*电机13寻参指令*)
37 bGlassForward AT%I* : BOOL;(*电机12更换保护玻璃前进*)
38 bGlassBack AT%I* : BOOL;(*电机12更换保护玻璃后退*)
39 bTurnIn AT%I* : BOOL;(*电机11转入*)
40 bTurnOut AT%I* : BOOL;(*电机11转出*)
1 CASE iAxisNum OF
2 1:
3 Axis[1].M_PowerOn(bExcute:=bComPowerOn,bStatus=>PoweronStatus.bStatus,bBusy=>PoweronStatus.bBusy,bActive=>PoweronStatus.bActive,bError=>PoweronStatus.bErr,dErrorID=>PoweronStatus.dErrID);
4 Axis[1].M_PowerOff(bExcute:=bComPowerOff,bStatus=>PoweroffStatus.bStatus,bBusy=>PoweroffStatus.bBusy,bActive=>PoweroffStatus.bActive,bError=>PoweroffStatus.bErr,dErrorID=>PoweroffStatus.dErrID);
5 Axis[1].M_MoveAbs(bLimit_1:=LimitStatus.Axis_1_Limit_1,bLimit_2:=LimitStatus.Axis_1_Limit_2,rDistance:=rDistance,rVelocity:=rVelocity,bExcute:=bComMoveAbs,bDone=>MoveAbsStatus.bDone,bBusy=>MoveAbsStatus.bBusy,bActive=>MoveAbsStatus.bActive,bError=>MoveAbsStatus.bErr,dErrorID=>MoveAbsStatus.dErrID);
6 Axis[1].M_MoveRela(bLimit_1:=LimitStatus.Axis_1_Limit_1,bLimit_2:=LimitStatus.Axis_1_Limit_2,rDistance:=rDistance,rVelocity:=rVelocity,bExcute:=bComMoveRela,bDone=>MoveRelaStatus.bDone,bBusy=>MoveRelaStatus.bBusy,bActive=>MoveRelaStatus.bActive,bError=>MoveRelaStatus.bErr,dErrorID=>MoveRelaStatus.dErrID);
7 Axis[1].M_Stop(bExcute:=bComStop,bDone=>StopStatus.bDone,bBusy=>StopStatus.bBusy,bActive=>StopStatus.bActive,bError=>StopStatus.bErr,dErrorID=>StopStatus.dErrID);
8 Axis[1].M_Reset(bExcute:=bComRest,bDone=>ResetStatus.bDone,bBusy=>ResetStatus.bBusy,bError=>ResetStatus.bErr,dErrorID=>ResetStatus.dErrID);
9 Axis[1].M_ReadPosition(bExcute:=bComReadPos,bValid=>ReadPosStatus.bValid,bBusy=>ReadPosStatus.bBusy,bError=>ReadPosStatus.bErr,dErrorID=>ReadPosStatus.dErrID,lPosition=>ReadPosStatus.lPosition);
10 Axis[1].M_ReadStatus(bExcute:=bComReadStatus,bValid=>AxisStatus.Axis_Valid,bBusy=>AxisStatus.Axis_Busy,bError=>AxisStatus.Axis_Err,dErrorID=>AxisStatus.Axis_ErrID,bErrorStop=>AxisStatus.Axis_ErrorStop,bDisabled=>AxisStatus.Axis_Disabled,bStopping=>AxisStatus.Axis_Stopping,bStandStill=>AxisStatus.Axis_StandStill,bDiscreteMotion=>AxisStatus.Axis_DiscreteMotion,bContinuousMotion=>AxisStatus.Axis_ContinuousMotion,bSynchronizedMotion=>AxisStatus.Axis_SynchronizedMotion,bHoming=>AxisStatus.Axis_Homing,bConstantVelocity=>AxisStatus.Axis_ConstantVelocity,bAccelerating=>AxisStatus.Axis_Accelerating,bDecelerating=>AxisStatus.Axis_Decelerating);
11 2:
12 Axis[2].M_PowerOn(bExcute:=bComPowerOn,bStatus=>PoweronStatus.bStatus,bBusy=>PoweronStatus.bBusy,bActive=>PoweronStatus.bActive,bError=>PoweronStatus.bErr,dErrorID=>PoweronStatus.dErrID);
13 Axis[2].M_PowerOff(bExcute:=bComPowerOff,bStatus=>PoweroffStatus.bStatus,bBusy=>PoweroffStatus.bBusy,bActive=>PoweroffStatus.bActive,bError=>PoweroffStatus.bErr,dErrorID=>PoweroffStatus.dErrID);
14 Axis[2].M_MoveAbs(bLimit_1:=LimitStatus.Axis_2_Limit_1,bLimit_2:=LimitStatus.Axis_2_Limit_2,rDistance:=rDistance,rVelocity:=rVelocity,bExcute:=bComMoveAbs,bDone=>MoveAbsStatus.bDone,bBusy=>MoveAbsStatus.bBusy,bActive=>MoveAbsStatus.bActive,bError=>MoveAbsStatus.bErr,dErrorID=>MoveAbsStatus.dErrID);
15 Axis[2].M_MoveRela(bLimit_1:=LimitStatus.Axis_2_Limit_1,bLimit_2:=LimitStatus.Axis_2_Limit_2,rDistance:=rDistance,rVelocity:=rVelocity,bExcute:=bComMoveRela,bDone=>MoveRelaStatus.bDone,bBusy=>MoveRelaStatus.bBusy,bActive=>MoveRelaStatus.bActive,bError=>MoveRelaStatus.bErr,dErrorID=>MoveRelaStatus.dErrID);
16 Axis[2].M_Stop(bExcute:=bComStop,bDone=>StopStatus.bDone,bBusy=>StopStatus.bBusy,bActive=>StopStatus.bActive,bError=>StopStatus.bErr,dErrorID=>StopStatus.dErrID);
17 Axis[2].M_Reset(bExcute:=bComRest,bDone=>ResetStatus.bDone,bBusy=>ResetStatus.bBusy,bError=>ResetStatus.bErr,dErrorID=>ResetStatus.dErrID);
18 Axis[2].M_ReadPosition(bExcute:=bComReadPos,bValid=>ReadPosStatus.bValid,bBusy=>ReadPosStatus.bBusy,bError=>ReadPosStatus.bErr,dErrorID=>ReadPosStatus.dErrID,lPosition=>ReadPosStatus.lPosition);
19 Axis[2].M_ReadStatus(bExcute:=bComReadStatus,bValid=>AxisStatus.Axis_Valid,bBusy=>AxisStatus.Axis_Busy,bError=>AxisStatus.Axis_Err,dErrorID=>AxisStatus.Axis_ErrID,bErrorStop=>AxisStatus.Axis_ErrorStop,bDisabled=>AxisStatus.Axis_Disabled,bStopping=>AxisStatus.Axis_Stopping,bStandStill=>AxisStatus.Axis_StandStill,bDiscreteMotion=>AxisStatus.Axis_DiscreteMotion,bContinuousMotion=>AxisStatus.Axis_ContinuousMotion,bSynchronizedMotion=>AxisStatus.Axis_SynchronizedMotion,bHoming=>AxisStatus.Axis_Homing,bConstantVelocity=>AxisStatus.Axis_ConstantVelocity,bAccelerating=>AxisStatus.Axis_Accelerating,bDecelerating=>AxisStatus.Axis_Decelerating);
20 ……………………
21 13:
22 Axis13.M_PowerOn(bExcute:=bComPowerOn,bStatus=>PoweronStatus.bStatus,bBusy=>PoweronStatus.bBusy,bActive=>PoweronStatus.bActive,bError=>PoweronStatus.bErr,dErrorID=>PoweronStatus.dErrID);
23 Axis13.M_PowerOff(bExcute:=bComPowerOff,bStatus=>PoweroffStatus.bStatus,bBusy=>PoweroffStatus.bBusy,bActive=>PoweroffStatus.bActive,bError=>PoweroffStatus.bErr,dErrorID=>PoweroffStatus.dErrID);
24 Axis13.M_MoveAbs(bLimit_1:=LimitStatus.Axis_13_Limit_1,bLimit_2:=LimitStatus.Axis_13_Limit_2,rDistance:=rDistance,rVelocity:=rVelocity,bExcute:=bComMoveAbs,bDone=>MoveAbsStatus.bDone,bBusy=>MoveAbsStatus.bBusy,bActive=>MoveAbsStatus.bActive,bError=>MoveAbsStatus.bErr,dErrorID=>MoveAbsStatus.dErrID);
25 Axis13.M_MoveRela(bLimit_1:=LimitStatus.Axis_13_Limit_1,bLimit_2:=LimitStatus.Axis_13_Limit_2,rDistance:=rDistance,rVelocity:=rVelocity,bExcute:=bComMoveRela,bDone=>MoveRelaStatus.bDone,bBusy=>MoveRelaStatus.bBusy,bActive=>MoveRelaStatus.bActive,bError=>MoveRelaStatus.bErr,dErrorID=>MoveRelaStatus.dErrID);
26 Axis13.M_Stop(bExcute:=bComStop,bDone=>StopStatus.bDone,bBusy=>StopStatus.bBusy,bActive=>StopStatus.bActive,bError=>StopStatus.bErr,dErrorID=>StopStatus.dErrID);
27 Axis13.M_Reset(bExcute:=bComRest,bDone=>ResetStatus.bDone,bBusy=>ResetStatus.bBusy,bError=>ResetStatus.bErr,dErrorID=>ResetStatus.dErrID);
28 Axis13.M_ReadPosition(bExcute:=bComReadPos,bValid=>ReadPosStatus.bValid,bBusy=>ReadPosStatus.bBusy,bError=>ReadPosStatus.bErr,dErrorID=>ReadPosStatus.dErrID,lPosition=>ReadPosStatus.lPosition);
29 Axis13.M_ReadStatus(bExcute:=bComReadStatus,bValid=>AxisStatus.Axis_Valid,bBusy=>AxisStatus.Axis_Busy,bError=>AxisStatus.Axis_Err,dErrorID=>AxisStatus.Axis_ErrID,bErrorStop=>AxisStatus.Axis_ErrorStop,bDisabled=>AxisStatus.Axis_Disabled,bStopping=>AxisStatus.Axis_Stopping,bStandStill=>AxisStatus.Axis_StandStill,bDiscreteMotion=>AxisStatus.Axis_DiscreteMotion,bContinuousMotion=>AxisStatus.Axis_ContinuousMotion,bSynchronizedMotion=>AxisStatus.Axis_SynchronizedMotion,bHoming=>AxisStatus.Axis_Homing,bConstantVelocity=>AxisStatus.Axis_ConstantVelocity,bAccelerating=>AxisStatus.Axis_Accelerating,bDecelerating=>AxisStatus.Axis_Decelerating);
30 Axis13.M_Home(bExcute:=bHome,bCalibrationCam:=Axis_13_CaliCam,bDone=>HomeStatus.bDone,bBusy=>HomeStatus.bBusy,bActive=>HomeStatus.bActive,bError=>HomeStatus.bErr,dErrorID=>HomeStatus.dErrID);
31 END_CASE
运行时,先输入iAxisNum,再执行命令即可。
方法二
定义轴基本功能,同上。区别在于Main主函数:
在Main中添加Action
ACT_PowerOn方法代码,其余类似。
1 FOR i:=1 TO 13 DO
2 Axis[i].M_PowerOn(bExcute:=cmdPowerOn[i],bStatus=>PoweronStatus.bStatus,bBusy=>PoweronStatus.bBusy,bActive=>PoweronStatus.bActive,bError=>PoweronStatus.bErr,dErrorID=>PoweronStatus.dErrID);
3 END_FOR
Main函数代码:
1 //定义接口及继承关系
2 Axis : ARRAY[1..10] OF Axis_Base_PTP;
3 Axis11 : Axis11_PTP;
4 Axis12 : Axis12_PTP;
5 Axis13 : Axis13_PTP;
6
7 cmdPowerOn AT%I* : ARRAY[1..13] OF BOOL;
8 cmdPowerOff AT%I* : ARRAY[1..13] OF BOOL;
9 cmdMoveRela AT%I* : ARRAY[1..13] OF BOOL;
10 cmdMoveAbs AT%I* : ARRAY[1..13] OF BOOL;
11 cmdReset AT%I* : ARRAY[1..13] OF BOOL;
12 cmdStop AT%I* : ARRAY[1..13] OF BOOL;
13 cmdReadPos AT%I* : ARRAY[1..13] OF BOOL;
14 cmdReadStatus AT%I* : ARRAY[1..13] OF BOOL;
15 cmdHome AT%I* : BOOL;
16 cmdGlassForward AT%I* : BOOL;
17 cmdGlassBack AT%I* : BOOL;
18 cmdTurnIn AT%I* : BOOL;
19 cmdTurnOut AT%I* : BOOL;
主函数调用Action方法进行轮询:
1 ACT_PowerOn();
2 ACT_PowerOff();
3 ACT_MoveAbs();
4 ACT_MoveRela();
5 ACT_Reset();
6 ACT_Stop();
7 ACT_ReadPos();
8 ACT_ReadStatus();
运行时,需针对每个轴的每个指令进行下发。
方法三
利用面向对象中的接口和继承方法。借鉴示例。
首先定义接口及属性方法,定义一个基类实现接口中的属性和方法,若需要再定义类继承基类。
Main函数;
1 PROGRAM MAIN
2 VAR
3 fbGenerator1 : FB_Generator;
4 fbGenerator2 : FB_GeneratorEX;
5 iGenerator : I_Generator;
6 tCycletime: TIME :=T#3S;
7 sVendor: STRING;
8 change: BOOL :=TRUE;
9 output: BOOL;
10 END_VAR
1 IF change THEN
2 iGenerator:=fbGenerator1;
3 ELSE
4 iGenerator:=fbGenerator2;
5 END_IF
6
7 output:=iGenerator.Flash();
8 iGenerator.Cycletime:=tcycletime;
9 sVendor:=iGenerator.Vendor;
运行时,通过接口切换调用不同轴模块。
优缺点比较
方法一:上位机调用变量较少,主程序复杂;
方法二:上位机调用变量较多,主程序简单;
方法三:上位机调用变量较少,主程序轴联动复杂;