一.硬件介绍

PCIE464运动控制卡是正运动推出的一款EtherCAT总线+脉冲型、PCIE接口式的运动控制卡,可选6-64轴运动控制,支持多路高速数字输入输出,可轻松实现多轴同步控制和高速数据传输。

PCIE464运动控制卡适合于多轴点位运动、插补运动、轨迹规划、手轮控制、编码器位置检测、IO控制、位置锁存等功能的应用。PCIE464运动控制卡适用于3C电子加工、检测设备、半导体设备、SMT加工、激光加工、光通讯设备、锂电及光伏设备、以及非标自动化设备等高速高精应用场合。

PCIE4系列控制卡的应用程序可以使用VC,VB,VS,C++,C#等软件开发,程序运行时需要动态库zmotion.dll,调试时可以将RTSys软件同时连接控制器,从而方便调试、方便观察。

PCIE464产品介绍

更多关于PCIE464的详情介绍,点击“PCIE464 — 高速高精,超高实时性的PCIe EtherCAT实时运动控制卡”查看。

二.接线参考

1.IN数字量输入接口数字输入分布在J400(IN0-IN7)和X400(IN8-IN39)信号接口中。
2.OUT数字量输出接口数字输出分布在J400(OUT0-7)和X400(OUT8-OUT39)信号接口中。

3.单端编码器及单端脉冲接线

单端脉冲接线图

差分脉冲接线图

单端编码器接线图

差分编码器接线图

注:PCIE464J400接口中有一个差分脉冲轴接口和三个单端脉冲轴接口,两个差分编码器接口(其中一个与差分脉冲轴接口复用,取决于固件设定)和两个单端编码器接口,具体引脚定义参见PCIE464硬件手册。

三.使用运动缓冲实现同步/提前/延时开关胶

1.运动缓冲

ZMotion运动控制器具有多级的运动缓冲,并且遵循先进先出原则。当运动缓冲开启的时候,程序在扫描识别到程序任务的第一条运动指令时,将运动指令分配到指定轴的运动缓冲区,电机开始运动,此时程序继续向下扫描到第二条运动指令时,再往运动缓冲区中存,在不断扫描存入运动指令的同时,从运动缓冲区中依次取出运动指令执行。

运动缓冲原理参考下图:

①MTYPE,NTYPE分别是当前运行的运动指令类型和MTYPE后面的第一条指令类型。

②任意一段程序的运动指令都可以进入任意轴的运动缓冲区,由轴号指定。

③每个轴的运动缓冲区都是独立的,互不干扰。

如下图:当运动缓冲区还有空间,运动指令就会进入运动缓冲区。然后可以通过MOVE_MARK设置标识,表示下一条要调用的运动指令的MARK标号,这个标号会和运动指令一起写入运动缓冲。等指令执行完成后,则退出运动缓冲区,之前的下一条指令变成正在运动指令,循环往复,直到缓冲区没有指令去执行。

缓冲多条运动指令时,为了判断当前运动执行到哪一条,提供MOVE_MARK运动标号和MOVE_CURMARK当前运动标号指令。

MOVE_MARK运动标号每扫描一条运动指令+1。

MOVE_CURMARK指令为当前运动的标号,提示当前运动到第几条运动指令,所有运动完成后为-1。

当前运动完成后会自动执行运动缓冲区内的下一条运动。运动指令全部执行完后,运动缓冲区为空,或者使用CANCEL/RAPIDSTOP指令清空运动缓冲区。

2.使用到的运动缓冲指令以及Basic效果演示

点胶的应用场景中,运动控制系统需要精准调节点胶阀开闭时机与针头运动轨迹,通过开胶延时,关胶延时,提前关胶等参数,确保胶量精准可控,满足工艺要求。

正运动技术提供了MOVE_OP运动缓冲中控制输出指令,用来实现点胶工艺中的同步/提前/延时开关胶功能。

(1)运动缓冲开关OP指令(MOVE_OP -- 缓冲输出)

MOVE_OP指令和MOVE/MOVEABS等指令一样属于运动指令,属于只操作I/O的特殊运动指令不会阻塞后续运动指令的执行。

MOVE_OP指令MOVE/MOVEABS等缓冲运动指令配合时可以实现在运动过程中指定位置同步开关胶。

Basic效果演示:

BASE(0,1)	 '依次例如点胶XY轴
UNITS = 1000000,1000000
SPEED = 100,100
ACCEL = 1000,1000
DECEL = 1000,1000
MPOS = 0,0
DPOS = 0,0
MERGE = 1
OP(0,OFF)
TRIGGER
MOVEABS(100,100)
'开胶点100,100
'XY走轨迹	
MOVE_OP(0,ON)	
MOVE(0,70)
MOVE(-100,0)
MOVE(0,-70)
MOVE(50,0)
MOVEABS(100,100)
'关胶点	
MOVE_OP(0,OFF)	
MOVEABS(0,0)

