[汇川] 汇川中型PLC电子凸轮同步应用案例

[复制链接]
查看71552 | 回复0 | 2024-9-5 09:16:52 | 显示全部楼层 |阅读模式
本案例应用在龙门传动结构时,传动部分需要使用两个伺服电机达到位置与速度同步。首先介绍下机械凸轮与电子凸轮的基础介绍及区别一、机械凸轮基础机械凸轮(CAM)是一种能够按照动力学特征和运行学特征的要求,具有曲线或者曲面轮廓作为高副元素的构件。从动件(Driven Link)是机构中除了主动件以外随着主动件运动的其余可动构件。凸轮曲线(CAM Curve)是凸轮驱动从动件的运动曲线。

二、电子凸轮基础电子凸轮(ECAM)是利用构造的凸轮曲线来模拟机械凸轮,以达到机械凸轮系统相同的凸轮轴与主轴之间相对运动的软件系统。电子凸轮相当于无数个各种类型的机械凸轮的集合体,只需进行参数配置,即可适用于各种方案,典型的电子凸轮应用有:飞剪、旋切、追剪、飞锯、跟随、龙门同步等。电子凸轮相比于机械凸轮的优点:兼容性:机械凸轮一种结构只能实现一种运动动作,电子凸轮可以通过程序修改运行精度:电气元件精度远高于机械精度设备结构:电子凸轮机构上的组成通常仅需一套简单的传送机构安全性能:伺服系统的制动时间远短于机械动态制动电子凸轮根据动作特点分类:5. 单向型:一致执行同向运动,如飞剪、旋切等;6. 双向型:执行的往复运动如追剪、飞锯等;7. 特殊型:根据自由的曲线进行动作的曲线,如跟随、同步等;电子凸轮系统由4部分构成:上位机(如PLC)、驱动部分(如伺服电机)、执行部分(如直线滑台)和检测部分(各类传感器)。电子凸轮的基本运动实现过程:将电子凸轮曲线导入上位机,上位机根据电子凸轮曲线的位置数据对相应的执行部分进行控制,通过外部信号或内部逻辑进行电子凸轮运动的启动和停止。

三、电子凸轮的典型应用1、飞剪:剪切机构一般为圆周运动,与被剪切物体同向运动,通过改变剪切机构运行中的速度,达到改变剪切长度的目的。2、追剪:剪切机构平行于被剪切物体,剪切机构做往复运动,通过改变在非同步区的速度达到改变剪切长度的目的。飞剪与追剪的共同点:飞剪与追剪都分为非同步区与同步区的概念,要求同步区剪切机构与被剪切机构速度相同。飞剪与追剪的不同点:飞剪是圆周运动,同步区小,但是可以做高速运动;追剪是往复运动,同步区大,可以完成较为复杂的剪切、冲压等动作。四、电子凸轮关键词定义主轴:作为同步控制的参考轴,又名输入轴。
从轴:根据主轴位置,按照所需非线性特性进行跟随运动的伺服轴,又名输出轴。
凸轮表:描述主轴 - 从轴相对位置与范围、周期性等的数据表或凸轮曲线。用户编写程序需要设计凸轮表,指定主轴与从轴,运行中在合适时刻触发凸轮运行,就可以使得从轴进入凸轮运行了。五、电子凸轮功能块MC_CamTableSelect
这个功能块位于函数库SM3_Basic.library。用于将选择的cam表格连接到实际的表格上。

MC_Camin这个功能块位于函数库SM3_Basic.library。用于启动一个cam。

MC_CamOut

这个功能块位于函数库SM3_Basic.library。此功能块将从轴与主轴立刻分离。

MC_Phasing

MC_Phasing 保证主从轴之间的常量相位偏移。

六、案例应用组态配置


