EtherCAT运动控制卡开发教程之python

news2024/11/28 8:36:05

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

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

一、ECI2828硬件介绍

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

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

在这里插入图片描述

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

二、Python语言开发流程

Python语言的使用环境

  • 操作系统环境:win7_64x

  • Python开发运行环境:PyCharm2019.2

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

1、新建项目。

打开Pycharm软件进行操作,点击Create New Project新建项目。
在这里插入图片描述

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

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

在这里插入图片描述

3、新建Python文件。

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

在这里插入图片描述

4、将Python动态库复制到Python项目中。
在这里插入图片描述

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对象进行调用”。

在这里插入图片描述

2)通过ip连接函数接口返回的控制器句柄handle,对控制器的句柄handle操作。
在这里插入图片描述

#####控制器连接#####
    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总线轴的初始化

在这里插入图片描述

********************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位置

在这里插入图片描述

本次,正运动技术EtherCAT运动控制卡开发教程之python,就分享到这里。更多精彩内容请关注“正运动小助手”公众号。

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/572905.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

第三十七章 扩展知识点

1、setState (1). setState(stateChange, [callback])------对象式的setState1.stateChange为状态改变对象(该对象可以体现出状态的更改)2.callback是可选的回调函数, 它在状态更新完毕、界面也更新后(render调用后)才被调用(2). setState(updater, [callback])------函数式的…

敏捷专题:新一代的汽车软件研发

过去&#xff0c;买车属于一锤子买卖&#xff0c;但近年来智能制造、新能源汽车等概念的狂飙突进下&#xff0c;个性化、定制化、智能化的新车型正倍速来到消费者面前&#xff0c;不到20万元就能买到各大车企搭载了智能座舱和智能驾驶功能的产品。 ▲智能座舱 众所周知&#xf…

(一)微服务中间键工作原理——nacos客户端服务注册原理说明及源码解读

前言 本节内容我们主要介绍一下中间键nacos的客户端服务注册原理及其源码解读&#xff0c;便于我们理解nacos作为服务注册中心的具体实现。在springcloud的微服务体系中&#xff0c;nacos客户端的注册是通过使用spring的监听机制ApplicationListener实现的。学习本节内容&…

golang常见导致panic的场景

1、越界 常见有数组越界和字符串越界 2、空指针引用 直接引用空指针结构体的字段会引发panic&#xff0c;但调用成员方法里如果没引用结构体的字段不会引发panic 3、断言失败 4、map操作错误 map未初始化&#xff0c;可读不可写。 map的value如果是结构体指针&#xf…

G0第21章 :gin框架介绍、RESTful API、Gin渲染

G0第21章 &#xff1a;gin框架 01 内容介绍 web本质 Web是基于HTTP协议进行交互的应用网络Web就是通过使用浏览器/APP访问的各种资源 package mainimport ("fmt""net/http" )func sayHello(w http.ResponseWriter, r *http.Request){_, _ fmt.Fprintln(…

MKS SERVO4257D 闭环步进电机_系列1 产品简介

第1部分 产品概述 1.1 产品介绍 MKS SERVO 28D/35D/42D/57D 系列闭环步进电机是创客基地为满足市场需求而自主研发的一款产品。具备脉冲接口&#xff0c;RS485接口和CAN接口&#xff0c;内置高效FOC矢量算法&#xff0c;采用高精度编码器&#xff0c;通过位置反馈&#xff0c;有…

《深入理解计算机系统》读书笔记1.1-1.5

1.1信息就是位上下文 只由ASCLL字符构成的文件称为文本文件&#xff0c;所有其他文件都称为二进制文件。 系统中的所有的信息都由一串比特表示。区分不同数据对象的唯一方法是读到这些数据对象时的上下文。 1.2程序被其他程序翻译成不同的格式 预编译&#xff0c;编译&#xf…

EasyCVR视频融合平台设备分组共享功能的使用介绍

EasyCVR视频融合平台基于云边端一体化架构&#xff0c;具有强大的数据接入、处理及分发能力&#xff0c;平台支持海量视频汇聚管理&#xff0c;可支持多协议、多类型的设备接入&#xff0c;并能对设备进行分级、分组管理&#xff0c;并支持权限、角色分配&#xff0c;属于功能全…

PFC落石模拟

Landslide/Rockfall simulation 山体滑坡/落石模拟 https://www.youtube.com/watch?vWSa3909qYmI 模拟的目的在于通过导入团块的对象文件产生团块的二进制输出。 具体措施&#xff1a; (i) 使用导入的几何体形成团块模板 (ii) 使用Taghavi(2011)定义的BubblePack算法来生成卵石…

