EtherCAT超高速实时运动控制卡XPCIE1032H上位机C#开发(十四)

描述

XPCIE1032H功能简介

XPCIE1032H是一款基于PCI Express的EtherCAT总线运动控制卡,可选6-64轴运动控制,支持多路高速数字输入输出,可轻松实现多轴同步控制和高速数据传输。

XPCIE1032H集成了强大的运动控制功能,结合MotionRT7运动控制实时软核,解决了高速高精应用中,PC Windows开发的非实时痛点,指令交互速度比传统的PCI/PCIe快10倍。

XPCIE1032H支持PWM,PSO功能,板载16进16出通用IO口,其中输出口全部为高速输出口,可配置为4路PWM输出口或者16路高速PSO硬件比较输出口。输入口含有8路高速输入口,可配置为4路高速色标锁存或两路编码器输入。

XPCIE1032H搭配MotionRT7实时内核,使用本地LOCAL接口连接,通过高速的核内交互,可以做到更快速的指令交互,单条指令与多条指令一次性交互时间可以达到3-5us左右。

PWM输出

➜XPCIE1032H与MotionRT7实时内核的配合具有以下优势:

PWM输出

1.支持多种上位机语言开发,所有系列产品均可调用同一套API函数库;

2.借助核内交互,可以快速调用运动指令,响应时间快至微秒级,比传统PCI/PCIe快10倍;

3.解决传统PCI/PCIe运动控制卡在Windows环境下控制系统的非实时性问题;

4.支持一维/二维/三维PSO(高速硬件位置比较输出),适用于视觉飞拍、精密点胶和激光能量控制等应用;

5.提供高速输入接口,便于实现位置锁存;

6.支持EtherCAT总线和脉冲输出混合联动、混合插补。

➜使用XPCIE1032H和MotionRT7进行项目开发时,通常需要进行以下步骤:

1.安装驱动程序,识别XPCIE1032H;

2.打开并执行文件“MotionRT710.exe”,配置参数和运行运动控制实时内核;

3.使用ZDevelop软件连接到控制器,进行参数监控。连接时请使用PCI/LOCAL方式,并确保ZDevelop软件版本在3.10以上;

4.完成控制程序开发,通过LOCAL链接方式连接到运动控制卡,实现实时运动控制。

➜与传统PCI/PCIe卡和PLC的测试数据结果对比:

PWM输出

我们可以从测试对比结果看出,XPCIE1032H运动控制卡配合实时运动控制内核MotionRT7,在LOCAL链接(核内交互)的方式下,指令交互的效率是非常稳定,当测试数量从1w增加到10w时,单条指令交互时间与多条指令交互时间波动不大,非常适用于高速高精的应用。

XPCIE1032H控制卡安装

关闭计算机电源。

打开计算机机箱,选择一条空闲的XPCIE卡槽,用螺丝刀卸下相应的挡板条。

将运动控制卡插入该槽,拧紧挡板条上的固定螺丝。

一、C#语言进行运动控制项目开发

PWM输出

1.解压下载的安装包找到“ Zmcaux.cs ”,“ zauxdll.dll ”,“ zmotion.dll ”放入到项目文件中。

(1)“Zmcaux.cs”放在项目根目录文件中,与bin目录同级。

PWM输出

(2)“zauxdll.dll”,“zmotion.dll”放在bin → Debug。

PWM输出

2.用vs打开新建的项目文件,在右边的解决方案资源管理器中点击显示所有,然后鼠标右键点击zmcaux.cs文件,点击包括在项目中。

PWM输出

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

PWM输出

PWM输出

二、PC函数介绍

PC函数手册也在光盘资料里面,具体路径如下:“光盘资料8.PC函数函数库2.1Motion函数库编程手册 V2.1.pdf”。

PWM输出

