技术频道

娓娓工业
您现在的位置: 中国传动网 > 技术频道 > 应用方案 > 步进的光栅尺全闭环EtherCAT运动控制器ZMC432CL-V2(三):C#编程调试

步进的光栅尺全闭环EtherCAT运动控制器ZMC432CL-V2(三):C#编程调试

时间:2025-02-28 15:11:01来源:深圳市正运动技术有限公司

导语:​ZMC432CL-V2高性能多轴运动控制器是一款兼容EtherCAT总线和脉冲型的独立式运动控制器,具备高速实时反馈功能,支持脉冲全闭环控制,能够实现高精度、高响应速度的运动控制。

  上节课程给大家介绍了ZMC432CL-V2硬件接口(详情点击→步进的光栅尺全闭环EtherCAT运动控制器ZMC432CL-V2(一):硬件接口介绍)。

  本节主要讲解如何通过C#编写程序调试ZMC432CL-V2的脉冲闭环功能。

  一、ZMC432CL-V2产品简介

  ZMC432CL-V2高性能多轴运动控制器是一款兼容EtherCAT总线和脉冲型的独立式运动控制器,具备高速实时反馈功能,支持脉冲全闭环控制,能够实现高精度、高响应速度的运动控制。高精度定位,有效消除机械传动误差,满足高精密加工场景应用要求。

正运动

  1.ZMC432CL-V2硬件功能

  (1)丰富的运动控制功能:支持直线、圆弧、空间圆弧、螺旋插补等。(2)硬件接口丰富:支持脉冲轴(带编码器反馈)和EtherCAT总线轴,具备24路输入和12路输出的通用IO,部分为高速IO,2路模拟量输出(DA)。(3)EtherCAT刷新周期最快达250us,满足高速通信需求。(4)支持4通道硬件比较输出、硬件定时器、运动中精准输出,适用于多通道视觉飞拍等场合。(5)支持掉电检测、掉电存储,多种程序加密方式,能够有效防止系统故障,保护项目工程文件数据,并提高系统的可靠性。(6)通过纯国产IDE开发环境RTSys进行项目开发,可实时仿真、在线跟踪以及诊断与调试,简便易用,支持多种高级上位机语言联合编程进行二次开发。

正运动

  ZMC432CL-V2产品介绍视频

  更多关于ZMC432CL-V2详情介绍点击→步进控制的光栅尺全闭环解决方案:32轴EtherCAT总线运动控制器ZMC432CL-V2。

  二、C#语言如何调用ZMotion的动态库进行项目开发

  (一)新建WinForm项目并添加函数库

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

正运动

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

正运动

  3.找到厂家提供的光盘资料里面的C#函数库,路径如下。

  1)进入厂商提供的光盘资料找到“04PC函数”文件夹,并点击进入。

正运动

  2)选择“01 PC函数库V2.1”文件夹。

正运动

  3)选择“Windows平台”文件夹。

正运动

  4)选择“C#”文件夹,里面有32位和64位的动态库和例程。

正运动

正运动

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

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

正运动

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

正运动

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

正运动

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

正运动

  三、PC函数介绍

  1.PC函数手册可在光盘资料查看,具体路径如下。

正运动

  2.控制器/卡接口之链接控制器,获取链接句柄。

正运动

正运动

  3.万能指令之在线命令。

  有一些使用频率较低的Basic指令我们没有封装到上位机的辅助库中,如果用户上位机需要调用对应的Basic指令的话,可以通过在线命令自行进行相关指令封装。

正运动

正运动

  四、C#编写例程调试ZMC432CL-V2的脉冲闭环功能

  1.通过在线命令封装脉冲闭环功能对应的上位机接口。

  (1)右击【项目】→【添加】→【新建项】→【新建C#类】,这里新建了一个MyFullCloseLoop的C#类。

正运动

  (2)查询Basic对应指令的使用说明,封装一个设置轴比例增益的上位机接口。