变量声明与实例化
全局变量
VAR_GLOBAL  g_凸轮表结构体数组    :  ARRAY[0..g_i轴数量] OF MC_CAM_REF;    g_凸轮点数组      :  ARRAY[0..g_i轴数量] OF ARRAY [0..19] OF SMC_CAMXYVA;  g_dx           :  ARRAY[0..g_i轴数量] OF ARRAY[0..10] OF REAL;  g_dy           :  ARRAY[0..g_i轴数量] OF ARRAY[0..10] OF REAL;  g_dv           :  ARRAY[0..g_i轴数量] OF ARRAY[0..10] OF REAL;  g_b轴使能        :  ARRAY[0..g_i轴数量] OF BOOL;  g_b凸轮点写入      :  ARRAY[0..g_i轴数量] OF BOOL;  g_b凸轮耦合        :  ARRAY[0..g_i轴数量] OF BOOL;  g_b主轴正向点动      :  BOOL;  g_b主轴负向点动      :  BOOL;  g_b从轴1正向点动    :  BOOL;  g_b从轴1负向点动    :  BOOL;  g_b从轴2正向点动    :  BOOL;  g_b从轴2负向点动    :  BOOL;  g_b主轴绝对定位      :  BOOL;  g_b上电初始化定位    :  BOOL;  g_lr就近位置      :  LREAL;    g_r主轴定位位置: REAL;END_VARVAR_GLOBAL CONSTANTg_i轴数量              :  INT := 29;END_VAR
局部变量
PROGRAMPLC_PRGVARMC_Power_0: MC_Power;MC_Power_1: MC_Power;MC_Power_2: MC_Power;MC_CamTableSelect_0: MC_CamTableSelect;MC_CamIn_0: MC_CamIn;MC_CamTableSelect_1: MC_CamTableSelect;MC_CamIn_1: MC_CamIn;MC_MoveAbsolute_0: MC_MoveAbsolute;MC_MoveAbsolute_1: MC_MoveAbsolute;v_b凸轮点写入:ARRAY[0..g_i轴数量] OF BOOL;MC_SetPosition_0: MC_SetPosition;MC_Jog_从轴1: MC_Jog;MC_Jog_从轴2: MC_Jog;MC_Jog_主轴: MC_Jog;  MC_MoveAbsolute_主轴: MC_MoveAbsolute;END_VAR本案例中使用了枚举如下
TYPE Enum_轴名称 :(  主轴     := 0,//Axis_0  从轴1     := 1,//Axis_1  从轴2     := 2//Axis_2);END_TYPE
轴使能
MC_Power_0(  Axis:= SM_Drive_Virtual,   Enable:= TRUE,   bRegulatorOn:= g_b轴使能[Enum_轴名称.主轴],   bDriveStart:= TRUE, Status=> , bRegulatorRealState=> , bDriveStartRealState=> , Busy=> , Error=> , ErrorID=> );MC_Power_1(  Axis:= Axis,   Enable:= TRUE,   bRegulatorOn:= g_b轴使能[Enum_轴名称.从轴1],   bDriveStart:= TRUE, Status=> , bRegulatorRealState=> , bDriveStartRealState=> , Busy=> , Error=> , ErrorID=> );MC_Power_2(  Axis:= Axis_1,   Enable:= TRUE,   bRegulatorOn:= g_b轴使能[Enum_轴名称.从轴2],   bDriveStart:= TRUE, Status=> , bRegulatorRealState=> , bDriveStartRealState=> , Busy=> , Error=> ,   ErrorID=> );凸轮关键点计算与凸轮表数据结构,这里默认使用多项式的形式进行编译
g_dx[Enum_轴名称.从轴1][0]:=0;g_dy[Enum_轴名称.从轴1][0]:=g_lr就近位置;g_dv[Enum_轴名称.从轴1][0]:=(g_dy[Enum_轴名称.从轴1][1]-g_dy[Enum_轴名称.从轴1][0])/360;g_dx[Enum_轴名称.从轴1][1]:=360;g_dy[Enum_轴名称.从轴1][1]:=g_lr就近位置+360;g_dv[Enum_轴名称.从轴1][1]:=(g_dy[Enum_轴名称.从轴1][1]-g_dy[Enum_轴名称.从轴1][0])/360;
g_dx[Enum_轴名称.从轴2][0]:=0;g_dy[Enum_轴名称.从轴2][0]:=g_lr就近位置;g_dv[Enum_轴名称.从轴2][0]:=(g_dy[Enum_轴名称.从轴2][1]-g_dy[Enum_轴名称.从轴2][0])/360;g_dx[Enum_轴名称.从轴2][1]:=360;g_dy[Enum_轴名称.从轴2][1]:=g_lr就近位置+360;g_dv[Enum_轴名称.从轴2][1]:=(g_dy[Enum_轴名称.从轴2][1]-g_dy[Enum_轴名称.从轴2][0])/360;//从轴1凸轮点IF g_b凸轮点写入[Enum_轴名称.从轴1] THEN  g_凸轮点数组[Enum_轴名称.从轴1][0].dX:=g_dx[Enum_轴名称.从轴1][0];  g_凸轮点数组[Enum_轴名称.从轴1][0].dy:=g_dy[Enum_轴名称.从轴1][0];  g_凸轮点数组[Enum_轴名称.从轴1][0].dv:=g_dv[Enum_轴名称.从轴1][0];  g_凸轮点数组[Enum_轴名称.从轴1][0].da:=0;  g_凸轮点数组[Enum_轴名称.从轴1][1].dX:=g_dx[Enum_轴名称.从轴1][1];  g_凸轮点数组[Enum_轴名称.从轴1][1].dy:=g_dy[Enum_轴名称.从轴1][1];  g_凸轮点数组[Enum_轴名称.从轴1][1].dv:=g_dv[Enum_轴名称.从轴1][1];  g_凸轮点数组[Enum_轴名称.从轴1][1].da:=0;  g_凸轮表结构体数组[Enum_轴名称.从轴1](  wCamStructID:= , byType:= 3, byVarType:= 6,   xStart:= 0, xEnd:= g_凸轮点数组[Enum_轴名称.从轴1][1].dX,   nElements:= 2, nTappets:=, pce:= ADR(g_凸轮点数组[Enum_轴名称.从轴1]),   pt:= , dwTappetActiveBits:= , strCAMName:= , byInterpolationQuality:= ,   byCompatibilityMode:= , bChangedOnline:= , xPartofLM:= );  v_b凸轮点写入[Enum_轴名称.从轴1]:=TRUE;ELSE  v_b凸轮点写入[Enum_轴名称.从轴1]:=FALSE;END_IF//从轴2凸轮点IF g_b凸轮点写入[Enum_轴名称.从轴2] THEN  g_凸轮点数组[Enum_轴名称.从轴2][0].dX:=g_dx[Enum_轴名称.从轴2][0];  g_凸轮点数组[Enum_轴名称.从轴2][0].dy:=g_dy[Enum_轴名称.从轴2][0];  g_凸轮点数组[Enum_轴名称.从轴2][0].dv:=g_dv[Enum_轴名称.从轴2][0];  g_凸轮点数组[Enum_轴名称.从轴2][0].da:=0;  g_凸轮点数组[Enum_轴名称.从轴2][1].dX:=g_dx[Enum_轴名称.从轴2][1];  g_凸轮点数组[Enum_轴名称.从轴2][1].dy:=g_dy[Enum_轴名称.从轴2][1];  g_凸轮点数组[Enum_轴名称.从轴2][1].dv:=g_dv[Enum_轴名称.从轴2][1];  g_凸轮点数组[Enum_轴名称.从轴2][1].da:=0;  g_凸轮表结构体数组[Enum_轴名称.从轴2](  wCamStructID:= , byType:= 3, byVarType:= 6,   xStart:= 0, xEnd:= g_凸轮点数组[Enum_轴名称.从轴2][1].dX,   nElements:= 2, nTappets:= , pce:= ADR(g_凸轮点数组[Enum_轴名称.从轴2]),   pt:= , dwTappetActiveBits:= , strCAMName:= , byInterpolationQuality:= ,   byCompatibilityMode:= , bChangedOnline:= , xPartofLM:= );  v_b凸轮点写入[Enum_轴名称.从轴2]:=TRUE;ELSE  v_b凸轮点写入[Enum_轴名称.从轴2]:=FALSE;END_IF


轴定位到凸轮起点//因该用法需将两个从轴定义为绝对值模式,上电后耦合需将两个轴定位到两个轴的区间中心处IFAxis.fActPosition > Axis_1.fActPosition THENg_lr就近位置:=((Axis.fActPosition - Axis_1.fActPosition)/2)+Axis_1.fActPosition;ELSIFAxis.fActPosition < Axis_1.fActPosition THENg_lr就近位置:=((Axis_1.fActPosition - Axis.fActPosition)/2)+Axis.fActPosition;END_IFMC_MoveAbsolute_0(Axis:= Axis, Execute:= g_b上电初始化定位, Position:= g_lr就近位置, Velocity:= 50, Acceleration:= 50/0.5, Deceleration:= 50/0.5,Jerk:= , Direction:= , BufferMode:= , Done=> , Busy=> , Active=> , CommandAborted=> , Error=> , ErrorID=> );MC_MoveAbsolute_1(Axis:= Axis_1, Execute:= g_b上电初始化定位, Position:= g_lr就近位置, Velocity:= 50, Acceleration:= 50/0.5,Deceleration:= 50/0.5,Jerk:= , Direction:= , BufferMode:= , Done=> , Busy=> , Active=> , CommandAborted=> , Error=> , ErrorID=> );//上电将主轴位置定义为两轴就近位置,以确保凸轮耦合时主从位置相对凸轮表进行对齐。MC_SetPosition_0(Axis:= SM_Drive_Virtual, Execute:= g_b上电初始化定位, Position:= 0, Mode:= , Done=> , Busy=> , Error=> , ErrorID=> );凸轮耦合//从轴1耦合MC_CamTableSelect_0(Master:= SM_Drive_Virtual, Slave:= Axis, CamTable:= g_凸轮表结构体数组[Enum_轴名称.从轴1],Execute:= v_b凸轮点写入[Enum_轴名称.从轴1], Periodic:= TRUE, MasterAbsolute:= TRUE, SlaveAbsolute:= TRUE, Done=> , Busy=> , Error=> , ErrorID=> , CamTableID=> );MC_CamIn_0(Master:= SM_Drive_Virtual, Slave:= Axis, Execute:= MC_CamTableSelect_0.Done AND g_b凸轮耦合[Enum_轴名称.从轴1], MasterOffset:= , SlaveOffset:= , MasterScaling:= 1, SlaveScaling:= 1, StartMode:= ramp_in, CamTableID:= MC_CamTableSelect_0.CamTableID, VelocityDiff:= 50, Acceleration:= 250, Deceleration:= 250, Jerk:= , TappetHysteresis:= , InSync=> , Busy=> , CommandAborted=> , Error=> , ErrorID=> , EndOfProfile=> , Tappets=> );//从轴2耦合MC_CamTableSelect_1(Master:= SM_Drive_Virtual, Slave:= Axis_1, CamTable:= g_凸轮表结构体数组[Enum_轴名称.从轴2],Execute:=  v_b凸轮点写入[Enum_轴名称.从轴2], Periodic:= TRUE, MasterAbsolute:= TRUE, SlaveAbsolute:= TRUE, Done=> , Busy=> , Error=> , ErrorID=> , CamTableID=> );MC_CamIn_1(Master:= SM_Drive_Virtual, Slave:= Axis_1, Execute:= MC_CamTableSelect_1.Done AND g_b凸轮耦合[Enum_轴名称.从轴2], MasterOffset:= , SlaveOffset:= , MasterScaling:= 1, SlaveScaling:= 1, StartMode:= ramp_in, CamTableID:= MC_CamTableSelect_1.CamTableID, VelocityDiff:= 50, Acceleration:= 250, Deceleration:= 250, Jerk:= , TappetHysteresis:= , InSync=> , Busy=> , CommandAborted=> , Error=> , ErrorID=> , EndOfProfile=> , Tappets=> );耦合完成后,可通过任意单轴运动控制指令(不包括轴回零,轴设置位置)去控制主轴,这里将主轴绝对定位到360后又返回到0。//主轴点动MC_Jog_主轴(Axis:= SM_Drive_Virtual, JogForward:= g_b主轴正向点动, JogBackward:= g_b主轴负向点动, Velocity:= 50, Acceleration:= 50/0.5, Deceleration:= 50/0.5, Jerk:= , Busy=> , CommandAborted=> , Error=> , ErrorId=> );
MC_MoveAbsolute_主轴(Axis:= SM_Drive_Virtual, Execute:= g_b主轴绝对定位, Position:= g_r主轴定位位置, Velocity:= 50, Acceleration:= 50/0.5, Deceleration:= 50/0.5, Jerk:= , Direction:= , BufferMode:= , Done=> , Busy=> , Active=> , CommandAborted=> , Error=> , ErrorID=> );

需要了解更多关于运动控制相关的信息,可关注本公众号。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册哦

x
您需要登录后才可以回帖 登录 | 注册哦

本版积分规则