指令11 ZAux_FastOpen
指令原型 int32  __stdcall  ZAux_FastOpen(int type, char *pconnectstring, uint32 uims ,ZMC_HANDLE * phandle)
指令说明 与控制器建立连接, 可以指定连接的等待时间
输入参数
参数名 描述
type 连接类型
type: 1-COM 2-ETH 4-PCI 5-LOCAL
pconnectstring 连接字符串:
COM口号/IP地址
uims 连接超时时间 uims;单位ms
输出参数
参数名 描述
phandle 控制器连接句柄
返回值 成功返回值为0,非0详见错误码说明。
指令示例 串口连接:
ZMC_HANDLE  phandle;//控制器连接句柄
Char comID[32]= "0";//串口ID
ZAux_FastOpen(1, comID,1000 ,&phandle);
网口连接例子:
ZMC_HANDLE  phandle;//控制器连接句柄
Char EthID[32]= "192.168.0.11";//网口ID
ZAux_FastOpen(2, EthID,1000 ,&phandle);
LOCAL接口连接例子:
ZMC_HANDLE  phandle;//控制器连接句柄
ZAux_FastOpen(5, "LOCAL1",1000,&phandle);
详细说明 type 设置为 5,zmotion.dll 版本要在 3.8.8.50 以上。
指令8 ZAux_Direct_CycleRegist
指令原型 int32 __stdcall ZAux_Direct_CycleRegist(ZMC_HANDLE handle,int iaxis, int imode,int iTabStart,int iTabNum)
指令说明 位置连续锁存。
输入参数
参数名 描述
handle 连接标识。
iaxis 轴号。
imode
描述
101 当Z脉冲上升沿时的绝对位置送到RegPos
102 当Z脉冲下降沿时的绝对位置送到RegPos
103 当输入信号R0上升沿的绝对位置送到RegPos
104 当输入信号R0下降沿的绝对位置送到RegPos
114 输入信号R1上升沿时的绝对位置送到RegPosB
115 输入信号R1下降沿时的绝对位置送到RegPosB
116 Z信号上升沿时的绝对位置送到RegPosB
117 Z信号下降沿时的绝对位置送到RegPosB
123 当输入信号R0上升沿的绝对位置送到RegPosB
124 当输入信号R0下降沿的绝对位置送到RegPosB
133 当输入信号R0上升沿的绝对位置送到RegPos,下一次切换下降沿,轮流切换。
134 当输入信号R0下降沿的绝对位置送到RegPos,下一次切换上升沿,轮流切换。
135 当输入信号R1上升沿的绝对位置送到RegPosB,下一次切换下降沿,轮流切换。下一次切换下降沿,轮流切换。
136 当输入信号R1下降沿的绝对位置送到RegPosB,下一次切换上升沿,轮流切换。
iTabStart 连续锁存的内容存储的table位置,第一个table元素存储锁存的个数,后面存储锁存的坐标,最多保存个数= numes-1,溢出时循环写入
iTabNum 占用的table个数
输出参数 /
返回值 成功返回值为0,非0详见错误码说明。
指令示例 连续位置锁存
详细说明 锁存结果存储到TABLE里面。
分别对两个通道进行连续锁存,可以实现上下边沿的连续锁存。
ECI:20150829以上固件支持。
4系列控制器:20170523以上固件支持。
指令27 ZAux_Direct_MoveSync
指令原型 int32 __stdcall ZAux_Direct_MoveSync(ZMC_HANDLE handle,float  imode,int synctime, float syncposition, int syncaxis, int imaxaxises, int *piAxislist, float *pfDisancelist)
指令说明 同步运动,皮带上物体跟随,此运动非插补运动,不保证运动轨迹为直线。
输入参数
参数名 描述
handle 连接标识。
imode 同步模式:
imode =-1:结束模式,运动到指定的绝对位置, 此模式运动如果后面紧接着其它ZAux_Direct_MoveSync指令,会被覆盖, 此模式下皮带轴无效。
imode =-2:强制结束,调用时强制停止原来的ZAux_Direct_MoveSync,运动到指定结束位置,此模式运动如果后面紧接着其它ZAux_Direct_MoveSync指令,会被覆盖, 此模式下皮带轴无效。
imode =-10: 跟随轴轴列表第一个轴跟随
imode =-20: 跟随轴轴列表第二个轴跟随
imode =-30: 跟随轴轴列表第二个轴跟随
imode =0+angle:
皮带旋转角度。angle:皮带旋转角度,角度 = 皮带与跟随轴轴列表第1/2轴的正向旋转夹角。例如imode = PI/4,皮带在45度的方向;imode =PI/2,皮带在y方向;imode =PI,皮带在x负向;imode =(PI*1.75),皮带在-45度的方向
imode=1000+tableindex,  轴号列表的跟踪比例依次存储table里面, 这样可以实现三维的皮带跟踪, 当皮带有倾斜的时候.( 固件版本20180209增加此功能)( tableindex:table寄存器起始编号)
synctime 同步时间,ms单位.运动在指定时间内完成,完成时轴跟皮带轴上物体保持速度一致。0表示根据运动轴的速度加速度来估计同步时间,可能不准确
syncposition 皮带轴物体被感应到时皮带轴的位置。此指令支持皮带轴坐标循环,但是在指令被调用时确保此参数位置和当前皮带轴位置之间没有发生坐标修改或循环操作,因此此指令调用时不要在坐标循环点附近
syncaxis 皮带轴轴号
imaxaxises 参与同步从轴总数
piAxislist 跟随轴轴号列表
pfDisancelist 皮带轴物体被感应到时从轴的绝对坐标位置
输出参数 /
返回值 成功返回值为0,非0详见错误码说明。
指令示例 皮带轴同步运动跟随
详细说明1 Imode:同步模式
指令228 ZAux_Direct_GetTable
指令原型 int32 __stdcall ZAux_Direct_GetTable(ZMC_HANDLE handle, int tabstart, int numes, float *pfValue)
指令说明 读取TABLE中的数据。
输入参数
参数名 描述
handle 连接句柄。
tabstart 读取Table寄存器的起始编号
numes 读的个数
输出参数
参数名 描述
pfValue 数据列表
返回值 成功返回值为0,非0详见错误码说明。
指令示例 Table寄存器的使用
详细说明 是控制器自带的一个超大数组,数据类型为32位浮点型(4系列及以上为64位浮点数),掉电不保存。