算法|4.归并排序及应用

算法|4.归并排序及应用 1.归并排序算法 题意&#xff1a;归并排序的递归和非递归实现 解题思路&#xff1a; ​ 递归实现&#xff1a; 预处理&#xff1a;数组为空或者长度小于2的直接返回调用子过程子过程终止条件LR分解成[L,mid]&#xff0c;[mid1,R] &#xff0c;子数组…

九章云极DataCanvas公司诚邀您共享AI基础软件前沿技术盛宴

“杭州通用人工智能论坛暨AIIA人工智能产业发展大会”将于2023年5月30日-31日在杭州举办。本次人工智能产业发展大会由中国信息通信研究院、中国人工智能产业发展联盟主办&#xff0c;杭州城西科创大走廊管委会、杭州市经济和信息化局、杭州未来科技城管理委员会、人工智能关键…

企业级信息系统开发——初探JdbcTemplate操作

文章目录 一、创建数据库与表1、创建数据库2、创建用户表3、用户表添加记录 二、打开Spring项目三、添加数据库相关依赖四、创建用户实体类五、创建用户数据访问接口六、创建用户数据访问接口实现类七、创建用户服务类八、创建数据库配置属性文件九、创建Spring配置文件十、创建…

Springboot +spring security,解决跨域问题

一.简介 这篇文章主要是解释什么是跨域&#xff0c;在Spring中如何解决跨域&#xff0c;引入Spring Security后Spring解决跨域的方式失效&#xff0c;Spring Security 如何解决跨域的问题。 二.什么是跨域 跨域的概率&#xff1a; 浏览器不能执行其他网站的脚本&#xff0c…

jsp页面调试

现象: 访问jsp页面, 页面为空, 网络请求显示失败, 控制台打印错误net::ERR_INCOMPLETE_CHUNKED_ENCODING 200 分析: 错误描述&#xff1a;编码模块不完整&#xff0c;返回浏览器的流不完整 可能得原因: 1、网络是否稳定 2、服务器端是否有对响应数据做限制&#xff0c;比如…

【App自动化测试】(十七)遍历测试工具——Android Maxim

目录 1. Android Maxim介绍2. Android Maxim使用方法3.Android Maxim运行命令4.Android Maxim的策略5.实例演示——Windows系统&#xff0c;使用AVD模拟器&#xff0c;系统 Android6.0 1. Android Maxim介绍 Android Maxim是基于遍历规则的高性能Android Monkey&#xff0c;适…

基于SpringBoot+Vue的毕业生信息招聘平台设计与实现

博主介绍&#xff1a; 大家好&#xff0c;我是一名在Java圈混迹十余年的程序员&#xff0c;精通Java编程语言&#xff0c;同时也熟练掌握微信小程序、Python和Android等技术&#xff0c;能够为大家提供全方位的技术支持和交流。 我擅长在JavaWeb、SSH、SSM、SpringBoot等框架下…

Elasticsearch常用接口使用说明以及postman调用调试

查看集群状态 接口url&#xff1a;http://xxxx:9200/_cat 查看所有索引 http://xxxx:9200/_cat/indices?v 创建索引 http://xxxx:9200/test-20230526?pretty 返回值 { "acknowledged": true, "shards_acknowledged": true, "index": &quo…

Opencv-C++笔记 (2) : opencv的矩阵操作

文章目录 创建与初始化1.1 数据类型1.2 基本方法1.3 初始化方法 矩阵加减法矩阵乘法矩阵转置矩阵求逆矩阵非零元素个数矩阵均值与标准差矩阵全局极值及位置GEMM 通用矩阵乘法Transform 对数组每一个元素执行矩阵变换MulTransposed 计算数组和数组的转置的乘积Trace 返回矩阵的迹…

WIN10:Cognos10.2_x32安装

一、Cognos BI Server 10.2 32Bit 二、Cognos Transformer 10.2 三、Cognos Framework Manager 10.2 四、环境 1、如果使用Cognos自带的Tomcat web容器&#xff0c;将E:\common\Cognos\c10\webcontent下的所有文件拷贝到E:\common\Cognos\c10\webapps\p2pd 下面.(一般我们就使…

redis高级篇 缓存双写一致性之更新策略

闲聊 缓存通用查询3部曲 redis 中数据&#xff0c;返回redis 中的数据redis 中没有&#xff0c;查询数据库并返回完成第二部的同时&#xff0c;将数据库查询结果写到redis,redis和数据库数据一致. 谈谈双写一致性的理解 1.如果redis 中有数据&#xff1a;需要和数据库中的相…