可以看到xy插补的时候,先运动到100,100打开OP,走完一个长方形轨迹后,再到100,100的位置关闭OP。

(2)MOVE_OP精准输出模式

实际点胶应用中有时精度要求比较高,用普通MOVEOP是比较指令位置(DPOS)满足不了要求,这时候我们需要开启MOVEOP精准模式。

开启精准模式后,MOVEOP执行时会在缓冲比较编码器位置(MPOS)到达前一条运动的目标位置再输出。

能够开启精准模式的OP需要硬件支持,一般4系列有4个通道可以用于精准输出,部分型号有8个,不同型号支持的通道数可以咨询正运动厂家。

Basic演示:

BASE(0,1)	 '依次例如点胶XY轴
UNITS = 1000000,1000000
SPEED = 100,100
ACCEL = 1000,1000
DECEL = 1000,1000
MPOS = 0,0
DPOS = 0,0
MERGE = 1
OP(0,OFF)
AXIS_ZSET = 19		'主轴设置精准输出模式
'XY走轨迹
MOVEABS(100,100)
'关胶点100,100
MOVE_OP(0,ON)	
MOVEABS(300,400)
'关胶点300,400
MOVE_OP(0,OFF)

设置插补主轴AXIS_ZSET=19开启MOVEOP精准模式。

(3)使用MOVEOP_ADIST设置提前/滞后一定距离开关胶

通过设置矢量距离来控制提前滞后开关胶,设置正数会比缺省输出位置(MOVE_OP上一条运动指令的目标位置)提前指定矢量距离,设置负数则延后指定矢量距离。可以由AXIS_ZSET来启动精准输出,同MOVE_OP精准,比较反馈位置。

Basic效果演示:

BASE(0,1)	 '依次例如点胶XY轴
UNITS = 1000000,1000000
SPEED = 100,100
ACCEL = 1000,1000
DECEL = 1000,1000
MPOS = 0,0
DPOS = 0,0
MERGE = 1
OP(0,OFF)
TRIGGER
MOVEABS(100,100)
'开胶点100,100
'XY走轨迹
MOVEOP_ADIST = -50	'滞后50mm打开	
MOVE_OP(0,ON)
MOVEOP_ADIST = 0		
MOVE_OP(1,ON)
MOVE(0,70)
MOVE(-100,0)
MOVE(0,-70)
MOVE(50,0)
MOVEABS(100,100)
'关胶点
MOVEOP_ADIST = 50	'提前50mm关闭
MOVE_OP(0,OFF)
MOVEOP_ADIST = 0			
MOVE_OP(1,OFF)	
MOVEABS(0,0)

设置OP1开关不做提前延后设置与OP0进行对比,可以看到OP0根据程序设置滞后50mm打开,提前50mm关闭了。

(4)使用MOVEOP_AHEADMS设置提前开关胶时间和MOVEOP_DELAY设置延后开关胶时间

注意MOVEOP_DELAY指令的效果受到轴FE的影响,若要忽略该影响,单纯验证指令功能,可以把ATYPE设置成0或者1去测试。

Basic效果演示:

BASE(0,1)	 '依次例如点胶XY轴
UNITS = 1000000,1000000
SPEED = 100,100
ACCEL = 1000,1000
DECEL = 1000,1000
MPOS = 0,0
DPOS = 0,0
MERGE = 1
AXIS_ZSET = 19		'主轴设置精准输出模式
OP(0,OFF)
TRIGGER
MOVEABS(100,100)
'开胶点100,100
'XY走轨迹
MOVEOP_DELAY = 100	'滞后50ms打开
MOVEOP_AHEADMS = 0	
MOVE_OP(0,ON)
MOVEOP_DELAY = 0	
MOVEOP_AHEADMS = 0		
MOVE_OP(1,ON)		'OP1对比
MOVE(0,70)
MOVE(-100,0)
MOVE(0,-70)
MOVE(50,0)
MOVEABS(100,100)
'关胶点
MOVEOP_DELAY = 0	'
MOVEOP_AHEADMS = 100	'提前50ms打开
MOVE_OP(0,OFF)
MOVEOP_DELAY = 0	
MOVEOP_AHEADMS = 0		
MOVE_OP(1,OFF)		'OP1对比
MOVEABS(0,0)

同样设置OP1开关不做提前延后设置与OP0进行对比,可以看到OP0根据程序设置滞后100ms打开,提前100ms关闭了。

3.流程总结

四.C#编程进行运动控制项目开发

1.在VS2010菜单“文件”→“新建”→“项目”,启动创建项目向导。