三、同步跟随运动介绍

同步跟随运动 -- MOVESYNC

此运动可以简拆成两部分组成(同步+跟随),整个过程由同步和跟随组成;

同步过程:是实现追上目标并获得和目标同样的运动速度;

跟随过程:是在同步过程完成后与产品保持相对静止运动的过程,在此过程中可以引用其他运动动作,以实现点胶、分拣等工艺动作。

同步跟随运动的重点说明

1.同步+跟随的过程一般分为3段:加速段(同步过程)、同步段(跟随过程)、减速段(复位过程);

2.加速时间:作用于同步过程,指示同步要在运动触发后多久完成,单位MS;

3.匀速时间:作用于跟随过程,指示在同步运动结束后,跟随过程持续时间,单位MS,此处需要注意与加工动作耗时的搭配;如果跟随时间小于加工时间,则可能出现部分加工过程不在跟随过程完成(轨迹会出现偏差);

4.减速时间:作用于减速度,指示加工完成回到指定位置等待下一次触发过程的归位时间,单位MS。

四、例程说明

1.C#例程界面如下。

PWM输出

2.例程实现逻辑解读简图。

PWM输出

3.在Form1的构造函数中调用接口ZAux_FastOpen(),使在系统初始化的时候自动链接控制器。

 

//LOCAL 链接
private void button4_Click(object sender, EventArgs e)
{
    if (G_CardHandle == (IntPtr)0)
    {
        btn_Close_Click(sender, e);
    }
    zmcaux.ZAux_FastOpen(5, comboBox1.Text, 1000, out G_CardHandle);
    if (G_CardHandle != (IntPtr)0)
    {
        this.Text = "已链接";
        timer1.Enabled = true;
    }
    else
    {
        MessageBox.Show("链接失败,请选择正确的LOCAL!");
    }
}
4.定时器运行获取锁存位置信息。
private void timer2_Tick(object sender, EventArgs e)
{
    int iret = 0;
    float[] MarkNum = new float[2];
    float[] RegistPos = new float[1000];
    iret = zmcaux.ZAux_Direct_GetTable(G_CardHandle, Convert.ToInt32(Text_TabStart.Text), 1, MarkNum);        //获取锁存触发次数
    m_RegistCount = (int)MarkNum[0];
    this.DataGridView2.Rows[0].Cells[1].Value = m_RegistCount.ToString();
    //显示到列表
    if (m_RegistCount > m_RegistShow)                   //锁存数量大于显示
    {
        int iNum = m_RegistCount - m_RegistShow;
        iret = zmcaux.ZAux_Direct_GetTable(G_CardHandle, Convert.ToInt32(Text_TabStart.Text) + 1 + m_RegistShow, iNum, RegistPos);        //获取锁存触发次数
        for (int i = 0; i < iNum; i++)
        {
            this.DataGridView2.Rows[m_RegistShow + i + 1].Cells[1].Value = RegistPos[i].ToString();
        }
        m_RegistShow = m_RegistCount;
    }
    else if (m_RegistCount < m_RegistShow)                             //锁存循环溢出
    {
        int iNum = Convert.ToInt32(Text_TabNum.Text) - m_RegistShow - 1;
        iret = zmcaux.ZAux_Direct_GetTable(G_CardHandle, Convert.ToInt32(Text_TabStart.Text) + 1 + m_RegistShow, iNum, RegistPos);        //获取锁存触发次数
        for (int i = 0; i < iNum; i++)
        {
            this.DataGridView2.Rows[m_RegistShow + i + 1].Cells[1].Value = RegistPos[i].ToString();
        }
        m_RegistShow = 0;
    }
}
5.同步跟随线程触发并执行同步跟随动作。
public void SubMoveSync()
{
    int iret = 0;
    int[] iAxisList = new int[2] { 0, 1 };
    int[] iTime = new int[3];
    iTime[0] = Convert.ToInt32(TextAccTime.Text);
    iTime[1] = Convert.ToInt32(TextSyncTime.Text);
    iTime[2] = Convert.ToInt32(TextBackTime.Text);
    float[] fWaitPos = new float[2];
    fWaitPos[0] = Convert.ToSingle(TextXpos.Text);
    fWaitPos[1] = Convert.ToSingle(TextYpos.Text);
    float fOffPos = Convert.ToSingle(TextOffpos.Text);
    float fPdAxisPos = 0;       //当前皮带轴位置
    float[] fMakrPos = new float[2];          //当前加工产品锁存编码器的位置
    int iMaxNum = Convert.ToInt32(Text_TabNum.Text);
    float imode = 0;
    if (radioBtnX.Checked)
    {
        imode = 0 + (float)(Convert.ToSingle(TextAngle.Text) / 180.0 * Math.PI);        //X方向跟随
    }
    else
    {
        imode = 10 + (float)(Convert.ToSingle(TextAngle.Text) / 180.0 * Math.PI);       //Y方向跟随  
    }
    while (true)
    {
        if ((m_RegistCount != 0) && (iWorkCount < iMaxNum))              //锁存 已经触发加工数量小于总锁存数
        {
            iret = zmcaux.ZAux_Direct_GetTable(G_CardHandle, Convert.ToInt32(Text_TabStart.Text) + 1 + iWorkCount, 1, fMakrPos);    //获取当前准备加工的锁存位置
        }
        else if (iWorkCount > iMaxNum)    //锁存坐标已经溢出,数据保存在锁存前面
        {
            iWorkCount = iWorkCount - m_RegistCount;        //从下个循环开始取值
            if (iWorkCount < m_RegistCount)
            {
                iret = zmcaux.ZAux_Direct_GetTable(G_CardHandle, Convert.ToInt32(Text_TabStart.Text) + 1 + iWorkCount, 1, fMakrPos);    //获取当前准备加工的锁存位置
            }
            else
            {
                continue;
            }
        }
        //锁存事件未触发
        if (m_RegistCount == 0 || m_RegistCount == iWorkCount)
        {
            continue;
        }
        //等待传送带位置运动超过开始跟随位置
        do
        {
            iret = zmcaux.ZAux_Direct_GetMpos(G_CardHandle, 2, ref fPdAxisPos);            //获取当前编码轴位置
        } while (fPdAxisPos < fOffPos + fMakrPos[0]);
        iret = zmcaux.ZAux_Direct_MoveSync(G_CardHandle, imode, iTime[0], fMakrPos[0] + fOffPos, 2, 2, iAxisList, fWaitPos);      //同步启动加速段,
        iret = zmcaux.ZAux_Direct_MoveSync(G_CardHandle, imode, iTime[1], fMakrPos[0] + fOffPos, 2, 2, iAxisList, fWaitPos);      //同步启动匀速速段,匀速时间
        iret = zmcaux.ZAux_Direct_MoveSync(G_CardHandle, imode, iTime[2], 0, -1, 2, iAxisList, fWaitPos);      //结束同步走到待机位置
        int Axisidle = 0;
        do
        {
            iret = zmcaux.ZAux_Direct_GetIfIdle(G_CardHandle, iAxisList[0], ref Axisidle);            //等待主轴跟随完毕
        } while (Axisidle == 0);
        iWorkCount++;
    }
}
五、调试与运行

1.用X方向跟随(Y方向同理),输入X方向跟随参数。

 

PWM输出

如下图,锁存通过输入0号触发,触发多次,将数据提供给同步跟随并触发同步跟随波形,波形图中,X跟随轴在前5S内实现同步后,与皮带轴在2S内保持相同速度相对运行,跟随结束后在5S内归位完成。

PWM输出

PWM输出



 

审核编辑:刘清

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分