热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

运动控制卡应用开发教程之C#

今天,正运动小助手为大家分享一下应用C#开发一个多段连续插补的运动控制应用。我们主要从新建项目,添加函数库讲起,再了解PC函数使用&#x

今天,正运动小助手为大家分享一下应用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 !&#61; (IntPtr)0){zmcaux.ZAux_Close(g_handle);//断开连接g_handle &#61; (IntPtr)0;}zmcaux.ZAux_OpenEth(comboBox_IpList.Text, out g_handle);//连接控制器if (g_handle !&#61; (IntPtr)0){this.Text &#61; "已连接";timer1.Enabled &#61; true;//初始化轴参数for (int i &#61; 0; i < 4; i&#43;&#43;){zmcaux.ZAux_Direct_SetAtype(g_handle, i, 1);//轴类型 脉冲轴zmcaux.ZAux_Direct_SetUnits(g_handle, i, 1);//脉冲当量}}else{MessageBox.Show("控制器链接失败&#xff0c;请检测IP地址!", "警告");}}4.通过定时器1更新控制器轴0-3的位置和速度等信息。//定时器刷新private void timer1_Tick(object sender, EventArgs e){int runstate &#61; 0;float[] curpos &#61; new float[4];float vspeed &#61; 0;int remin_buff &#61; 0;int curmark &#61; 0;//获取轴位置for (int i &#61; 0; i < 4; i&#43;&#43;){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);//判断当前运动到第几条运动&#xff0c;zmcaux.ZAux_Direct_GetMoveCurmark(g_handle, 0, ref curmark);label_pos.Text &#61; "X:" &#43; curpos[0] &#43; " Y:" &#43; curpos[1] &#43; " Z:" &#43; curpos[2] &#43; " U:" &#43; curpos[3];label_state.Text &#61; Convert.ToString(runstate &#61;&#61; 0 ? " 运行状态&#xff1a;运行中" : " 运行状态&#xff1a;停止中");label_vspeed.Text &#61; "当前速度&#xff1a;" &#43; vspeed;label_buff.Text &#61; "剩余缓冲&#xff1a;" &#43; remin_buff;label_mark.Text &#61; "当前MARK&#xff1a;" &#43; curmark;}

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