正运动

  /// /// 设置轴的比例增益/// /// 连接句柄/// 轴号/// 比例增益P的值/// 错误码public int ZAux_Direct_SetPGain(IntPtr handle, int iaxis, float fValue){ String cmdbuff; //定义命令字符串 //判断轴数是否超标 StringBuilder cmdbuffAck = new StringBuilder(1024); if (iaxis > MAX_AXIS_AUX) { return ERR_AUX_PARAERR; } //生成命令,根据Basic指令的用法格式去拼接命令字符串 cmdbuff = string.Format("P_Gain({0}) = {1}", iaxis, fValue); //调用命令执行函数 return zmcaux.ZAux_DirectCommand(handle, cmdbuff, cmdbuffAck, 2048); }

  (3)查询Basic对应指令的使用说明,封装一个获取轴比例增益的上位机接口。

  ·

  /// /// 获取轴的比例增益/// /// 连接句柄/// 轴号/// 获取的轴比例增益P的值/// 错误码public int ZAux_Direct_GetPGain(IntPtr handle, int iaxis, ref float fValue){ String cmdbuff; //定义命令字符串 StringBuilder cmdbuffAck = new StringBuilder(1024); //定义接受返回的结果字符串 //判断轴数是否超标 if (iaxis > MAX_AXIS_AUX) { return ERR_AUX_PARAERR; } //生成命令 ?类似于C的printf指令,用于打印,打印出来的字符串通过cmdbuffAck去接收 cmdbuff = string.Format("?P_Gain({0}) ", iaxis); //调用命令执行函数 int iresult = zmcaux.ZAux_Execute(handle, cmdbuff, cmdbuffAck, 2048); if (ERR_OK != iresult) { return iresult; } //解析返回的字符串 if (cmdbuffAck.Length == 0) { return ERR_NOACK; } else { fValue = float.Parse(cmdbuffAck.ToString()); } return ERR_OK;}

  (4)封装好的脉冲闭环功能相关的上位机接口。

正运动

  2.C#闭环功能的测试例程的编写。

      (1)脉冲闭环测试例程界面的设计。

