Beckhoff TwinCAT3 PLC多轴编程的方法


测试共有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 CmandAborted=> , 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 CmandAborted=> , 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 CmandAborted=> , 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 CmandAborted=> , 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 HeStatus:ST_HeStatus;(*寻参模块结构体*) 25 LimitStatus:ST_LimitStatus;(*限位开关状态*) 26 27 //定义指令 28 bCPowerOn AT%I* : BOOL;(*上电命令*) 29 bCPowerOff AT%I* : BOOL;(*下电命令*) 30 bCMoveRela AT%I* : BOOL;(*相对位置指令*) 31 bCStop AT%I* : BOOL;(*停止指令*) 32 bCMoveAbs AT%I* : BOOL;(*绝对位置指令*) 33 bCRest AT%I* : BOOL;(*复位指令*) 34 bCReadPos AT%I* : BOOL;(*读取当前位置指令*) 35 bCReadStatus AT%I* : BOOL;(*读取电机状态指令*) 36 bHe 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:=bCPowerOn,bStatus=>PoweronStatus.bStatus,bBusy=>PoweronStatus.bBusy,bActive=>PoweronStatus.bActive,bError=>PoweronStatus.bErr,dErrorID=>PoweronStatus.dErrID); 4 Axis[1].M_PowerOff(bExcute:=bCPowerOff,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:=bCMoveAbs,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:=bCMoveRela,bDone=>MoveRelaStatus.bDone,bBusy=>MoveRelaStatus.bBusy,bActive=>MoveRelaStatus.bActive,bError=>MoveRelaStatus.bErr,dErrorID=>MoveRelaStatus.dErrID); 7 Axis[1].M_Stop(bExcute:=bCStop,bDone=>StopStatus.bDone,bBusy=>StopStatus.bBusy,bActive=>StopStatus.bActive,bError=>StopStatus.bErr,dErrorID=>StopStatus.dErrID); 8 Axis[1].M_Reset(bExcute:=bCRest,bDone=>ResetStatus.bDone,bBusy=>ResetStatus.bBusy,bError=>ResetStatus.bErr,dErrorID=>ResetStatus.dErrID); 9 Axis[1].M_ReadPosition(bExcute:=bCReadPos,bValid=>ReadPosStatus.bValid,bBusy=>ReadPosStatus.bBusy,bError=>ReadPosStatus.bErr,dErrorID=>ReadPosStatus.dErrID,lPosition=>ReadPosStatus.lPosition); 10 Axis[1].M_ReadStatus(bExcute:=bCReadStatus,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,bHing=>AxisStatus.Axis_Hing,bConstantVelocity=>AxisStatus.Axis_ConstantVelocity,bAccelerating=>AxisStatus.Axis_Accelerating,bDecelerating=>AxisStatus.Axis_Decelerating); 11 2: 12 Axis[2].M_PowerOn(bExcute:=bCPowerOn,bStatus=>PoweronStatus.bStatus,bBusy=>PoweronStatus.bBusy,bActive=>PoweronStatus.bActive,bError=>PoweronStatus.bErr,dErrorID=>PoweronStatus.dErrID); 13 Axis[2].M_PowerOff(bExcute:=bCPowerOff,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:=bCMoveAbs,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:=bCMoveRela,bDone=>MoveRelaStatus.bDone,bBusy=>MoveRelaStatus.bBusy,bActive=>MoveRelaStatus.bActive,bError=>MoveRelaStatus.bErr,dErrorID=>MoveRelaStatus.dErrID); 16 Axis[2].M_Stop(bExcute:=bCStop,bDone=>StopStatus.bDone,bBusy=>StopStatus.bBusy,bActive=>StopStatus.bActive,bError=>StopStatus.bErr,dErrorID=>StopStatus.dErrID); 17 Axis[2].M_Reset(bExcute:=bCRest,bDone=>ResetStatus.bDone,bBusy=>ResetStatus.bBusy,bError=>ResetStatus.bErr,dErrorID=>ResetStatus.dErrID); 18 Axis[2].M_ReadPosition(bExcute:=bCReadPos,bValid=>ReadPosStatus.bValid,bBusy=>ReadPosStatus.bBusy,bError=>ReadPosStatus.bErr,dErrorID=>ReadPosStatus.dErrID,lPosition=>ReadPosStatus.lPosition); 19 Axis[2].M_ReadStatus(bExcute:=bCReadStatus,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,bHing=>AxisStatus.Axis_Hing,bConstantVelocity=>AxisStatus.Axis_ConstantVelocity,bAccelerating=>AxisStatus.Axis_Accelerating,bDecelerating=>AxisStatus.Axis_Decelerating); 20 …………………… 21 13: 22 Axis13.M_PowerOn(bExcute:=bCPowerOn,bStatus=>PoweronStatus.bStatus,bBusy=>PoweronStatus.bBusy,bActive=>PoweronStatus.bActive,bError=>PoweronStatus.bErr,dErrorID=>PoweronStatus.dErrID); 23 Axis13.M_PowerOff(bExcute:=bCPowerOff,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:=bCMoveAbs,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:=bCMoveRela,bDone=>MoveRelaStatus.bDone,bBusy=>MoveRelaStatus.bBusy,bActive=>MoveRelaStatus.bActive,bError=>MoveRelaStatus.bErr,dErrorID=>MoveRelaStatus.dErrID); 26 Axis13.M_Stop(bExcute:=bCStop,bDone=>StopStatus.bDone,bBusy=>StopStatus.bBusy,bActive=>StopStatus.bActive,bError=>StopStatus.bErr,dErrorID=>StopStatus.dErrID); 27 Axis13.M_Reset(bExcute:=bCRest,bDone=>ResetStatus.bDone,bBusy=>ResetStatus.bBusy,bError=>ResetStatus.bErr,dErrorID=>ResetStatus.dErrID); 28 Axis13.M_ReadPosition(bExcute:=bCReadPos,bValid=>ReadPosStatus.bValid,bBusy=>ReadPosStatus.bBusy,bError=>ReadPosStatus.bErr,dErrorID=>ReadPosStatus.dErrID,lPosition=>ReadPosStatus.lPosition); 29 Axis13.M_ReadStatus(bExcute:=bCReadStatus,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,bHing=>AxisStatus.Axis_Hing,bConstantVelocity=>AxisStatus.Axis_ConstantVelocity,bAccelerating=>AxisStatus.Axis_Accelerating,bDecelerating=>AxisStatus.Axis_Decelerating); 30 Axis13.M_He(bExcute:=bHe,bCalibrationCam:=Axis_13_CaliCam,bDone=>HeStatus.bDone,bBusy=>HeStatus.bBusy,bActive=>HeStatus.bActive,bError=>HeStatus.bErr,dErrorID=>HeStatus.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 cmdHe 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 iGeneratorycletime:=tcycletime; 9 sVendor:=iGenerator.Vendor;

运行时,通过接口切换调用不同轴模块。

优缺点比较

方法一:上位机调用变量较少,主程序复杂;
方法二:上位机调用变量较多,主程序简单;
方法三:上位机调用变量较少,主程序轴联动复杂;



上一篇:三菱Q系列PLC串口和台达变频器进行RTU通信

下一篇:Mitsubishi 三菱PLC高速计数器应用案例(电机测速、流量计、伺服同步、光栅尺控制)


倍福(Beckhoff)
Copyright © 2002-2019 k262电脑网 www.k262.cn 皖ICP备2020016292号
温馨提示:部分文章图片数据来源与网络,仅供参考!版权归原作者所有,如有侵权请联系删除!QQ:251442993 热门搜索 网站地图