//启动按钮private void button_start_Click(object sender, EventArgs e){int[] axislist &#61; { 0, 1, 2, 3 }; //轴列表float[] destdis &#61; { 0, 0, 0, 0 }; //运动距离列表int corner_mode &#61; 0; //拐角模式int merge_flag &#61; 0; //连续插补int iresult &#61; 0; //PC函数返回值int remin_buff &#61; 0; //剩余直线缓冲数if (checkBox1.Checked){corner_mode &#61; corner_mode &#43; 2;}if(checkBox2.Checked){corner_mode &#61; corner_mode &#43; 8;}if(checkBox3.Checked){corner_mode &#61; corner_mode &#43; 32;}if (checkBox4.Checked){merge_flag &#61; 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);//开始减速角度&#xff0c;转换为弧度zmcaux.ZAux_Direct_SetDecelAngle(g_handle, axislist[0], (float)(Convert.ToSingle(textBox_ang1.Text) * 3.14 / 180));//停止减速角度&#xff0c;转换为弧度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 &#61; 0 &#xff0c;来通过读取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] &#61; Convert.ToSingle(destdis1_X.Text);destdis[1] &#61; Convert.ToSingle(destdis1_Y.Text);destdis[2] &#61; Convert.ToSingle(destdis1_Z.Text);destdis[3] &#61; Convert.ToSingle(destdis1_U.Text);iresult &#61; zmcaux.ZAux_Direct_MoveAbs(g_handle, 4, axislist, destdis);//4轴插补指令//函数返回非0 则表示发送不成功&#xff0c;缓冲区可能满了&#xff0c;重新发送while (iresult !&#61; 0){iresult &#61; zmcaux.ZAux_Direct_MoveAbs(g_handle, 4, axislist, destdis);System.Threading.Thread.Sleep(1); //1毫秒}//第二段插补运动destdis[0] &#61; Convert.ToSingle(destdis2_X.Text);destdis[1] &#61; Convert.ToSingle(destdis2_Y.Text);destdis[2] &#61; Convert.ToSingle(destdis2_Z.Text);destdis[3] &#61; Convert.ToSingle(destdis2_U.Text);iresult &#61; zmcaux.ZAux_Direct_MoveAbs(g_handle, 4, axislist, destdis);//4轴插补指令//函数返回非0 则表示发送不成功&#xff0c;缓冲区可能满了&#xff0c;重新发送while (iresult !&#61; 0){iresult &#61; zmcaux.ZAux_Direct_MoveAbs(g_handle, 4, axislist, destdis);System.Threading.Thread.Sleep(1); //1毫秒}//第三段插补运动destdis[0] &#61; Convert.ToSingle(destdis3_X.Text);destdis[1] &#61; Convert.ToSingle(destdis3_Y.Text);destdis[2] &#61; Convert.ToSingle(destdis3_Z.Text);destdis[3] &#61; Convert.ToSingle(destdis3_U.Text);iresult &#61; zmcaux.ZAux_Direct_MoveAbs(g_handle, 4, axislist, destdis);//4轴插补指令//函数返回非0 则表示发送不成功&#xff0c;缓冲区可能满了&#xff0c;重新发送while (iresult !&#61; 0){iresult &#61; zmcaux.ZAux_Direct_MoveAbs(g_handle, 4, axislist, destdis);System.Threading.Thread.Sleep(1); //1毫秒}//第四段插补运动destdis[0] &#61; Convert.ToSingle(destdis4_X.Text);destdis[1] &#61; Convert.ToSingle(destdis4_Y.Text);destdis[2] &#61; Convert.ToSingle(destdis4_Z.Text);destdis[3] &#61; Convert.ToSingle(destdis4_U.Text);iresult &#61; zmcaux.ZAux_Direct_MoveAbs(g_handle, 4, axislist, destdis);//4轴插补指令//函数返回非0 则表示发送不成功&#xff0c;缓冲区可能满了&#xff0c;重新发送while (iresult !&#61; 0){iresult &#61; 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 &#61;&#61; (IntPtr)0){MessageBox.Show("未链接到控制器!", "提示");}else{for (int i &#61; 0; i < 4; i&#43;&#43;){zmcaux.ZAux_Direct_SetDpos(g_handle, i, 0);}}}

8. 编译运行演示。

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

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

26.jpg

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

27.jpg

28.jpg

29.jpg

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

30.jpg

31.jpg

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

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

在这里插入图片描述