正运动

  (2)【连接】按钮如何连接控制器。

  int Err = 0; //接口返回的错误码int LinkMode = 2; //FastOpen接口连接类型的介绍 1-COM 2-ETH 4-PCI 5-LOCALErr = zmcaux.ZAux_FastOpen(LinkMode, Buffer, 2000, out g_handle);if (Err == 0){ // 修改按钮文字 LinkStatus.Text = "链接状态:OK"; // 修改按钮背景色 LinkStatus.BackColor = Color.FromArgb(192, 255, 192); //相关参数初始化 AxisParaSet(); //进行PID参数的初始化 PidParaSet(); //打开定时器 Timer.Start();}else{ // 修改按钮文字 LinkStatus.Text = "链接状态:Ng"; // 修改按钮背景色 LinkStatus.BackColor = Color.FromArgb(255, 192, 192); //关闭定时器 Timer.Stop();}

  (3)【更新PID参数】按钮如何打开和关闭脉冲闭环功能,如何更新PID参数。

  ·

  //将上位机设置的PID参数更新到控制器private int PidParaSet(){ float TempFloat = 0; float TempDpos = 0, TempMpos = 0; bool TempInt = false; MyFullClosedLoop CloseLoop = new MyFullClosedLoop(); String CompareStr = "闭环已开"; String TempStr = IsClosedLoop.Text; //打开全闭环去控制轴运动 if (TempStr == CompareStr) { //获取轴位置,如果DPOS和MPOS相差太大不能打开脉冲闭环,保证安全 zmcaux.ZAux_Direct_GetDpos(g_handle, int.Parse(AxisId.Text), ref TempDpos); zmcaux.ZAux_Direct_GetMpos(g_handle, int.Parse(AxisId.Text), ref TempMpos); if ((TempDpos - TempMpos) > 4 || (TempDpos - TempMpos < -4)) { Console.WriteLine("规划位置和反馈位置相差太大,无法启动闭环功能!!!!"); return -1; } //更新比例增益 CloseLoop.ZAux_Direct_SetPGain(g_handle, int.Parse(AxisId.Text), float.Parse(text_ParaP.Text)); //更新积分增益 CloseLoop.ZAux_Direct_SetIGain(g_handle, int.Parse(AxisId.Text), float.Parse(text_ParaI.Text)); //更新微分增益 CloseLoop.ZAux_Direct_SetDGain(g_handle, int.Parse(AxisId.Text), float.Parse(text_ParaD.Text)); //更新速度前馈增益 CloseLoop.ZAux_Direct_SetVffGain(g_handle, int.Parse(AxisId.Text), float.Parse(text_ParaVF.Text)); //更新加速度前馈增益 CloseLoop.ZAux_Direct_SetAffGain(g_handle, int.Parse(AxisId.Text), float.Parse(text_ParaAF.Text)); //更新速度增益 CloseLoop.ZAux_Direct_SetOvGain(g_handle, int.Parse(AxisId.Text), float.Parse(text_ParaOV.Text)); //注意:在打开servo之前打开encoder_servo后要完成一次atype由0变为4的切换,否则会报axis:0 config not support Servo. //1、先打开axis_enable 和 encoder_servo zmcaux.ZAux_Direct_SetAxisEnable(g_handle, int.Parse(AxisId.Text), 1); CloseLoop.ZAux_Direct_SetEncoderServo(g_handle, int.Parse(AxisId.Text), 1); Thread.Sleep(20); CloseLoop.ZAux_Direct_GetEncoderServo(g_handle, int.Parse(AxisId.Text), ref TempInt); if (TempInt) { //2、完成一次Atype由0变为4的切换 zmcaux.ZAux_Direct_SetAtype(g_handle, int.Parse(AxisId.Text), 0); Thread.Sleep(20); zmcaux.ZAux_Direct_SetAtype(g_handle, int.Parse(AxisId.Text), 4); //3、打开Servo CloseLoop.ZAux_Direct_SetServo(g_handle, int.Parse(AxisId.Text), 1); Thread.Sleep(10); CloseLoop.ZAux_Direct_GetServo(g_handle, int.Parse(AxisId.Text), ref TempInt); if (TempInt) { Console.WriteLine("闭环参数配置完成, 轴全闭环功能打开成功。"); } else { Console.WriteLine("轴闭环开关Servo打开失败, 导致脉冲全闭环开启失败!!!"); return -1; } } else { Console.WriteLine("轴编码器闭环EncoderServo打开失败, 导致脉冲全闭环开启失败!!!"); return -1; }

  } else { //关闭全闭环的功能 //1、关闭EncoderServo CloseLoop.ZAux_Direct_SetEncoderServo(g_handle, int.Parse(AxisId.Text), 0); Thread.Sleep(20); CloseLoop.ZAux_Direct_GetEncoderServo(g_handle, int.Parse(AxisId.Text), ref TempInt); if (TempInt) { Console.WriteLine("轴EncoderServo关闭失败!!!"); return -1; } //2、关闭EncoderServo后需要完成ATYPE的切换,保证完全关闭闭环功能 zmcaux.ZAux_Direct_SetAtype(g_handle, int.Parse(AxisId.Text), 0); Thread.Sleep(10); zmcaux.ZAux_Direct_SetAtype(g_handle, int.Parse(AxisId.Text), 4); //3、关闭Servo CloseLoop.ZAux_Direct_SetServo(g_handle, int.Parse(AxisId.Text), 0); Thread.Sleep(20); CloseLoop.ZAux_Direct_GetServo(g_handle, int.Parse(AxisId.Text), ref TempInt); if (TempInt) { Console.WriteLine("轴Servo关闭失败!!!"); return -1; } } return 0;}

  (4)【更新轴参数】按钮如何完成轴参数的更新。

  ·

  //更新轴参数private void AxisParaSet(){ //设置最大随动误差FE_LIMIT zmcaux.ZAux_Direct_SetFeLimit(g_handle, int.Parse(AxisId.Text), 500); //更新编码器齿轮比 (如果发N个脉冲,实际编码器反馈M个脉冲,编码器齿轮比要设置成 N/M) zmcaux.ZAux_Direct_EncoderRatio(g_handle, int.Parse(AxisId.Text), int.Parse(EncoderRatioMol.Text), int.Parse(EncoderRatioDenom.Text)); //更新脉冲当量,一般脉冲当量设置成机台运动1mm需要的脉冲数 zmcaux.ZAux_Direct_SetUnits(g_handle, int.Parse(AxisId.Text), float.Parse(text_ParaUnits.Text)); //全闭环的功能需要把ATYPE设置成4 zmcaux.ZAux_Direct_SetAtype(g_handle, int.Parse(AxisId.Text), 4); //更新速度 zmcaux.ZAux_Direct_SetSpeed(g_handle, int.Parse(AxisId.Text), float.Parse(text_ParaSpeed.Text)); //更新加速度、减速度 zmcaux.ZAux_Direct_SetAccel(g_handle, int.Parse(AxisId.Text), float.Parse(text_ParaAccel.Text)); zmcaux.ZAux_Direct_SetDecel(g_handle, int.Parse(AxisId.Text), float.Parse(text_ParaDecel.Text)); StringBuilder Buff = new StringBuilder(512); //是否启用SS曲线 if (CurveIsSS.Checked) { //启用SS曲线,VP_MODE模式设置成7即可 //上位机旧库没有现成设置VP_MODE的接口,直接在线命令去封装,在线命令是万能接口 string CmdBuff = string.Format("VP_MODE({0}) = 7 ", int.Parse(AxisId.Text)); zmcaux.ZAux_DirectCommand(g_handle, CmdBuff, Buff, 512); } else { //启用S曲线,VP_MODE模式设置成0即可 //上位机旧库没有现成设置VP_MODE的接口,直接在线命令去封装,在线命令是万能接口 string CmdBuff = string.Format("VP_MODE({0}) = 0 ", int.Parse(AxisId.Text)); zmcaux.ZAux_DirectCommand(g_handle, CmdBuff, Buff, 512); //S曲线模式,S曲线时间sramp是有效果的,需要设置一下 zmcaux.ZAux_Direct_SetSramp(g_handle, int.Parse(AxisId.Text), float.Parse(text_ParaSramp.Text)); }}

  (5)【手动】按钮如何控制脉冲轴的点动与寸动。

  ·

  //X-鼠标按下private void ButtonHangRev_MouseDown(object sender, MouseEventArgs e){ if (IsInchMode.Checked) { //寸动运动 zmcaux.ZAux_Direct_Single_Move(g_handle, int.Parse(AxisId.Text), -1 * float.Parse(InchDis.Text)); } else { //手动运动 zmcaux.ZAux_Direct_Single_Vmove(g_handle, int.Parse(AxisId.Text), -1); }}//X-鼠标松开private void ButtonHangRev_MouseUp(object sender, MouseEventArgs e){ if (IsInchMode.Checked == false) { //手动运动停止 zmcaux.ZAux_Direct_Single_Cancel(g_handle, int.Parse(AxisId.Text), 2); }}//X+鼠标按下private void ButtonHangFwd_MouseDown(object sender, MouseEventArgs e){ if (IsInchMode.Checked) { //寸动运动 zmcaux.ZAux_Direct_Single_Move(g_handle, int.Parse(AxisId.Text), 1 * float.Parse(InchDis.Text)); } else { //手动运动 zmcaux.ZAux_Direct_Single_Vmove(g_handle, int.Parse(AxisId.Text), 1); }}//X+鼠标松开private void ButtonHangFwd_MouseUp(object sender, MouseEventArgs e){ if (IsInchMode.Checked == false) { //手动运动停止 zmcaux.ZAux_Direct_Single_Cancel(g_handle, int.Parse(AxisId.Text), 2); }}

  五、通过RTSys的示波器对比开环控制和全闭环控制的情况

  示波器的使用可以参考正运动小助手的历史推文《运动控制看的更清楚细致!RTSys示波器功能简介 (qq.com)》。

  1.开环控制情况分析

正运动

正运动

  测试发现:步进驱动器的开环控制,运动过程中随动误差(规划位置和光栅尺反馈位置的差值)一直维持在0.02个用户单位左右(这里一个用户单位即一个UNITS设置的是1mm),当运动结束时光栅尺的反馈位置和指令规划位置也不相等,大概差了0.0015个用户单位,折算为脉冲数是0.0015*用户单位=3个脉冲。

  2.闭环控制情况分析

正运动

正运动

  测试发现:步进驱动器的闭环控制,运动过程中随动误差(规划位置和光栅尺反馈位置的差值)除了启动和停止以外大部分保持在0个脉冲当量左右,相比较开环控制有较大的提升,当运动结束时光栅尺的反馈位置和指令规划位置也是相等的。

  六、总结

  1.启用控制器闭环的时候注意要在打开encoder_servo后,打开servo之前要完成一次ATYPE从0到4的切换,这样才可以正常打开控制器闭环的功能。

       2.启用控制器闭环同时还需要打开单轴使能axis_enable,这样才能保证控制器闭环的正常启用。

正运动

  3.为保证控制器闭环功能的完全关闭,在关闭ENCODER_SERVO后需要完成一次 ATYPE从0到4的切换,这样才能保证控制器闭环功能完全关闭。

正运动

完整代码获取地址

正运动

  本次,正运动技术步进的光栅尺全闭环EtherCAT运动控制器ZMC432CL-V2(三):C#编程调试,就分享到这里。

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

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

标签: 正运动

点赞

分享到:

上一篇:如何扩大制造业的可持续性

下一篇:创新附件:用于肘节夹的传感支架

传动网版权与免责声明:凡本网注明[来源:传动网]的所有文字、图片、音视和视频文件,版权均为传动网(m.jsovip.com)独家所有。如需转载请与0755-82949061联系。任何媒体、网站或个人转载使用时须注明来源“传动网”,违反者本网将追究其法律责任。

本网转载并注明其他来源的稿件,均来自互联网或业内投稿人士,版权属于原版权人。转载请保留稿件来源及作者,禁止擅自篡改,违者自负版权法律责任。

网站简介|会员服务|联系方式|lol外围投注网站英雄联盟 |版权信息|网站地图|友情链接|法律支持|意见反馈|反水投注网站

传动网-足球世界杯直播平台官网与智能制造的全媒体“互联网+”创新服务平台

网站客服服务咨询采购咨询媒体合作

www.jsovip.com Copyright ©2005 - 2025 ,All Rights Reserved 世预赛直播观看在线 版权所有
粤ICP备 14004826号 | 营业执照证书 | 不良信息举报中心 | 粤公网安备 44030402000946号

Baidu
反水投注网站