2.选择开发语言为“Visual C#”和.NET Framework 4以及Windows窗体应用程序。

3.找到厂家提供的光盘资料里面的C#函数库,路径如下(32位库为例)。

(1)进入厂商提供的光盘资料找到“04PC函数”文件夹,并点击进入。

(2)选择“01PC函数库2.1”文件夹。

(3)选择“Windows平台”文件夹。

(4)选择“C#”文件夹

(5)根据需要选择对应的函数库,这里选择32位库。

4.将厂商提供的C#的库文件以及相关文件复制到新建的项目中。

(1)将zmcaux.cs文件复制到新建的项目里面中。

(2)将zauxdll.dllzmotion.dll文件放入bin\debug文件夹中。

5.双击Form1.cs里面的Form1,出现代码编辑界面,在文件开头写入using cszmcaux,并声明控制器句柄g_handle。

6.至此,项目新建完成,可进行C#项目开发。

五.相关PC函数

指令77

ZAux_Direct_MoveOp

指令原型

int32 __stdcall ZAux_Direct_MoveOp(ZMC_HANDLE handle, int iaxis, int ioutnum, int ivalue);

指令说明

把输出指定写到运动缓冲里面。

输入参数

[tr][/tr][tr][/tr][tr][/tr][tr][/tr]

参数名

描述

handle

连接标识。

iaxis

轴号。

ioutnum

IO编号。

ivalue

IO状态。

输出参数

/

返回值

成功返回值为0,非0详见错误码说明。

指令示例

例1:

ZAux_Direct_Single_Move(handle, 0, 100);//轴0正向运动100

ZAux_Direct_MoveOp(handle, 0,1, 1);//轴0正向运动100后把out1的状态置为1

例2:连续位置锁存

详细说明

这个指令LOAD执行时不做任何运动,只操作输出口。语法同OP指令。

普通模式,误差在一个扫描周期,所有控制器都可使用。精准位置输出模式,误差1微秒以内,4系列产品,20170421以上版本支持。

1.只有支持硬件比较输出的OP口才支持精准输出功能。

2.每个生效的精准输出MOVE_OP需要间隔1个周期时间才能继续生效,此间隔内新的MOVE_OP自动使用普通方式,超过此间隔,新MOVE_OP可继续生效。连续的MOVE_OP,因为没有间隔时间,只有第一个生效。(某些控制器可以多个精准输出同时触发,具体查看控制器硬件手册说明,例如ZMC420SCAN前8个输出口支持精准输出,而且每个输出口可以同时使用精准输出)

3.在控制器支持OP口独立的情况下,不同OP口就算多个轴MOVE_OP精准输出也不冲突,在OP口精准输出功能不独立的情况,同时使用精准功能可能冲突。

4.MOVE_OP精准功能基于BASE主轴,多个轴插补时,与BASE主轴ATYPE类型不一样的从轴,无法保证精准位置输出。

由于函数库未封装对应MOVEOP_ADIST / MOVEOP_AHEADMS / MOVEOP_DELAY的函数,所以需要用ZAux_DirectCommand来发送对应Basic指令。

指令265

ZAux_DirectCommand

指令原型

int32  __stdcall  ZAux_DirectCommand(ZMC_HANDLE handle, const char  *pszCommand,char  *psResponse, uint32 uiResponseLength)

指令说明

发送字符串命令到控制器,直接方式(不进缓冲区,有少数命令,暂时不支持)。

输入参数

[tr][/tr][tr][/tr][/table][tr][/tr][tr][/tr][tr][/tr]

参数名

描述

handle

连接句柄。

pszCommand

发送的命令字符串。

uiResponseLength

返回的字符长度。

输出参数

[table]

参数名

描述

uiResponseLength

返回的字符串。

返回值

成功返回值为0,非0详见错误码说明。

指令示例

在线命令函数的使用

详细说明

上位机调用上位机未封装的Basic指令功能

C#主体代码:

private void auto_move()
{
    ThreadFlag = true;
    zmcaux.ZAux_Direct_SetSpeed(g_handle, 0, Convert.ToSingle(C_AutoSpeed.Text));
    zmcaux.ZAux_Direct_SetAccel(g_handle, 0, Convert.ToSingle(C_AutoAccel.Text));
    zmcaux.ZAux_Direct_SetDecel(g_handle, 0, Convert.ToSingle(C_AutoDecel.Text));
    string cmdbuff = "AXIS_ZSET(0) = 19  ";
    UInt32 uiResponseLength = 2048;
    StringBuilder psResponse = new StringBuilder((Int32)uiResponseLength);
    Int32 iresult = zmcaux.ZAux_DirectCommand(g_handle, cmdbuff, psResponse, uiResponseLength);       //设置主轴开启精准输出模式
    zmcaux.ZAux_Direct_MoveAbs(g_handle, 2, new int[] { 0,1}, new float[] { 0, 0 });//走到零位
    while (true)
    { 
        if (checkFrameAxisIdleState() == true) break; 
    }
    zmcaux.ZAux_Trigger(g_handle);
    //相对运动走轨迹
    zmcaux.ZAux_Direct_Move(g_handle, 2, new int[] { 0, 1 }, new float[] { 0, -35});        //走到开胶点
    cmdbuff = "MOVEOP_DELAY = 0";
    iresult = zmcaux.ZAux_DirectCommand(g_handle, cmdbuff, psResponse, uiResponseLength);
    if (!ifTimeControl)        //距离控制
    {
        cmdbuff = "MOVEOP_ADIST = " + C_OpenDis.Text;
        iresult = zmcaux.ZAux_DirectCommand(g_handle, cmdbuff, psResponse, uiResponseLength);
    }
    else
    {
        if (Convert.ToSingle(C_OpenTime.Text) > 0)     //提前
        {
            cmdbuff = "MOVEOP_AHEADMS = " + C_OpenTime.Text;
            iresult = zmcaux.ZAux_DirectCommand(g_handle, cmdbuff, psResponse, uiResponseLength);
        }
        else     //滞后
        {
            string T_Value = (-Convert.ToSingle(C_OpenTime.Text)).ToString();   //moveop_delay滞后需要正值
            cmdbuff = "MOVEOP_DELAY = " + T_Value;
            iresult = zmcaux.ZAux_DirectCommand(g_handle, cmdbuff, psResponse, uiResponseLength);
        }
    }
    zmcaux.ZAux_Direct_MoveOp(g_handle, 0, 0, 1);
    //测试走点胶轨迹
    zmcaux.ZAux_Direct_Move(g_handle, 2, new int[] { 0, 1 }, new float[] { 50, 0});
    //iresult = zmcaux.ZAux_Direct_MSpherical(g_handle, virAxisList.Length, virAxisList, 0, 100, 0, 50, 50, 0, mSphericalMode, 5, 90);
    zmcaux.ZAux_Direct_Move(g_handle, 2, new int[] { 0, 1 }, new float[] { 0, 70 });
    //iresult = zmcaux.ZAux_Direct_MSpherical(g_handle, virAxisList.Length, virAxisList, 0, -100, 0, -50, -50, 0, mSphericalMode, 5, 90);
    zmcaux.ZAux_Direct_Move(g_handle, 2, new int[] { 0, 1 }, new float[] { -100, 0 });
    zmcaux.ZAux_Direct_Move(g_handle, 2, new int[] { 0, 1 }, new float[] { 0, -70});
    zmcaux.ZAux_Direct_Move(g_handle, 2, new int[] { 0, 1 }, new float[] { 50,0 });     //走到关胶点
    //zmcaux.ZAux_Direct_Move(g_handle, 2, new int[] { 0, 1 }, new float[] { 0, 35 });         //走到关胶点
    cmdbuff = "MOVEOP_DELAY = 0";
    iresult = zmcaux.ZAux_DirectCommand(g_handle, cmdbuff, psResponse, uiResponseLength);
    if (!ifTimeControl)        //距离控制
    {
        cmdbuff = "MOVEOP_ADIST = " + C_CloseDis.Text;
        iresult = zmcaux.ZAux_DirectCommand(g_handle, cmdbuff, psResponse, uiResponseLength);
    }
    else
    {
        if (Convert.ToSingle(C_CloseTime.Text) > 0)     //提前
        {
            cmdbuff = "MOVEOP_AHEADMS = " + C_CloseTime.Text;
            iresult = zmcaux.ZAux_DirectCommand(g_handle, cmdbuff, psResponse, uiResponseLength);
        }
        else     //滞后
        {
            string T_Value = (-Convert.ToSingle(C_CloseTime.Text)).ToString();   //moveop_delay滞后需要正值
            cmdbuff = "MOVEOP_DELAY = " + T_Value;
            iresult = zmcaux.ZAux_DirectCommand(g_handle, cmdbuff, psResponse, uiResponseLength);
        }
    }
    zmcaux.ZAux_Direct_MoveOp(g_handle, 0, 0, 0);
    zmcaux.ZAux_Direct_MoveAbs(g_handle, 2, new int[] { 0, 1 }, new float[] { 0, 0 });         //走到零位
}

六.效果演示

下面以C#代码跑测试和RTSys示波器抓取波形分析

1.同步输出效果:

2.距离控制提前滞后输出效果:

3.时间控制提前滞后效果:

视频讲解。

以下视频来源于
正运动小助手
已关注 关注 重播 分享

本帖子中包含更多资源

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

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

本版积分规则

上一主题上一主题         下一主题下一主题