测试共有13个轴,前10个轴包含基本功能,后3个轴包含独有功能。
定义每个轴的基本功能,包括上电、下电、走相对、走绝对、读位置、读状态、复位、停止等。
在Axis_Base_PTP中定义变量:
FUNCTION_BLOCK Axis_Base_PTP
VAR
REF: AXIS_REF;
mcMoveRela: MC_MoveRelative;
mcPower: MC_Power;
mcStop: MC_Stop;
mcMoveAbs: MC_MoveAbsolute;
mcReset: MC_Reset;
mcReadPosition: MC_ReadActualPosition;
mcReadStatus: MC_ReadStatus;
mcHalt: MC_Halt;
AxisPara:ST_AxisPara;
END_VAR
M_PowerOn方法代码:
METHOD M_PowerOn : BOOL
VAR_INPUT
bExcute : BOOL;
END_VAR
VAR_OUTPUT
bStatus : BOOL; (* B *)
bBusy : BOOL; (* V *)
bActive : BOOL; (* V *)
bError : BOOL; (* B *)
dErrorID : UDINT; (* E *)
END_VAR
IF bExcute THEN
mcPower(
Axis:= REF,
Enable:= TRUE,
Enable_Positive:= TRUE,
Enable_Negative:= TRUE,
Override:= AxisPara.rOverride,
BufferMode:= ,
Options:= ,
Status=> bStatus,
Busy=> bBusy,
Active=> bActive,
Error=> bError,
ErrorID=> dErrorID);
END_IF
M_MoveRela方法代码:
METHOD M_MoveRela : BOOL
VAR_INPUT
bLimit_1 : BOOL;
bLimit_2 : BOOL;
rDistance : REAL;
rVelocity : REAL;
bExcute : BOOL;
END_VAR
VAR_OUTPUT
bDone : BOOL; (* B *)
bBusy : BOOL; (* V *)
bActive : BOOL; (* V *)
bError : BOOL; (* B *)
dErrorID : UDINT; (* E *)
END_VAR
IF rDistance>0 THEN
mcHalt(
Axis:= REF,
Execute:= bLimit_1,
Deceleration:= AxisPara.Deceleration,
Jerk:= ,
BufferMode:= ,
Options:= ,
Done=> ,
Busy=> ,
Active=> ,
CommandAborted=> ,
Error=> ,
ErrorID=> );
IF NOT bLimit_1 THEN
mcMoveRela(
Axis:= REF,
Execute:= bExcute,
Distance:= rDistance,
Velocity:= rVelocity,
Acceleration:= AxisPara.Acceleration,
Deceleration:= AxisPara.Deceleration,
Jerk:= ,
BufferMode:= ,
Options:= ,
Done=> bDone,
Busy=> bBusy,
Active=> bActive,
CommandAborted=> ,
Error=> bError,
ErrorID=> dErrorID);
END_IF
ELSIF rDistance<0 THEN
mcHalt(
Axis:= REF,
Execute:= bLimit_2,
Deceleration:= AxisPara.Deceleration,
Jerk:= ,
BufferMode:= ,
Options:= ,
Done=> ,
Busy=> ,
Active=> ,
CommandAborted=> ,
Error=> ,
ErrorID=> );
IF NOT bLimit_2 THEN
mcMoveRela(
Axis:= REF,
Execute:= bExcute,
Distance:= rDistance,
Velocity:= rVelocity,
Acceleration:= AxisPara.Acceleration,
Deceleration:= AxisPara.Deceleration,
Jerk:= ,
BufferMode:= ,
Options:= ,
Done=> bDone,
Busy=> bBusy,
Active=> bActive,
CommandAborted=> ,
Error=> bError,
ErrorID=> dErrorID);
END_IF
END_IF
对于附加功能的轴11,继承Axis_Base_PTP,独有的方法M_TurnInOut另外添加。
Axis_Base_PTP继承自基类并定义变量:
FUNCTION_BLOCK Axis11_PTP EXTENDS Axis_Base_PTP
VAR_INPUT
END_VAR
VAR_OUTPUT
bMagnet_1 AT%Q* : BOOL;
bMagnet_2 AT%Q* : BOOL;
END_VAR
VAR
bIn : BOOL :=FALSE;
bOut: BOOL :=FALSE;
TON_0: TON;
TON_1: TON;
bTemp1: BOOL;
bTemp2: BOOL;
MC_MoveRelative_0: MC_MoveRelative;
mcHaltChange_0: MC_Halt;
END_VAR
M_TurnInOut方法代码:
METHOD M_TurnInOut : BOOL
VAR_INPUT
bTurnIn : BOOL;
bTurnOut : BOOL;
bLimit1 : BOOL;
END_VAR
VAR_OUTPUT
END_VAR
在Main函数中定义变量:
//定义接口及继承关系
Axis : ARRAY[1..10] OF Axis_Base_PTP;
Axis11 : Axis11_PTP;
Axis12 : Axis12_PTP;
Axis13 : Axis13_PTP;
//选择电机轴号
iAxisNum AT%I* : UINT;(*电机轴号*)
//定义电机运行相对距离参数
rDistance AT%I* : REAL;(*运动距离*)
rVelocity AT%I* : REAL;(*运动速度*)
//定义结构体
AxisPara:ST_AxisPara;(*轴参数结构体*)
AxisStatus:ST_AxisStatus;(*轴状态结构体*)
PoweronStatus:ST_PoweronStatus; (*上电模块结构体*)
PoweroffStatus:ST_PoweroffStatus;(*下电模块结构体*)
MoveAbsStatus:ST_MoveAbsStatus; (*绝对运动模式结构体*)
MoveRelaStatus:ST_MoveRelaStatus;(*相对运动模式结构体*)
StopStatus:ST_StopStatus;(*停止模块结构体*)
ResetStatus:ST_ResetStatus;(*复位模块结构体*)
ReadPosStatus:ST_ReadPosStatus;(*读取轴位置结构体*)
HomeStatus:ST_HomeStatus;(*寻参模块结构体*)
LimitStatus:ST_LimitStatus;(*限位开关状态*)
//定义指令
bComPowerOn AT%I* : BOOL;(*上电命令*)
bComPowerOff AT%I* : BOOL;(*下电命令*)
bComMoveRela AT%I* : BOOL;(*相对位置指令*)
bComStop AT%I* : BOOL;(*停止指令*)
bComMoveAbs AT%I* : BOOL;(*绝对位置指令*)
bComRest AT%I* : BOOL;(*复位指令*)
bComReadPos AT%I* : BOOL;(*读取当前位置指令*)
bComReadStatus AT%I* : BOOL;(*读取电机状态指令*)
bHome AT%I* : BOOL;(*电机13寻参指令*)
bGlassForward AT%I* : BOOL;(*电机12更换保护玻璃前进*)
bGlassBack AT%I* : BOOL;(*电机12更换保护玻璃后退*)
bTurnIn AT%I* : BOOL;(*电机11转入*)
bTurnOut AT%I* : BOOL;(*电机11转出*)
CASE iAxisNum OF
1:
Axis[1].M_PowerOn(bExcute:=bComPowerOn,bStatus=>PoweronStatus.bStatus,bBusy=>PoweronStatus.bBusy,bActive=>PoweronStatus.bActive,bError=>PoweronStatus.bErr,dErrorID=>PoweronStatus.dErrID);
Axis[1].M_PowerOff(bExcute:=bComPowerOff,bStatus=>PoweroffStatus.bStatus,bBusy=>PoweroffStatus.bBusy,bActive=>PoweroffStatus.bActive,bError=>PoweroffStatus.bErr,dErrorID=>PoweroffStatus.dErrID);
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);
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);
Axis[1].M_Stop(bExcute:=bComStop,bDone=>StopStatus.bDone,bBusy=>StopStatus.bBusy,bActive=>StopStatus.bActive,bError=>StopStatus.bErr,dErrorID=>StopStatus.dErrID);
Axis[1].M_Reset(bExcute:=bComRest,bDone=>ResetStatus.bDone,bBusy=>ResetStatus.bBusy,bError=>ResetStatus.bErr,dErrorID=>ResetStatus.dErrID);
Axis[1].M_ReadPosition(bExcute:=bComReadPos,bValid=>ReadPosStatus.bValid,bBusy=>ReadPosStatus.bBusy,bError=>ReadPosStatus.bErr,dErrorID=>ReadPosStatus.dErrID,lPosition=>ReadPosStatus.lPosition);
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);
2:
Axis[2].M_PowerOn(bExcute:=bComPowerOn,bStatus=>PoweronStatus.bStatus,bBusy=>PoweronStatus.bBusy,bActive=>PoweronStatus.bActive,bError=>PoweronStatus.bErr,dErrorID=>PoweronStatus.dErrID);
Axis[2].M_PowerOff(bExcute:=bComPowerOff,bStatus=>PoweroffStatus.bStatus,bBusy=>PoweroffStatus.bBusy,bActive=>PoweroffStatus.bActive,bError=>PoweroffStatus.bErr,dErrorID=>PoweroffStatus.dErrID);
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);
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);
Axis[2].M_Stop(bExcute:=bComStop,bDone=>StopStatus.bDone,bBusy=>StopStatus.bBusy,bActive=>StopStatus.bActive,bError=>StopStatus.bErr,dErrorID=>StopStatus.dErrID);
Axis[2].M_Reset(bExcute:=bComRest,bDone=>ResetStatus.bDone,bBusy=>ResetStatus.bBusy,bError=>ResetStatus.bErr,dErrorID=>ResetStatus.dErrID);
Axis[2].M_ReadPosition(bExcute:=bComReadPos,bValid=>ReadPosStatus.bValid,bBusy=>ReadPosStatus.bBusy,bError=>ReadPosStatus.bErr,dErrorID=>ReadPosStatus.dErrID,lPosition=>ReadPosStatus.lPosition);
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);
……………………
13:
Axis13.M_PowerOn(bExcute:=bComPowerOn,bStatus=>PoweronStatus.bStatus,bBusy=>PoweronStatus.bBusy,bActive=>PoweronStatus.bActive,bError=>PoweronStatus.bErr,dErrorID=>PoweronStatus.dErrID);
Axis13.M_PowerOff(bExcute:=bComPowerOff,bStatus=>PoweroffStatus.bStatus,bBusy=>PoweroffStatus.bBusy,bActive=>PoweroffStatus.bActive,bError=>PoweroffStatus.bErr,dErrorID=>PoweroffStatus.dErrID);
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);
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);
Axis13.M_Stop(bExcute:=bComStop,bDone=>StopStatus.bDone,bBusy=>StopStatus.bBusy,bActive=>StopStatus.bActive,bError=>StopStatus.bErr,dErrorID=>StopStatus.dErrID);
Axis13.M_Reset(bExcute:=bComRest,bDone=>ResetStatus.bDone,bBusy=>ResetStatus.bBusy,bError=>ResetStatus.bErr,dErrorID=>ResetStatus.dErrID);
Axis13.M_ReadPosition(bExcute:=bComReadPos,bValid=>ReadPosStatus.bValid,bBusy=>ReadPosStatus.bBusy,bError=>ReadPosStatus.bErr,dErrorID=>ReadPosStatus.dErrID,lPosition=>ReadPosStatus.lPosition);
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);
Axis13.M_Home(bExcute:=bHome,bCalibrationCam:=Axis_13_CaliCam,bDone=>HomeStatus.bDone,bBusy=>HomeStatus.bBusy,bActive=>HomeStatus.bActive,bError=>HomeStatus.bErr,dErrorID=>HomeStatus.dErrID);
END_CASE
运行时,先输入iAxisNum,再执行命令即可。
定义轴基本功能,同上。区别在于Main主函数:
在Main中添加Action
ACT_PowerOn方法代码,其余类似。
FOR i:=1 TO 13 DO
Axis[i].M_PowerOn(bExcute:=cmdPowerOn[i],bStatus=>PoweronStatus.bStatus,bBusy=>PoweronStatus.bBusy,bActive=>PoweronStatus.bActive,bError=>PoweronStatus.bErr,dErrorID=>PoweronStatus.dErrID);
END_FOR
Main函数代码:
//定义接口及继承关系
Axis : ARRAY[1..10] OF Axis_Base_PTP;
Axis11 : Axis11_PTP;
Axis12 : Axis12_PTP;
Axis13 : Axis13_PTP;
cmdPowerOn AT%I* : ARRAY[1..13] OF BOOL;
cmdPowerOff AT%I* : ARRAY[1..13] OF BOOL;
cmdMoveRela AT%I* : ARRAY[1..13] OF BOOL;
cmdMoveAbs AT%I* : ARRAY[1..13] OF BOOL;
cmdReset AT%I* : ARRAY[1..13] OF BOOL;
cmdStop AT%I* : ARRAY[1..13] OF BOOL;
cmdReadPos AT%I* : ARRAY[1..13] OF BOOL;
cmdReadStatus AT%I* : ARRAY[1..13] OF BOOL;
cmdHome AT%I* : BOOL;
cmdGlassForward AT%I* : BOOL;
cmdGlassBack AT%I* : BOOL;
cmdTurnIn AT%I* : BOOL;
cmdTurnOut AT%I* : BOOL;
主函数调用Action方法进行轮询:
ACT_PowerOn();
ACT_PowerOff();
ACT_MoveAbs();
ACT_MoveRela();
ACT_Reset();
ACT_Stop();
ACT_ReadPos();
ACT_ReadStatus();
运行时,需针对每个轴的每个指令进行下发。
利用面向对象中的接口和继承方法。借鉴示例。
首先定义接口及属性方法,定义一个基类实现接口中的属性和方法,若需要再定义类继承基类。
Main函数;
PROGRAM MAIN
VAR
fbGenerator1 : FB_Generator;
fbGenerator2 : FB_GeneratorEX;
iGenerator : I_Generator;
tCycletime: TIME :=T#3S;
sVendor: STRING;
change: BOOL :=TRUE;
output: BOOL;
END_VAR
IF change THEN
iGenerator:=fbGenerator1;
ELSE
iGenerator:=fbGenerator2;
END_IF
output:=iGenerator.Flash();
iGenerator.Cycletime:=tcycletime;
sVendor:=iGenerator.Vendor;
运行时,通过接口切换调用不同轴模块。
方法一:上位机调用变量较少,主程序复杂;
方法二:上位机调用变量较多,主程序简单;
方法三:上位机调用变量较少,主程序轴联动复杂;