TwinCAT3 PLC多轴编程的方法

您所在的位置:网站首页 多工位plc编程方法 TwinCAT3 PLC多轴编程的方法

TwinCAT3 PLC多轴编程的方法

2023-09-10 10:27| 来源: 网络整理| 查看: 265

测试共有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 , 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

在这里插入图片描述 轴12、13等同理,省略。

在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;

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

优缺点比较

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



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3