推荐阅读
  • 本文分享了一个关于在C#中使用异步代码的问题,作者在控制台中运行时代码正常工作,但在Windows窗体中却无法正常工作。作者尝试搜索局域网上的主机,但在窗体中计数器没有减少。文章提供了相关的代码和解决思路。 ... [详细]
  • 本文讨论了在Windows 8上安装gvim中插件时出现的错误加载问题。作者将EasyMotion插件放在了正确的位置,但加载时却出现了错误。作者提供了下载链接和之前放置插件的位置,并列出了出现的错误信息。 ... [详细]
  • 本文详细介绍了Linux中进程控制块PCBtask_struct结构体的结构和作用,包括进程状态、进程号、待处理信号、进程地址空间、调度标志、锁深度、基本时间片、调度策略以及内存管理信息等方面的内容。阅读本文可以更加深入地了解Linux进程管理的原理和机制。 ... [详细]
  • Redis底层数据结构之压缩列表的介绍及实现原理
    本文介绍了Redis底层数据结构之压缩列表的概念、实现原理以及使用场景。压缩列表是Redis为了节约内存而开发的一种顺序数据结构,由特殊编码的连续内存块组成。文章详细解释了压缩列表的构成和各个属性的含义,以及如何通过指针来计算表尾节点的地址。压缩列表适用于列表键和哈希键中只包含少量小整数值和短字符串的情况。通过使用压缩列表,可以有效减少内存占用,提升Redis的性能。 ... [详细]
  • Skywalking系列博客1安装单机版 Skywalking的快速安装方法
    本文介绍了如何快速安装单机版的Skywalking,包括下载、环境需求和端口检查等步骤。同时提供了百度盘下载地址和查询端口是否被占用的命令。 ... [详细]
  • 本文介绍了Python高级网络编程及TCP/IP协议簇的OSI七层模型。首先简单介绍了七层模型的各层及其封装解封装过程。然后讨论了程序开发中涉及到的网络通信内容,主要包括TCP协议、UDP协议和IPV4协议。最后还介绍了socket编程、聊天socket实现、远程执行命令、上传文件、socketserver及其源码分析等相关内容。 ... [详细]
  • 生成式对抗网络模型综述摘要生成式对抗网络模型(GAN)是基于深度学习的一种强大的生成模型,可以应用于计算机视觉、自然语言处理、半监督学习等重要领域。生成式对抗网络 ... [详细]
  • CSS3选择器的使用方法详解,提高Web开发效率和精准度
    本文详细介绍了CSS3新增的选择器方法,包括属性选择器的使用。通过CSS3选择器,可以提高Web开发的效率和精准度,使得查找元素更加方便和快捷。同时,本文还对属性选择器的各种用法进行了详细解释,并给出了相应的代码示例。通过学习本文,读者可以更好地掌握CSS3选择器的使用方法,提升自己的Web开发能力。 ... [详细]
  • android listview OnItemClickListener失效原因
    最近在做listview时发现OnItemClickListener失效的问题,经过查找发现是因为button的原因。不仅listitem中存在button会影响OnItemClickListener事件的失效,还会导致单击后listview每个item的背景改变,使得item中的所有有关焦点的事件都失效。本文给出了一个范例来说明这种情况,并提供了解决方法。 ... [详细]
  • Metasploit攻击渗透实践
    本文介绍了Metasploit攻击渗透实践的内容和要求,包括主动攻击、针对浏览器和客户端的攻击,以及成功应用辅助模块的实践过程。其中涉及使用Hydra在不知道密码的情况下攻击metsploit2靶机获取密码,以及攻击浏览器中的tomcat服务的具体步骤。同时还讲解了爆破密码的方法和设置攻击目标主机的相关参数。 ... [详细]
  • 本文介绍了Oracle数据库中tnsnames.ora文件的作用和配置方法。tnsnames.ora文件在数据库启动过程中会被读取,用于解析LOCAL_LISTENER,并且与侦听无关。文章还提供了配置LOCAL_LISTENER和1522端口的示例,并展示了listener.ora文件的内容。 ... [详细]
  • XML介绍与使用的概述及标签规则
    本文介绍了XML的基本概念和用途,包括XML的可扩展性和标签的自定义特性。同时还详细解释了XML标签的规则,包括标签的尖括号和合法标识符的组成,标签必须成对出现的原则以及特殊标签的使用方法。通过本文的阅读,读者可以对XML的基本知识有一个全面的了解。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • Webmin远程命令执行漏洞复现及防护方法
    本文介绍了Webmin远程命令执行漏洞CVE-2019-15107的漏洞详情和复现方法,同时提供了防护方法。漏洞存在于Webmin的找回密码页面中,攻击者无需权限即可注入命令并执行任意系统命令。文章还提供了相关参考链接和搭建靶场的步骤。此外,还指出了参考链接中的数据包不准确的问题,并解释了漏洞触发的条件。最后,给出了防护方法以避免受到该漏洞的攻击。 ... [详细]
  • 服务器上的操作系统有哪些,如何选择适合的操作系统?
    本文介绍了服务器上常见的操作系统,包括系统盘镜像、数据盘镜像和整机镜像的数量。同时,还介绍了共享镜像的限制和使用方法。此外,还提供了关于华为云服务的帮助中心,其中包括产品简介、价格说明、购买指南、用户指南、API参考、最佳实践、常见问题和视频帮助等技术文档。对于裸金属服务器的远程登录,本文介绍了使用密钥对登录的方法,并提供了部分操作系统配置示例。最后,还提到了SUSE云耀云服务器的特点和快速搭建方法。 ... [详细]
author-avatar
旭峰fd_817
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有