zoukankan      html  css  js  c++  java
  • Zmotion快速入门之EtherCAT通信

    新阁教育-喜科堂付工原创文章

    本案例采用Zmotion运动控制卡与伺服驱动器进行EtherCAT通信,从而实现对伺服电机的相关控制。

    硬件连接

    因为采用总线的原因,所以基本上不用接线,硬件原理图如下所示:

    将PC通过Ethernet连接至运动控制卡,然后运动控制卡的EtherCAT接至伺服驱动器,伺服驱动器与伺服电机之间通过配套电缆进行连接。

    快速上手

    第一次使用时,最好的方式就是看编程手册,并结合官方提供的案例来学习使用。

    Zmotion厂家提供的配套资料,我会传到公众号里,需要的小伙伴,可以后台回复 Zmotion 获取

    在保证硬件没有问题的前提下(这里主要是指伺服驱动器,至少能够手动转起来),打开 ZMC光盘资料8.PC编程相关函数库2.1windows平台64位库C#例程例程8-总线控制运动 中的源程序,运行起来如下所示:

    这里有两个地方要注意,不然是运行不起来的。

    • 案例中提供的ECAT初始化.bas文件,最大轴数是32,需要根据实际情况修改,否则会报错,我这里改成16。

     如果伺服没有接限位开关,轴状态应该是30H,表示正负限位报警,需要将正负限位禁用掉,具体操作是通过ZDevelop将FWD_IN和REV_IN设置为-1,当然后续可以通过代码实现。

    这两点注意,伺服电机就应该可以动起来了。

    软件开发

    后续的软件开发主要就是封装应用,Zmotion的使用会涉及到两个dll库(zauxdll.dll和zmotion.dll)和一个Zmcaux.cs类文件,提前将这两个dll库复制到根目录下,然后手动将Zmcaux.cs类添加到你的项目中。

    创建一个新的Zmotion.cs类,对Zmcaux.cs中的一些方法进行二次封装,便于后续项目的应用。

    二次封装的方式每个人都会根据自己的编码习惯,进行不同程度的封装,下面我仅列举部分我的封装方法,仅供参考:

    建立连接:EtherCAT连接之前需要执行一个bas文件,根据案例中的代码封装如下:

     /// <summary>
            /// 初始化卡
            /// </summary>
            /// <param name="ipAddress">IP地址</param>
            /// <param name="file">BAS文件</param>
            /// <param name="tempstatus">总线初始化完成状态</param>
            /// <param name="m_BusNodeNum">节点数</param>
            /// <returns>操作结果</returns>
            public OperationResult InitCard(string ipAddress, string file, ref float tempstatus, ref int m_BusNodeNum)
            {
                int error = 0;
                error = zmcaux.ZAux_OpenEth(ipAddress, out zhandle);
                if (error == 0)
                {
                    error = zmcaux.ZAux_BasDown(zhandle, file, 1);
                    if (error == 0)
                    {
                        //执行初始化
                        StringBuilder buffer = new StringBuilder(10240);
                        //任务1重新运行BAS中的初始化函数
                        error = zmcaux.ZAux_Execute(zhandle, "RUNTASK 1,Ecat_Init", buffer, 0);
                        if (error != 0)
                        {
                            return new OperationResult()
                            {
                                IsSuccess = true,
                                ErrorMsg = "初始化失败"
                            };
                        }
                        IEC_Timer_TON ton = new IEC_Timer_TON(5000);
                        ton.Input = true;
                        while (true)
                        {
                            int ret = 0;
                            float Bus_type = 0.0f;
                            float m_BusAxisNum = 0.0f;
                            //读取BAS文件中的变量判断总线类型
                            ret += zmcaux.ZAux_Direct_GetUserVar(zhandle, "BUS_TYPE", ref Bus_type);
                            // 读取BAS文件中的变量判断总线初始化完成状态
                            ret += zmcaux.ZAux_Direct_GetUserVar(zhandle, "Bus_InitStatus", ref tempstatus);
                            ret += zmcaux.ZAux_BusCmd_GetNodeNum(zhandle, 0, ref m_BusNodeNum);
                            ret += zmcaux.ZAux_Direct_GetUserVar(zhandle, "Bus_TotalAxisnum", ref m_BusAxisNum);
                            bool completed = ret == 0;
                            completed &= tempstatus == 1;
                            completed &= m_BusNodeNum > 0;
                            bool output = ton.Output;
                            if (completed)
                            {
                                break;
                            }
                            else if (!output)
                            {
                                continue;
                            }
                            else
                            {
                                if (tempstatus == -1)
                                {
                                    return new OperationResult()
                                    {
                                        IsSuccess = false,
                                        ErrorMsg = "正在初始化"
                                    };
                                }
                                else
                                {
                                    return new OperationResult()
                                    {
                                        IsSuccess = false,
                                        ErrorMsg = "初始化失败"
                                    };
                                }
                            }
                        }
                        initedOK = true;
                        return OperationResult.CreateSuccessResult();
                    }
                    return new OperationResult()
                    {
                        IsSuccess = true,
                        ErrorMsg = "文件下载失败"
                    };
                }
                return new OperationResult()
                {
                    IsSuccess = true,
                    ErrorMsg = "以太网连接失败"
                };
            }

    点位运动:点位运动主要就是根据轴号、速度、加速度、脉冲当量进行正转或反转,代码如下:

      public OperationResult Move(int axisNo, float scale, float vel, float acc, bool dir)
           {
               int error = 0;
               error += zmcaux.ZAux_Direct_SetUnits(zhandle, axisNo, scale);
               error += zmcaux.ZAux_Direct_SetSpeed(zhandle, axisNo, vel);
               error += zmcaux.ZAux_Direct_SetAccel(zhandle, axisNo, acc);
               error += zmcaux.ZAux_Direct_Single_Vmove(zhandle, axisNo, dir ? 1 : -1);

               if (error > 0)
               {
                   return OperationResult.CreateFailResult();
               }
               else
               {
                   return OperationResult.CreateSuccessResult();
               }
           }

    停止运动:停止运动比较简单,调用ZAux_Direct_Single_Cancel指令即可。

    public OperationResult Stop(int axisNo)
           {
               int error = 0;
               error = zmcaux.ZAux_Direct_Single_Cancel(zhandle, axisNo, 2);

               if (error > 0)
               {
                   return OperationResult.CreateFailResult();
               }
               else
               {
                   return OperationResult.CreateSuccessResult();
               }
           }

    开发界面

    这里做了一个简单的控制界面,实现了基本的板卡连接、点动、连续运动、伺服使能等基本控制功能。

  • 相关阅读:
    6.Ray-消息订阅器编写
    附录:2-Event Sourcing pattern (事件溯源设计模式)
    附录:1-Grain生命周期-译注
    4.Ray-Handler之CoreHandler编写
    Q&A-20180128
    TODO
    3.Ray-Event编写
    缓存技术内部交流_01_Ehcache3简介
    Spring AMQP 源码分析 04
    Spring AMQP 源码分析 03
  • 原文地址:https://www.cnblogs.com/xiketang/p/14692999.html
Copyright © 2011-2022 走看看