精华内容
下载资源
问答
  • 2018-06-14 10:50:16

    转载连接: https://blog.csdn.net/liubing8609/article/details/78884424










    更多相关内容
  • 汇川IMC30G-E系列运动控制卡(器)软件编程手册
  • 运动控制卡编程

    热门讨论 2012-11-03 09:46:57
    运动控制卡编程源代码
  • 最全的运动控制教程.rar
  • 第 2 章 运动控制器函数库的使用 15 © 1999-2019 固高科技版权所有 (3) 选择“Project”菜单下的“Settings…”菜单项; (4) 切换到“Link”标签页,在“Object\library modules”栏中输入lib文件名,例如gts.lib;...
  • 凌华运动控制卡资料,有相关的C#,VB,Labview的编程Demo
  • PC+运动控制卡 编程示例

    热门讨论 2010-10-27 10:30:48
    运动控制编程的经典参考例子!很新的!有详细的程序!
  • 本手册描述了固高运动卡所有的底层函数,用于编制控制运动控制卡的程序,适用于基础和具有一定开发经验的开发者 本手册描述了固高运动卡所有的底层函数,用于编制控制运动控制卡的程序,适用于基础和具有一定开发...
  • C#编程基础及在运动控制卡上的应用,PDF文档,雷赛运动控制卡+C#,厂家提供的文档,大家可以参考下,有机会把DEMO程序发上来.
  • 运动控制卡应用开发教程之C#

    千次阅读 2021-06-03 16:50:15
    在正式学习之前,我们先了解一下正运动技术的运动控制卡ECI2418和ECI2618。这两款产品分别是4轴,6轴运动控制卡。 ECI2418支持4轴脉冲输入与编码器反馈,板载24点输入,16点输出,2AD,2DA,支持手轮接口,其中...

    今天,正运动小助手为大家分享一下应用C#开发一个多段连续插补的运动控制应用。

    我们主要从新建项目,添加函数库讲起,再了解PC函数使用,最后通过项目实战——连续插补运动例程讲解,来让大家熟悉它的项目开发。

    在正式学习之前,我们先了解一下正运动技术的运动控制卡ECI2418和ECI2618。这两款产品分别是4轴,6轴运动控制卡。

    在这里插入图片描述

    ECI2418支持4轴脉冲输入与编码器反馈,板载24点输入,16点输出,2AD,2DA,支持手轮接口,其中特定输出口支持高速PWM控制。

    2.jpg

    ECI2618支持6轴脉冲输入与编码器反馈,板载24点输入,16点输出,2AD,2DA,支持手轮接口,其中特定输出口支持高速PWM控制。

    3.jpg

    ECI2418,ECI2618均使用同一套API函数,均支持C、C++、C#、LabVIEW、Python、Delphi等开发语言,支持VC6.0、VB6.0、Qt、.Net等平台,支持Windows、Linux、WinCE、iMac等操作系统。

    以下是C#

    开发流程

    01 新建MFC项目,添加函数库。

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

    4.jpg

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

    5.jpg

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

    1)进入光盘资料找到PC函数文件夹。

    6.jpg

    2)选择函数库2.1。

    7.jpg

    3)Windows平台。

    8.jpg

    4)根据需要选择对应的函数库这里选择64位库。

    9.jpg

    5)解压C++的压缩包,里面有C#对应的函数库。

    10.jpg

    6)函数库具体路径如下图所示。

    11.jpg

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

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

    12.jpg

    2)将zaux.dll和zmotion.dll文件放入bin\debug文件夹中。

    13.jpg

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

    14.jpg

    15.jpg

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

    16.jpg

    至此项目新建完成。

    02 查看PC函数手册,了解其用法。

    1.PC函数手册也在光盘资料里面,具体路径如下。

    17.jpg

    2.PC编程,一般先根据控制器连接方式选择对应的连接函数连接控制器,返回控制器句柄。接着用返回的控制器句柄,实现对控制器的控制。

    3.比如通过网口连接控制器,先使用ZAux_OpenEth()链接控制器,获取控制器句柄handle。

    18.jpg

    19.jpg

    项目应用截图

    4.通过获取到的控制器句柄handle,对控制器进行单轴运动控制。

    20.jpg

    5.通过获取到的控制器句柄handle,进行多轴绝对插补运动。

    21.jpg

    int[] axislist = { 0, 1, 2, 3 }; //轴列表

    float[] destdis = { 100, 100, 200, 100 }; //运动距离列表

    zmcaux.ZAux_Direct_MoveAbs(g_handle, 4, axislist, destdis);

    6.通过获取到的控制器句柄handle,获取控制器缓冲区剩余的缓冲数量。

    23.jpg

    03 项目实战之连续插补运动例程讲解。

    1.例程以建立板卡的连接,执行4段连续轨迹的加工为目标。

    24.jpg

    2.例程简易流程图。

    25.jpg

    3.通过网口方式连接控制器,获取控制器连接句柄。

    //连接控制器
    
      private void button_link_Click(object sender, EventArgs e)
    
      {
    
              if (g_handle != (IntPtr)0)
    
              {
    
                  zmcaux.ZAux_Close(g_handle);//断开连接
    
                  g_handle = (IntPtr)0;
    
          }
    
          zmcaux.ZAux_OpenEth(comboBox_IpList.Text, out g_handle);//连接控制器
    
          if (g_handle != (IntPtr)0)
    
          {
    
              this.Text = "已连接";
    
              timer1.Enabled = true;
    
              //初始化轴参数
    
              for (int i = 0; i < 4; i++)
    
              {
    
                  zmcaux.ZAux_Direct_SetAtype(g_handle, i, 1);//轴类型 脉冲轴
    
                  zmcaux.ZAux_Direct_SetUnits(g_handle, i, 1);//脉冲当量
    
              }
    
          }
    
          else
    
          {
    
              MessageBox.Show("控制器链接失败,请检测IP地址!", "警告");
    
          }
    
      }
    
      
    
      4.通过定时器1更新控制器轴0-3的位置和速度等信息。
    
      
    
      //定时器刷新
    
      private void timer1_Tick(object sender, EventArgs e)
    
      {
    
          int runstate = 0;
    
          float[] curpos = new float[4];
    
          float vspeed = 0;
    
          int remin_buff = 0;
    
          int curmark = 0;
    
          //获取轴位置
    
          for (int i = 0; i < 4; i++)
    
          {
    
              zmcaux.ZAux_Direct_GetDpos(g_handle, i, ref curpos[i]);
    
          }
    
          //获取轴运动状态
    
          zmcaux.ZAux_Direct_GetIfIdle(g_handle, 0, ref runstate);
    
          //获取插补运动合速度
    
          zmcaux.ZAux_Direct_GetVpSpeed(g_handle, 0, ref vspeed);
    
          //判断存放直线的剩余缓冲
    
          zmcaux.ZAux_Direct_GetRemain_LineBuffer(g_handle, 0, ref remin_buff);
    
          //判断当前运动到第几条运动,
    
          zmcaux.ZAux_Direct_GetMoveCurmark(g_handle, 0, ref curmark);
    
    
          label_pos.Text = "X:" + curpos[0] + " Y:" + curpos[1] + " Z:" + curpos[2] + " U:" + curpos[3];
    
          label_state.Text = Convert.ToString(runstate == 0 ? " 运行状态:运行中" : " 运行状态:停止中");
    
          label_vspeed.Text = "当前速度:" + vspeed;
    
          label_buff.Text = "剩余缓冲:" + remin_buff;
    
          label_mark.Text = "当前MARK:" + curmark;
    
      }
    

    5.通过启动按钮的事件处理函数来启动插补运动

    //启动按钮
    
      private void button_start_Click(object sender, EventArgs e)
    
      {
    
              int[] axislist = { 0, 1, 2, 3 }; //轴列表
    
              float[] destdis = { 0, 0, 0, 0 }; //运动距离列表
    
              int corner_mode = 0; //拐角模式
    
              int merge_flag = 0; //连续插补
    
              int iresult = 0; //PC函数返回值
    
              int remin_buff = 0; //剩余直线缓冲数
    
              if (checkBox1.Checked)
    
              {
    
                  corner_mode = corner_mode + 2;
    
              }
    
              if(checkBox2.Checked)
    
              {
    
                  corner_mode = corner_mode + 8;
    
              }
    
              if(checkBox3.Checked)
    
      {
    
                  corner_mode = corner_mode + 32;
    
              }
    
              if (checkBox4.Checked)
    
              {
    
                  merge_flag = 1;
    
              }
    
              //设置插补速度
    
              zmcaux.ZAux_Direct_SetSpeed(g_handle, axislist[0], Convert.ToSingle(textBox_sp.Text));
    
              //设置插补加速度
    
              zmcaux.ZAux_Direct_SetAccel(g_handle, axislist[0], Convert.ToSingle(textBox_acc.Text));
    
              //设置插补减速度
    
              zmcaux.ZAux_Direct_SetDecel(g_handle, axislist[0], Convert.ToSingle(textBox_dec.Text));
    
              //设置连续插补
    
              zmcaux.ZAux_Direct_SetMerge(g_handle, axislist[0], merge_flag);
    
              //S曲线时间
    
              zmcaux.ZAux_Direct_SetSramp(g_handle, axislist[0], Convert.ToSingle(SRAMP.Text));
    
              //设置SP速度
    
              zmcaux.ZAux_Direct_SetForceSpeed(g_handle, axislist[0], Convert.ToSingle(textBox_for_sp.Text));
    
              //设置拐角模式
    
              zmcaux.ZAux_Direct_SetCornerMode(g_handle, axislist[0], corner_mode);
    
              //开始减速角度,转换为弧度
    
              zmcaux.ZAux_Direct_SetDecelAngle(g_handle, axislist[0], (float)(Convert.ToSingle(textBox_ang1.Text) * 3.14 / 180));
    
              //停止减速角度,转换为弧度
    
              zmcaux.ZAux_Direct_SetStopAngle(g_handle, axislist[0], (float)(Convert.ToSingle(textBox_ang2.Text) * 3.14 / 180));
    
              //小圆半径
    
              zmcaux.ZAux_Direct_SetFullSpRadius(g_handle, axislist[0], Convert.ToSingle(textBox_radio.Text));
    
              //倒角
    
              zmcaux.ZAux_Direct_SetZsmooth(g_handle, axislist[0], Convert.ToSingle(textBox_zsmooth.Text));
    
              //设置MARK = 0 ,来通过读取CURMARK实现判断当前执行到那里
    
              zmcaux.ZAux_Direct_SetMovemark(g_handle, axislist[0], 0);
    
              //选择base轴
    
              zmcaux.ZAux_Direct_Base(g_handle, 4, axislist);
    
              zmcaux.ZAux_Trigger(g_handle);
    
              //计算剩余直线缓冲数量
    
              zmcaux.ZAux_Direct_GetRemain_LineBuffer(g_handle, 0, ref remin_buff);
    
              while(remin_buff<4)
    
              {
    
                  zmcaux.ZAux_Direct_GetRemain_LineBuffer(g_handle, 0, ref remin_buff);
    
                  System.Threading.Thread.Sleep(1); //1毫秒
    
              }
    
              //第一段插补运动
    
              destdis[0] = Convert.ToSingle(destdis1_X.Text);
    
              destdis[1] = Convert.ToSingle(destdis1_Y.Text);
    
              destdis[2] = Convert.ToSingle(destdis1_Z.Text);
    
              destdis[3] = Convert.ToSingle(destdis1_U.Text);
    
              iresult = zmcaux.ZAux_Direct_MoveAbs(g_handle, 4, axislist, destdis);//4轴插补指令
    
              //函数返回非0 则表示发送不成功,缓冲区可能满了,重新发送
    
              while (iresult != 0)
    
              {
    
                  iresult = zmcaux.ZAux_Direct_MoveAbs(g_handle, 4, axislist, destdis);
    
                  System.Threading.Thread.Sleep(1); //1毫秒
    
              }
    
              //第二段插补运动
    
              destdis[0] = Convert.ToSingle(destdis2_X.Text);
    
              destdis[1] = Convert.ToSingle(destdis2_Y.Text);
    
              destdis[2] = Convert.ToSingle(destdis2_Z.Text);
    
              destdis[3] = Convert.ToSingle(destdis2_U.Text);
    
              iresult = zmcaux.ZAux_Direct_MoveAbs(g_handle, 4, axislist, destdis);//4轴插补指令
    
              //函数返回非0 则表示发送不成功,缓冲区可能满了,重新发送
    
      while (iresult != 0)
    
              {
    
                  iresult = zmcaux.ZAux_Direct_MoveAbs(g_handle, 4, axislist, destdis);
    
                  System.Threading.Thread.Sleep(1); //1毫秒
    
              }
    
              //第三段插补运动
    
              destdis[0] = Convert.ToSingle(destdis3_X.Text);
    
              destdis[1] = Convert.ToSingle(destdis3_Y.Text);
    
              destdis[2] = Convert.ToSingle(destdis3_Z.Text);
    
              destdis[3] = Convert.ToSingle(destdis3_U.Text);
    
              iresult = zmcaux.ZAux_Direct_MoveAbs(g_handle, 4, axislist, destdis);//4轴插补指令
    
              //函数返回非0 则表示发送不成功,缓冲区可能满了,重新发送
    
              while (iresult != 0)
    
              {
    
                  iresult = zmcaux.ZAux_Direct_MoveAbs(g_handle, 4, axislist, destdis);
    
                  System.Threading.Thread.Sleep(1); //1毫秒
    
              }
    
              //第四段插补运动
    
              destdis[0] = Convert.ToSingle(destdis4_X.Text);
    
              destdis[1] = Convert.ToSingle(destdis4_Y.Text);
    
              destdis[2] = Convert.ToSingle(destdis4_Z.Text);
    
              destdis[3] = Convert.ToSingle(destdis4_U.Text);
    
              iresult = zmcaux.ZAux_Direct_MoveAbs(g_handle, 4, axislist, destdis);//4轴插补指令
    
              //函数返回非0 则表示发送不成功,缓冲区可能满了,重新发送
    
              while (iresult != 0)
    
              {
    
                  iresult = zmcaux.ZAux_Direct_MoveAbs(g_handle, 4, axislist, destdis);
    
                  System.Threading.Thread.Sleep(1); //1毫秒
    
              }
    
          }
    

    6.通过停止按钮的事件处理函数来停止插补运动。

    //停止运动
    
      private void button_stop_Click(object sender, EventArgs e)
    
      {
    
              //取消主轴运动
    
              zmcaux.ZAux_Direct_Single_Cancel(g_handle, 0, 2);
    
      }
    

    7.轴坐标清零。

    //坐标清零
    
      private void button_zero_Click(object sender, EventArgs e)
    
      {
    
              if (g_handle == (IntPtr)0)
    
              {
    
                  MessageBox.Show("未链接到控制器!", "提示");
    
              }
    
              else
    
              {
    
              for (int i = 0; i < 4; i++)
    
              {
    
              zmcaux.ZAux_Direct_SetDpos(g_handle, i, 0);
    
              }
    
          }
    
      }
    

    8. 编译运行演示。

    编译运行示教例程,同时通过ZDevelop软件连接控制器,对运动控制的轴参数进行监控。

    9.连续插补加自动倒角的位置波形。

    26.jpg

    10.不开启连续插补的速度波形。

    27.jpg

    28.jpg

    29.jpg

    11.连续插补加合适的拐角减速的速度波形。

    30.jpg

    31.jpg

    正运动技术《运动控制卡应用开发教程之C#》就讲到这里。更多学习视频及图文,请关注我们的公众号“正运动小助手”。
      
      更多精彩内容请关注“正运动小助手”公众号,需要相关开发环境与例程代码,请咨询正运动技术销售工程师:400-089-8936。

    本文由正运动小助手原创,欢迎大家转载,共同学习,一起提高中国智能制造水平。文章版权归正运动技术所有,如有转载请注明文章来源。

    在这里插入图片描述

    展开全文
  • 今天正运动技术与大家分享一下运动控制卡应用开发教程之Python。 一 、ECI2828硬件介绍 ECI2828系列运动控制卡支持多达16轴直线插补、任意圆弧插补、空间圆弧、螺旋插补、电子凸轮、电子齿轮、同步跟随、虚拟轴和...

    众所周知,Python作为一门面向对象的新兴开发语言,具有非常完善的基础代码库,更注重实用,同时代码可读极强,编写完程序即可直接运行,被越来越多的人广泛将它用于机器视觉和自动化控制。

    今天正运动技术与大家分享一下运动控制卡应用开发教程之Python。

    一 、ECI2828硬件介绍

    ECI2828系列运动控制卡支持多达16轴直线插补、任意圆弧插补、空间圆弧、螺旋插补、电子凸轮、电子齿轮、同步跟随、虚拟轴和机械手指令等;采用优化的网络通讯协议可以实现实时的运动控制。

    ECI2828系列运动运动控制卡支持以太网,232 通讯接口和电脑相连,接收电脑的指令运行,可以通过EtherCAT总线和CAN总线去连接各个扩展模块,从而扩展输入输出点数或运动轴。

    1.jpg

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

    2.jpg

    二 、Python语言开发流程

    Python语言的使用环境:

    操作系统环境:win7_64x

    Python开发运行环境:PyCharm2019.2

    Python解释器版本:Python 3.7.4(32bit)

    1、新建项目。

    打开Pycharm软件进行操作,点击Create New Project新建项目。

    3.jpg

    2、设置Python项目存放路径。

    选择Python项目→选择Python项目将存放的路径→创建Python项目。

    4.jpg

    3、新建Python文件。

    在Python项目中新建Python文件,右键CratPython文件夹,选择“New→PythonFile”,创建新的Python 文件。

    5.jpg

    4、将Python动态库复制到Python项目中。

    6.jpg

    5、模块导入并加载动态链接库。

    首先把Python中的两个模块导入(platform和ctypes模块),其中ctypes模块提供和C语言兼容的数据类型,能够很方便地调用动态链接库中输出的C接口函数。

              import platform
    
              import ctypes
    
              import os
    
              #运行环境判断
    
              systype = platform.system()
    
              if systype == 'Windows':
    
              if platform.architecture()[0] == '64bit':
    
              zauxdll = ctypes.WinDLL('./zauxdll64.dll')
    
              print('Windows x64')
    
              else:
    
              zauxdll = ctypes.WinDLL('./zauxdll.dll')
    
              print('Windows x86')
    
              elif systype == 'Darwin':
    
              zmcdll = ctypes.CDLL('./zmotion.dylib')
    
              print("macOS")
    
              elif systype == 'Linux':
    
              zmcdll = ctypes.CDLL('./libzmotion.so')
    
              print("Linux")
    
              else:
    
              print("Not Supported!!")
    

    6、通过加载导入的动态库链接库,调用ZMotion PC函数手册中的函数。

    1)使用操作。

    首先根据控制器连接方式用连接函数连接控制器,输出控制器句柄,利用控制器的句柄我们就可以对库函数进行操作。

    即“打开PC函数手册→搜索想要的函数功能→查看函数说明→通过刚才加载的动态链接库返回的zauxdll对象进行调用”。

    7.jpg

    2)通过ip连接函数接口返回的控制器句柄handle,对控制器的句柄handle操作。

    8.jpg

              
    
            #####控制器连接#####
    
                def connect(self, ip, console=[]):
    
                    if self.handle.value is not None:
    
                        self.disconnect()
    
                    ip_bytes = ip.encode('utf-8')
    
                    p_ip = ctypes.c_char_p(ip_bytes)
    
                    print("Connecting to", ip, "...")
    
                    ret = zauxdll.ZAux_OpenEth(p_ip, ctypes.pointer(self.handle))
    
                    msg = "Connected"
    
                    if ret == 0:
    
                        msg = ip + " Connected"
    
                        self.sys_ip = ip
    
                        self.is_connected = True
    
                    else:
    
                        msg = "Connection Failed, Error " + str(ret)
    
                        self.is_connected = False
    
                    console.append(msg)
    
                    console.append(self.sys_info)
    
                    return ret
    
            
    
                # 断开连接
    
                def disconnect(self):
    
                    ret = zauxdll.ZAux_Close(self.handle)
    
                    self.is_connected = False
    
                    return ret
    

    3)我们会提供EtherCAT总线初始化的basic代码,可以通过指令ZAux_BasDown()将总线初始化的basic代码下载到控制器中,从而实现EtherCAT总线轴的初始化。

    9.jpg

            ********************ECAT总线初始化****************
    
            global CONST BUS_TYPE = 0           '总线类型。
    
            global CONST MAX_AXISNUM = 16       '最大轴数
    
            global CONST Bus_Slot  = 0          '槽位号0
    
            global CONST Bus_AxisStart   = 0    '总线轴起始轴号
    
            
    
            global Bus_InitStatus               '总线初始化完成状态
    
            Bus_InitStatus = -1
    
            global  Bus_TotalAxisnum            '检查扫描的总轴数
    
            delay(3000)                         '延时3S等待驱动器上电
    
            Ecat_Init()
    
            end
    
            
    
            global sub Ecat_Init()
    
               '初始化还原轴类型
    
               for i=0 to MAX_AXISNUM - 1              
    
                  AXIS_ENABLE(i) = 0
    
                  ATYPE(i)=0  
    
               next
    
                  '扫描总线  
    
                  Bus_InitStatus = -1
    
                  Bus_TotalAxisnum = 0  
    
                  SLOT_STOP(Bus_Slot)
    
                  DELAY(200)
    
                  SLOT_SCAN(Bus_Slot)
    
                  '如果扫描成功                      
    
                  if return then      
    
                     ?"总线扫描成功","连接设备数:"NODE_COUNT(Bus_Slot)    
    
                     ?"开始映射轴号"
    
                     '遍历总线下所有从站节点
    
                     for i=0 to NODE_COUNT(Bus_Slot)-1            
    
                        '判断当前节点是否有电机
    
                        if NODE_AXIS_COUNT(Bus_Slot,i) <>0 then      
    
                        for j=0 to NODE_AXIS_COUNT(Bus_Slot,i)-1
    
                           '映射轴号
    
                           AXIS_ADDRESS(Bus_AxisStart+i)=Bus_TotalAxisnum+1
    
                           '设置控制模式 65-位置 66-速度 67-转矩       
    
                           ATYPE(Bus_AxisStart+i)=65
    
                           '设置PROFILE功能                
    
                           DRIVE_PROFILE(Bus_AxisStart+i)= 4
    
                           '每轴单独分组            
    
                           DISABLE_GROUP(Bus_AxisStart+i)              
    
                           '映射驱动器上的IO起始地址
    
                           DRIVE_IO(Bus_AxisStart+i) = 128 + (Bus_AxisStart+i)*16  
    
                          '总轴数+1      
    
                          Bus_TotalAxisnum=Bus_TotalAxisnum+1                
    
                      next
    
                    endif
    
               next      
    
                  ?"轴号映射完成","连接总轴数:"Bus_TotalAxisnum
    
                  WA 2000
    
                  '总线开启
    
                  SLOT_START(Bus_Slot)            
    
                  if return then 
    
                     ?"总线开启成功"            
    
                     ?"开始清除驱动器错误(根据驱动器数据字典设置)"
    
                     for i= Bus_AxisStart to Bus_AxisStart + Bus_TotalAxisnum - 1              
    
                        DRIVE_CONTROLWORD(i)=128          '根据驱动器数据字典
    
                        wa 100
    
                        DRIVE_CONTROLWORD(i)=6
    
                        wa 100
    
                        DRIVE_CONTROLWORD(i)=15
    
                        wa 100      
    
                     next        
    
                        ?"驱动器错误清除完成"
    
                        wa 100    
    
                        ?"清除控制器错误"
    
                        DATUM(0)
    
                        DRIVE_CLEAR(0)
    
                        ?"控制器错误清除完成"
    
                        wa 100              
    
                        ?"轴使能准备"
    
                        for i= Bus_AxisStart to Bus_AxisStart + Bus_TotalAxisnum - 1
    
                           base(i)
    
                           AXIS_ENABLE=1
    
                        next
    
                           '使能总开关
    
                            WDOG=1                      
    
                            Bus_InitStatus  = 1
    
                            ?"轴使能完成"
    
                     else
    
                        ?"总线开启失败"
    
                        Bus_InitStatus = 0
    
                     endif
    
                  
    
                 else
    
                    ?"总线扫描失败"
    
                    Bus_InitStatus = 0
    
                 endif
    
            end sub
    

    4)轴参数设置。

            #####轴参数设置####
    
                # 设置轴类型
    
                def set_atype(self, iaxis, iValue):
    
                    ret = zauxdll.ZAux_Direct_SetAtype(self.handle, iaxis, iValue)
    
                    if ret == 0:
    
                        print("Set Axis (", iaxis, ") Atype:", iValue)
    
                    else:
    
                        print("Set Axis (", iaxis, ") Atype fail!error:",ret)
    
                    return ret
    
            
    
                # 设置脉冲当量
    
                def set_units(self, iaxis, iValue):
    
                    ret = zauxdll.ZAux_Direct_SetUnits(self.handle, iaxis, ctypes.c_float(iValue))
    
                    if ret == 0:
    
                        print("Set Axis (", iaxis, ") Units:", iValue)
    
                    else:
    
                        print("Set Axis (", iaxis, ") Units fail!error:",ret)
    
                    return ret
    
            
    
                # 设置轴加速度
    
                def set_accel(self, iaxis, iValue):
    
                    ret = zauxdll.ZAux_Direct_SetAccel(self.handle, iaxis, ctypes.c_float(iValue))
    
                    if ret == 0:
    
                        print("Set Axis (", iaxis, ") Accel:", iValue)
    
                    else:
    
                        print("Set Accel (", iaxis, ") Accel fail!")
    
                    return ret
    
            
    
                # 设置轴减速度
    
                def set_decel(self, iaxis, iValue):
    
                    ret = zauxdll.ZAux_Direct_SetDecel(self.handle, iaxis, ctypes.c_float(iValue))
    
                    if ret == 0:
    
                        print("Set Axis (", iaxis, ") Decel:", iValue)
    
                    else:
    
                        print("Set Axis (", iaxis, ") Decel fail!error:",ret)
    
                    return ret
    
            
    
                # 设置轴运行速度
    
                def set_speed(self, iaxis, iValue):
    
                    ret = zauxdll.ZAux_Direct_SetAccel(self.handle, iaxis, ctypes.c_float(iValue))
    
                    if ret == 0:
    
                        print("Set Axis (", iaxis, ") Speed:", iValue)
    
                    else:
    
                        print("Set Axis (", iaxis, ") Speed fail!error:",ret)
    
                    return ret
    

    5)轴参数读取。

              
    
            ####################轴参数读取##################################
    
                # 读取轴脉冲当量
    
                def get_untis(self, iaxis):
    
                    iValue = (ctypes.c_float)()
    
                    ret = zauxdll.ZAux_Direct_GetUnits(self.handle, iaxis, ctypes.byref(iValue))
    
                    if ret == 0:
    
                        print("Get Axis (", iaxis, ") Units:", iValue.value)
    
                    else:
    
                        print("Get Axis (", iaxis, ") Units fail! error:",ret)
    
                    return ret
    
            
    
                # 读取轴加速度
    
                def get_accel(self, iaxis):
    
                    iValue = (ctypes.c_float)()
    
                    ret = zauxdll.ZAux_Direct_GetAccel(self.handle, iaxis, ctypes.byref(iValue))
    
                    if ret == 0:
    
                        print("Get Axis (", iaxis, ") Accel:",  iValue.value)
    
                    else:
    
                        print("Get Axis (", iaxis, ") Accel fail! error:",ret)
    
                    return ret
    
            
    
                # 读取轴减速度
    
                def get_decel(self, iaxis):
    
                    iValue = (ctypes.c_float)()
    
                    ret = zauxdll.ZAux_Direct_GetDecel(self.handle, iaxis, ctypes.byref(iValue))
    
                    if ret == 0:
    
                        print("Get Axis (", iaxis, ") Decel:",  iValue.value)
    
                    else:
    
                        print("Get Axis (", iaxis, ") Decel fail! error:",ret)
    
                    return ret
    
            
    
                # 读取轴运行速度
    
                def get_speed(self, iaxis):
    
                    iValue = (ctypes.c_float)()
    
                    ret = zauxdll.ZAux_Direct_GetSpeed(self.handle, iaxis, ctypes.byref(iValue))
    
                    if ret == 0:
    
                        print("Get Axis (", iaxis, ") Speed:",  iValue.value)
    
                    else:
    
                        print("Get Axis (", iaxis, ") Speed fail! error:",ret)
    
                    return ret
    

    6)单轴运动。

            # 直线运动
    
                def move(self, iaxis, iValue):
    
                    ret = zauxdll.ZAux_Direct_Single_Move(self.handle, iaxis, ctypes.c_float(iValue))
    
                    if ret == 0:
    
                        print("Axis (", iaxis, ") Move:", iValue)
    
                    else:
    
                        print("Axis (", iaxis, ") Move Fail! error:",ret)
    
                    return ret
    
            
    
             # 持续运动
    
                def vmove(self, iaxis, idir):
    
                    ret = zauxdll.ZAux_Direct_Single_Vmove(self.handle, iaxis, idir)
    
                    if ret == 0:
    
                        print("axis (", iaxis, ")Vmoving!")
    
                    else:
    
                        print("Vmoving fail! error:",ret)
    
                    return ret
    

    7)运行程序,输出结果。

            ######################功能使用####################
    
            zaux = ZMCWrapper()
    
            # 连接控制器ip   默认192.168.0.11
    
            zaux.connect("192.168.0.11")
    
            
    
            # 加载EtherCat总线初始化bas文件
    
            filename =os.getcwd()+"\ECAT_INIT.bas"
    
            zaux.BasDown(filename,1)
    
            
    
            # 设置轴0参数
    
            zaux.set_units(0, 100)
    
            zaux.set_accel(0, 1000)
    
            zaux.set_decel(0, 1000)
    
            zaux.set_speed(0, 1000)
    
            
    
            # 获取轴0参数
    
            zaux.get_untis(0)
    
            zaux.get_accel(0)
    
            zaux.get_decel(0)
    
            zaux.get_speed(0)
    
            
    
            # 单轴运动
    
            zaux.move(0,100)  # 轴0直线运动移动100位置
    

    10.jpg

    运行并输出程序运行结果

    本次,正运动技术EtherCAT运动控制卡开发教程之python,就分享到这里。

    更多精彩内容请关注“正运动小助手”公众号,需要相关开发环境与例程代码,请咨询正运动技术销售工程师。

    本文由正运动技术原创,欢迎大家转载,共同学习,一起提高中国智能制造水平。文章版权归正运动技术所有,如有转载请注明文章来源。

    33.png

    展开全文
  • 运动控制卡应用开发教程之C++

    千次阅读 2020-11-12 09:56:14
     在正式学习之前,我们先了解一下正运动技术的运动控制卡ECI2418和ECI2618。这两款产品分别是4轴,6轴运动控制卡。 ECI2418支持4轴脉冲输入与编码器反馈,板载24点输入,16点输出,2AD,2DA,支持手轮接口,其中...

      今天,正运动技术为大家分享一下应用C++开发一个多段连续插补的运动控制应用。

      我们主要从新建MFC项目,添加函数库讲起,再了解PC函数用法,最后通过项目实战——连续插补运动例程讲解,来让大家熟悉C++的项目开发。

      在正式学习之前,我们先了解一下正运动技术的运动控制卡ECI2418和ECI2618。这两款产品分别是4轴,6轴运动控制卡。

      

      1.jpg

      

      ECI2418支持4轴脉冲输入与编码器反馈,板载24点输入,16点输出,2AD,2DA,支持手轮接口,其中特定输出口支持高速PWM控制。

      

      2.jpg

      

      ECI2618支持6轴脉冲输入与编码器反馈,板载24点输入,16点输出,2AD,2DA,支持手轮接口,其中特定输出口支持高速PWM控制。

      

      3.jpg

      

      ECI2418,ECI2618均使用同一套API函数,均支持C、C++、C#、LabVIEW、Python、Delphi等开发语言,支持VC6.0、VB6.0、Qt、.Net等平台,支持Windows、Linux、WinCE、iMac等操作系统。

      以下是C++

      开发流程

       01 新建MFC项目,添加函数库。

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

      

      4.jpg

      

       2、选择开发语言为“Visual C++”和程序类型“MFC应用程序”。

      

      5.jpg

      

       3、下一步即可。

      

      6.jpg

      

       4、选择类型为“基于对话框”,下一步或者完成。

      下一步则往后继续配置,完成就直接完成即可。这里就不需要再配置了,无关紧要的,只要这个类型选好就行,其他的可以在项目中编辑。

      

      7.jpg

      

       5、找到厂家提供的光盘资料,路径如下(64位库为例)。

      1)进入光盘资料找到PC函数文件夹。

      

      8.jpg

      

      2)选择函数库2.1。

      

      9.jpg

      

      3)Windows平台。

      

      10.jpg

      

      4)根据需要选择对应的函数库这里选择64位库。

      

      11.jpg

      

      5)解压C++的压缩包,里面有C++对应的函数库。

      

      12.jpg

      

      6)函数库具体路径如下。

      

      13.jpg

      

       6、将厂商提供的C++的库文件和相关头文件复制到新建的项目里面。

      

      14.jpg

      

       7、在项目中添加静态库和相关头文件。

      静态库:zauxdll.lib, zmotion.lib

      相关头文件:zauxdll2.h, zmotion.h

      1)先右击头文件,接着依次选择:“添加”→“现有项”。

      

      15.jpg

      

      

      2)在弹出的窗口中依次添加静态库和相关头文件。

      

      16.jpg

      

      3)声明用到的头文件和定义控制器连接句柄。

      

      17.jpg

      

      至此项目新建完成。

      

       02 查看PC函数手册,了解其用法。

      

       1、PC函数手册也在光盘资料里面。

      具体路径如下:

      

      18.jpg

      

       2、PC编程

      先根据控制器连接方式选择对应的连接函数连接控制器,返回控制器句柄。接着用返回的控制器句柄,实现对控制器的控制。

      比如通过网口连接控制器,先使用ZAux_OpenEth()链接控制器,获取控制器句柄handle。

      

      19.jpg

      

      通过获取到的控制器句柄handle,对控制器进行单轴运动控制。

      

      20.jpg

      

      通过获取到的控制器句柄handle,对控制器进行多轴运动控制。

      

      21.jpg

      

      //多轴运动

       intaxislist[ 4] = { 0, 1, 2, 3 };                                              //运动BASE轴列表

       floatdislist[ 4] = { 100,100,100,100};                            //运动距离列表

      ZAux_Direct_Move(g_handle, 4, axislist, dislist);           //多轴运动

      

       03 项目实战之连续插补运动例程讲解

      

       1、例程以建立板卡的连接,执行3段连续轨迹的加工为目标。

      

      22.jpg

      

       2、例程简易流程图。

      

      23.jpg

      

      // 相关函数

      ZAux_OpenEth(IP_buffer, &g_handle);                                            //连接控制器

      ZAux_Direct_GetAllAxisPara(g_handle, " DPOS", 4, showpos);        //获取当前轴位

      ZAux_Direct_GetAllAxisPara(g_handle, " MSPEED", 4, mspeed);     //更新轴速度

      ZAux_Direct_Single_Cancel(g_handle, 0, 2); //停止主轴运动

      ZAux_Direct_Move(g_handle, 4, axislist, dislist1);                            //第1段多轴插补指令

      ZAux_Direct_Move(g_handle, 4, axislist, dislist2);                            //第2段多轴插补指令

      ZAux_Direct_Move(g_handle, 4, axislist, dislist3);                            //第3段多轴插补指令

      ZAux_Close(g_handle);//断开连接

      

       3、通过网口连接控制器,获取控制器连接句柄。

      

      //Link按钮事件处理函数

       voidCMergeDlg::OnBnClickedButtonLink()

      {

           charbuffer[256];

          int32 iresult;

          //如果之前有连接控制器着先断开连接

           if(NULL != g_handle)

          {

          ZAux_Close(g_handle);

          g_handle = NULL;

          }

          //从IP下拉框中获取IP

          GetDlgItemText(IDC_COMBOX_IP, buffer, 255);

          buffer[255] = '\0';

          //通过PC函数库提供的连接控制器的函数接口(API),连接控制器

          iresult = ZAux_OpenEth(buffer, &g_handle);

           if(ERR_SUCCESS != iresult)

          {

          g_handle = NULL;

          MessageBox(_T(" 链接失败"));

          SetWindowText(" 未链接");

           return;

      }

      SetWindowText(" 已链接");

      //启动定时器

      SetTimer(1, 100, NULL);

      SetTimer(2, 100, NULL);

      //初始化轴参数

       for( inti = 0; i<4; i++)

      {

          ZAux_Direct_SetAtype(g_handle, i, 1); //轴类型

          ZAux_Direct_SetUnits(g_handle, i, 1000); //脉冲当量

          ZAux_Direct_SetSpeed(g_handle, i, 100); //速度

          ZAux_Direct_SetAccel(g_handle, i, 1000); //加速度

          ZAux_Direct_SetDecel(g_handle, i, 1000); //减速度

      ZAux_Direct_SetSramp(g_handle, i, 100); //S曲线时间

          }

      }

      

       4、通过定时器1更新控制器轴0-3的位置信息和速度信息。

      

      //定时器

      void CMergeDlg::OnTimer(UINT_PTR nIDEvent)

      {

          if (NULL == g_handle)

          {

              MessageBox(_T(" 链接断开"));

              return;

          }

          switch (nIDEvent)

          {

          case 1: //更新控制器轴0-3的位置信息和速度信息

              CString Xpos, Xmspeed;

              CString Ypos, Ymspeed;

              CString Zpos, Zmspeed;

              CString Upos, Umspeed;

              float showpos[4] = { 0 };

              float mspeed[4] = { 0 };

      int         status = 0;

              //获取当前轴位置

              ZAux_Direct_GetAllAxisPara(g_handle, " DPOS", 4, showpos);

              Xpos.Format(" X: %.2f", showpos[0]);

              Ypos.Format(" Y: %.2f", showpos[1]);

              Zpos.Format(" Z: %.2f", showpos[2]);

              Upos.Format(" U: %.2f", showpos[3]);

              GetDlgItem(IDC_XPOS)->SetWindowText(Xpos);

              GetDlgItem(IDC_YPOS)->SetWindowText(Ypos);

              GetDlgItem(IDC_ZPOS)->SetWindowText(Zpos);

              GetDlgItem(IDC_UPOS)->SetWindowText(Upos);

              //判断主轴状态(即BASE的第一个轴)

              ZAux_Direct_GetIfIdle(g_handle, 0, &status);

              if (status == -1)

              {

                  GetDlgItem(IDC_RUNSTATUS)->SetWindowText(" 运动状态:停止中");

              }

              else

              {

                  GetDlgItem(IDC_RUNSTATUS)->SetWindowText(" 运动状态:运动中");

              }

              //更新轴速度

              ZAux_Direct_GetAllAxisPara(g_handle, " MSPEED", 4, mspeed);

              Xmspeed.Format(" X轴速度: %.2f", mspeed[0]);

              Ymspeed.Format(" Y轴速度: %.2f", mspeed[1]);

              Zmspeed.Format(" Z轴速度: %.2f", mspeed[2]);

              Umspeed.Format(" U轴速度: %.2f", mspeed[3]);

              GetDlgItem(IDC_SPEED_X)->SetWindowText(Xmspeed);

              GetDlgItem(IDC_SPEED_Y)->SetWindowText(Ymspeed);

              GetDlgItem(IDC_SPEED_Z)->SetWindowText(Zmspeed);

              GetDlgItem(IDC_SPEED_U)->SetWindowText(Umspeed);

              break;

          }

          CDialogEx::OnTimer(nIDEvent);

      }

      

       5、通过启动按钮的事件处理函数来启动连续插补运动。

      

      //启动按钮

      void CMergeDlg::OnBnClickedButtonRun()

      {

          if (NULL == g_handle)

          {

              MessageBox(_T( "链接断开"));

              return;

          }

          UpdateData(true);//刷新参数

          int corner_mode = 0;

          int axislist[4] = { 0,1,2,3 }; //运动BASE轴列表

          float dislist1[4] = { 0 }; //运动距离列表

          float dislist2[4] = { 0 };

          float dislist3[4] = { 0 };

          //选择参与运动的轴,第一个轴为主轴,插补参数全用主轴参数

          ZAux_Direct_SetSpeed(g_handle, axislist[0], M_Speed); //速度

          ZAux_Direct_SetAccel(g_handle, axislist[0], M_Accel); //加速度

          ZAux_Direct_SetDecel(g_handle, axislist[0], M_Decel); //减速度

      ZAux_Direct_SetSramp(g_handle, axislist[0], M_SRAMP); //S曲线时间

          //设置拐角模式

          if (m_mode1 == 1)

          {

              corner_mode = corner_mode + 2;

          }

          if (m_mode2 == 1)

          {

              corner_mode = corner_mode + 8;

          }

          if (m_mode3 == 1)

          {

              corner_mode = corner_mode + 32;

          }

          ZAux_Direct_SetCornerMode(g_handle, axislist[0], corner_mode);

          //设置连续插补

          ZAux_Direct_SetMerge(g_handle, axislist[0], m_mode);

          //设置SP速度

          ZAux_Direct_SetForceSpeed(g_handle, axislist[0], SP_Speed);

          //设置开始.结束减速角度,转换为弧度

          ZAux_Direct_SetDecelAngle(g_handle, axislist[0], StartAngle * 3.14 / 180);

          ZAux_Direct_SetStopAngle(g_handle, axislist[0], StopAngle * 3.14 / 180);

          //设置小圆限速半径

          ZAux_Direct_SetFullSpRadius(g_handle, axislist[0], SP_Radius);

          //设置拐角半径

          ZAux_Direct_SetZsmooth(g_handle, axislist[0], CornerRadius);

          //SP指令中自动拐角模式中设置一个较大的startmovespeed与endmovespeed

          ZAux_Direct_SetStartMoveSpeed(g_handle, axislist[0], 10000);

          ZAux_Direct_SetEndMoveSpeed(g_handle, axislist[0], 10000);

          //更新运动数据

          dislist1[0] = DPOS_X_1; dislist1[1] = DPOS_Y_1;

          dislist1[2] = DPOS_Z_1; dislist1[3] = DPOS_U_1;

          dislist2[0] = DPOS_X_2; dislist2[1] = DPOS_Y_2;

          dislist2[2] = DPOS_Z_2; dislist2[3] = DPOS_U_2;

          dislist3[0] = DPOS_X_3; dislist3[1] = DPOS_Y_3;

          dislist3[2] = DPOS_Z_3; dislist3[3] = DPOS_U_3;

          //开始运动

          ZAux_Direct_Move(g_handle, 4, axislist, dislist1);

          ZAux_Direct_Move(g_handle, 4, axislist, dislist2);

          ZAux_Direct_Move(g_handle, 4, axislist, dislist3);

      }

      

       6、通过停止按钮的事件处理函数来停止插补运动。

      

      //停止按钮

      void CMergeDlg::OnBnClickedButtonStop()

      {

          if (NULL == g_handle)

          {

              MessageBox(_T("链接断开"));

              return;

          }

          ZAux_Direct_Single_Cancel(g_handle, 0, 2); //停止主轴 BASE的一个轴

      }

      

      7、轴坐标清零。

      

      //坐标清零

      void CMergeDlg::OnBnClickedButtonClear()

      {

          if (NULL == g_handle)

          {

              MessageBox(_T("链接断开"));

              return;

          }

          for (int i = 0; i<4; i++)

          {

              ZAux_Direct_SetDpos(g_handle, i, 0); //DPOS设为零

          }

      }

      

       8、编译运行演示。

      

      1)编译运行示教例程。

      

      24.jpg

      

      2)同时通过ZDevelop软件连接同一个控制器,对运动控制的轴参数进行监控。

          A、连续插补加自动倒角的位置波形。

      

      25.jpg

      

          B、不开启连续插补的速度波形。

      

      26.jpg

      28.jpg

      

      

          C、连续插补加合适的拐角减速的速度波形。

      

      28.jpg

      29.jpg

      30.jpg

      

      正运动技术C++开发就讲到这里。更多学习视频及图文请关注我们的公众号“正运动小助手”。

      本文由正运动小助手原创,欢迎大家转载,共同学习,一起提高中国智能制造水平。文章版权归正运动技术所有,如有转载请注明文章来源。

    31.jpg

    展开全文
  • 全套。 编程手册。用户手册。Demo软件:GTS-VB系列多轴运动控制器。
  • 雷赛运动控制卡软件开发应用课程,讲解的内容很基础,有点笼统。雷赛官网下载的。你好吗--凑字数--我很好-凑字数--
  • 固高GTS系列运动控制卡编程手册,编程范例等及调用的函数
  • 雷赛运动控制卡例子

    2022-03-01 21:47:11
    /* void d2410_write_outbit (WORD cardno, WORD bitno,WORD on_off) 功 能:对指定控制卡的某一位输出口置位 参 数:cardno 指定控制卡号, 范围(0 - N - 1 ,N 为卡数) Bitno 指定输出口位号(取值范围:1-20)...
  • 运动控制卡应用开发教程之LabVIEW

    千次阅读 2020-11-11 10:25:11
    今天,我们来讲解一下正运动技术运动控制卡应用开发教程之LabVIEW。 在正式学习之前,我们先了解一下正运动技术的运动控制卡ECI2418和ECI2618。这两款产品分别是4轴,6轴运动控制卡。 ECI2418支持4轴脉冲输入与...
  • 运动控制卡应用开发教程之VC6.0

    千次阅读 2020-11-13 09:00:42
    今天,我们来讲解一下正运动技术运动控制卡应用开发教程之VC6.0。 在正式学习之前,我们先了解一下正运动技术的运动控制卡ECI2418和ECI2618。这两款产品分别是4轴,6轴运动控制卡。 ECI2418支持4轴脉冲输入与编码...
  • 运动控制卡C程序示例2. VC编程示例2.1 准备工作新建一个项目,保存为“VCExample.dsw”;根据前面讲述的方法 ,将静态库“8840.lib”加载到项目中;2.2 运动控制模块(1) 在项目中添加一个新类 ,头文件保存为“CtrlCard...
  • 今天,正运动小助手给大家分享一下运动控制卡应用开发教程之MATLAB。 一 、ECI2828硬件介绍 ECI2828系列运动控制卡支持多达16 轴直线插补、任意圆弧插补、空间圆弧、螺旋插补、电子凸轮、电子齿轮、同步跟随、虚拟...
  •  今天正运动技术与大家分享一下运动控制卡应用开发教程之Python。 在正式学习之前,我们先了解一下正运动技术的运动控制卡ECI2418和ECI2618。这两款产品分别是4轴,6轴运动控制卡。 ECI2418支持4轴脉冲输入与编码...
  • 在正式学习之前,我们先了解一下正运动技术的运动控制卡ECI2418和ECI2618。这两款产品分别是4轴,6轴运动控制卡。 ECI2418支持4轴脉冲输入与编码器反馈,板载24点输入,16点输出,2AD,2DA,支持手轮接口,其中...
  • 摘要:今天,我们来讲解一下正运动技术运动控制卡应用开发教程之Qt。今天,我们来讲解一下正运动技术运动控制卡应用开发教程之Qt。此前,我们与大家分享过“开放式Linux平台控制器XPLC516E及其Linux下的Qt开发”,...
  • 固高是国内运动控制器做的时间比较长的厂家,相对来说产品质量还可以,技术支持还是不错的。厂家有测试软件,可以使用。对固高印象不错,主要是售后的技术支持比较给力,遇到问题能够想办法协调资源,想办法解决。...
  • 需要的环境: 文件:ExtModule.cfg ;... GTS800_1.cfg (这里以GTS-400-PT型号的控制卡为例); gts.cs 启动类: public class GTS_Start { protected short _cardNum; protected short _mdl; ...
  • 雷赛运动控制卡DMC2410入门篇

    千次阅读 2021-03-30 09:16:19
    随着机器人的发展,运动控制的应用也越来越广泛,运动控制的实现方式很多,包括PLC,运动控制器以及运动控制卡,这三种方式各有利弊,这里主要介绍通过雷赛运动控制卡来实现的控制,对第一次使用雷赛板卡的人来说,...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 2,364
精华内容 945
关键字:

运动控制卡编程教程

友情链接: duxt.rar