全国产EtherCAT运动控制边缘控制器(二):统一的上位机API接口

电子说

1.2w人已加入

描述

上节课程我们介绍了全国产EtherCAT运动控制边缘控制器ZMC432H的硬件接口与功能,本节课程我们主要讲解一下正运动API函数封装原理以及自定义API封装例程。

一、功能简介

全国产EtherCAT运动控制边缘控制器ZMC432H是正运动的一款软硬件全国产自主可控,运动控制接口兼容EtherCAT总线和脉冲型的独立式运动控制器,最多支持32轴运动控制,同时支持正运动远程HMI功能,能提供网络组态显示,可实时监控和调整参数配置。

运动控制器

ZMC432H具备丰富的硬件接口和控制功能模块,能实现高效稳定的运动控制和实时数据采集,以满足工业控制协同工业互联网的应用需求。ZMC432H内置了Linux系统,可以使用本地的LOCAL接口进行连接,可以做到更快速的指令交互,单条指令与多条指令一次性交互时间为40us左右。

运动控制器

二、统一的API接口

运动控制器

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

各个开发语言都有各自所对应的函数库,所调用的API均一致,这大大提高了可移植性。各个开发语言库的调用方式可参考“ZMotion PC函数库编程手册 V2.1.1”。

文档参考路径:光盘资料4PC函数Zmotion PC函数库编程手册及例程源码。

运动控制器

以下为各个功能部分API指令一览表;

1、控制器连接

 

ZAux_OpenCom 串口连接控制器
ZAux_SetComDefaultBaud 串口通讯参数设置
ZAux_OpenEth 以太网连接控制器
ZAux_OpenPci PCI卡连接
ZAux_Close 关闭控制器连接
ZAux_Setlp 设置控制IP
ZAux_SearchEthlist 搜索当前网段下控制器的IP
ZAux_SearchAndOpenCom 快速与控制器建立连接
ZAux_SearchEth 快速检索IP列表
ZAux_GetMaxPciCards 读取PCI的控制卡个数
ZAux_FastOpen 与控制器建立连接,指定连接的等待时间MotionRT7用此方式连接

 

2、控制器信息获取

 

ZAux_GetControllerInfo 获取控制器卡信息
ZAux_GetSysSpecification 获取控制器最大规格数
ZAux_GetRtcTime 读取控制器RTC时间
ZAux_SetRtcTime 设置控制器RTC时间

 

3、基本轴参数设置

 

ZAux_Direct_SetAtype 设置轴类型
ZAux_Direct_GetAtype 读取轴类型
ZAux_Direct_SetUnits 设置脉冲当量(units)
ZAux_Direct_GetUnits 读取脉冲当量(units)
ZAux_Direct_SetAccel 设置加速度,单位为units /s/s
ZAux_Direct_GetAccel 读取加速度,单位为units/s/s
ZAux_Direct_SetDecel 设置减速度,单位为units/s/s
ZAux_Direct_GetDecel 读取减速度,单位为units/s/s
ZAux_Direct_SetSpeed 设置轴速度,单位为units/s
ZAux_Direct_GetSpeed 读取轴速度,单位为units/s
ZAux_Direct_SetDpos 设置轴的规划位置,单位为units
ZAux_Direct_GetDpos 读取轴的规划位置,单位为units
ZAux_Direct_SetMpos 设置反馈位置,单位为units
ZAux_Direct_GetMpos 读取反馈位置,单位为units
ZAux_Direct_GetEncoder 获取控制器接收的脉冲数
ZAux_Direct_SetFastDec 设置快速减速度,单位为units/s/s
ZAux_Direct_GetFastDec 读取快速减速度,单位为units/s/s
ZAux_Direct_SetLspeed 设置轴起始速度,单位为units/s
ZAux_Direct_GetLspeed 读取轴起始速度,单位为units/s
ZAux_Direct_SetSramp 设置S曲线设置。0-梯形加减速
ZAux_Direct_GetSramp 读取S曲线设置。0-梯形加减速
ZAux_Direct_GetMspeed 读取反馈速度,单位为units/s
ZAux_Direct_GetVpSpeed 读取当前轴运行的命令速度,单位为units/s
ZAux_Direct_GetIfIdle 读取轴是否运动结束
ZAux_Direct_GetAxisStatus 读取轴的告警状态
ZAux_Direct_GetAxisStopReason 读取轴历史异常停止原因

 

4、基本运动控制

 

ZAux_Direct_Single_Move 单轴相对运动
ZAux_Direct_Single_MoveAbs 单轴绝对运动
ZAux_Direct_Single_Vmove 单轴连续运动
ZAux_Direct_SetJogSpeed 设置JOG时速度
ZAux_Direct_GetJogSpeed 读取JOG时速度
ZAux_Direct_GetFastJog 读取JOG速度输入IN,有输入时,速度由SPEED参数给出。如果没有输入,速度由JOGSPEED参数给出
ZAux_Direct_SetFastJog 设置JOG速度输入IN,有输入时,速度由SPEED参数给出。如果没有输入,速度由JOGSPEED参数给出
ZAux_Direct_SetFwdJog 设置正向JOG输入对应的输入编号-1无效。
ZAux_Direct_GetFwdJog 读取正向JOG输入对应的输入编号-1无效。
ZAux_Direct_SetRevJog 设置负向JOG输入对应的输入编号-1无效。
ZAux_Direct_GetRevJog 读取负向JOG输入对应的输入编号-1无效。

 

5、VR寄存器

 

ZAux_Direct_SetVrf 设置VR寄存器
ZAux_Direct_GetVrf 读取VR寄存器
ZAux_Direct_GetVrInt 整型方式读取VR寄存器

 

6、Table寄存器

 

ZAux_Direct_SetTable 设置系统table寄存器
ZAux_Direct_GetTable 读取系统table寄存器

 

7、Modbus寄存器

 

ZAux_Modbus_Set0x 设置modbus位寄存器
ZAux_Modbus_Get0x 读取modbus位寄存器
ZAux_Modbus_Set4x 设置modbus寄存器(REG)
ZAux_Modbus_Get4x 读取modbus寄存器(REG)
ZAux_Modbus_Set4x_Long Modbus4x寄存器写操作(LONG)
ZAux_Modbus_Get4x_Long Modbus4x寄存器读操作(LONG)
ZAux_Modbus_Set4x_String Modbus字寄存器操作(ASCII)
ZAux_Modbus_Get4x_String Modbus字寄存器操作(ASCII)
ZAux_Modbus_Set4x_Float 设置modbus寄存器(float类型)
ZAux_Modbus_Get4x_Float 读取modbus寄存器(float类型)

 

8、Flash/文件读写

 

ZAux_WriteUFile 向U盘中写文件
ZAux_ReadUFile 从U盘中读取文件
ZAux_FlashWritef 写控制器FLASH空间
ZAux_FlashReadf 读控制器FLASH空间

 

更多API接口详情可以参考“ZMotion PC函数库编程手册 V2.1.1”。

运动控制器

三、在线命令的机制

ZAux_Execute或ZAux_DirectCommand可对Basic指令进行封装。如果使用到没有封装的命令或者想封装自己的函数,可以通过ZAux_Execute发送或ZAux_DirectCommand,或是参照已有代码修改增加相应的函数。发送字符串命令有两种方式,缓冲方式和直接方式。具体如图所示:

运动控制器

直接方式:直接执行单个变量/数组/参数相关命令,此时所有传递的参数必须是具体的数值,不能是表达式;

缓冲方式:可以执行所有命令,并支持表达式作为参数,但是速度慢一些;

以zmcaux.cpp中对已封装的设置运动速度的函数ZAux_Direct_SetSpeed()与获取当前编码器反馈位置的函数ZAux_Direct_GetMpos为例。

程序如下:

 

#include "zmotion.h" #include "zauxdll2.h" int ZAux_Direct_SetSpeed(ZMC_HANDLE handle, int iaxis, float fValue) { char cmdbuff[2048]; char cmdbuffAck[2048]; if (iaxis > MAX_AXIS_AUX) //MAX_AXIS_AUX为zuaxdll2.h中定义的宏,zuaxdll2.h为正运动库头文件 { return ERR_AUX_PARAERR; } sprintf(cmdbuff,"SPEED(%d)=%f",iaxis,fValue);//生成对应命令的字符串 ZAux_DirectCommand(handle,cmdbuff,cmdbuffAck,2048); } int ZAux_Direct_GetMpos(ZMC_HANDLE handle, int iaxis, float fValue) { char cmdbuff[2048]; char cmdbuffAck[2048]; if (iaxis > MAX_AXIS_AUX) { return ERR_AUX_PARAERR; } sprintf(cmdbuff,"MPOS(%d)=%f",iaxis,fValue);//生成对应命令的字符串 ZAux_DirectCommand(handle,cmdbuff,cmdbuffAck,2048); }

 

四、自定义API封装介绍及例程

1、自定义API封装

自定义封装API的原理实际上是利用了在线命令的机制,上位机生成由各种ZBASIC指令来达到自己想要的功能。

ZAux库便是直接利用ZBASIC命令通过ZAux_Execute方式或ZAux_DirectCommand方式发送到控制器上,相应函数可以参考ZBASIC手册对应的命令介绍。

ZAux库是完全开源库,源代码皆可从官网下载,可以在源代码中添加用户自定义的函数,用户也可以新增库进行封装。

2、实用封装例程

(1)直接获取多种类型数据

用户若想要获取多种数据,如轴的命令位置,轴的反馈位置,板卡上的IO点等等,往往都是通过多种单独独立的函数获取不同的数据,这样堆积,会导致读写次数的上位,导致程序的卡顿。为了提升一个上位程序读取控制器数据的速度,往往可以通过自定义一个函数,快速的把数据传输到上位程序上面来,而不是通过多次循环来获取不同类型的数据。

例:假设有一个简易的三轴平台,需要读取轴0,轴1,轴2的命令位置,反馈位置,以及控制器板卡上的输入口0,输入口32,输出口0,输出口33,以及三个轴的状态。

运动控制器

获取数据程序如下:

 

// test1.cpp : 定义控制台应用程序的入口点。 #include "stdafx.h" #include < windows.h > #include "zmotion.h" #include "zauxdll2.h" void commandCheckHandler(const char *command, int ret) { if (ret)//非0则失败 { printf("%s fail!return code is %dn", command, ret); } } /************************************************************* Description: //我的自定义直接获取数据函数 Input: //handle 卡链接 iaxisNum 轴的总数量 iaxislist 轴号列表 fDposlist 输出的命令位置值 fMposlist 输出的反馈位置值 iAxisstatuslist 输出的轴状态位置值,按位对应 startIn 要获取起始的IN编号 endIn 要获取结束的IN编号 iIn 输出的IN状态,按位对应 startOut 要获取起始的OUT编号 endOut 要获取结束的OUT编号 iOut 输出的OUT状态,按位对应 Output: // Return: //错误码 *************************************************************/ int Demo_Direct_MyGetData(ZMC_HANDLE handle,int iaxisNum, int* iaxislist, float* fDposlist,float* fMposlist,int32* iAxisstatuslist,int startIn , int endIn,int *iIn,int startOut , int endOut,int *iOut) { char cmdbuff[2048]; char tempbuff[2048]; char cmdbuffAck[20480]; //若传进来的地址为空,则退出 if(NULL == iaxislist || NULL == fDposlist || NULL == fMposlist || NULL == iAxisstatuslist || NULL == iIn || NULL == iOut) { return ERR_AUX_PARAERR; } //若传进来的结束编号小于起始编码,则退出 if ((endIn< startIn) || (endOut< startOut)) { return ERR_AUX_PARAERR; } int ret=0; int i; //生成命令 sprintf(cmdbuff, "?"); //拼接DPOS for (i=0;i< iaxisNum;i++) { sprintf(tempbuff,"DPOS(%d),",iaxislist[i]);//生成对应命令的字符串 strcat(cmdbuff, tempbuff);//字符串拼接 if (strlen(cmdbuff) >1000) { return ERR_AUX_PARAERR; //参数错误,字符串拼接过长 } } //拼接MPOS for (i=0;i< iaxisNum;i++) { sprintf(tempbuff,"MPOS(%d),",iaxislist[i]);//生成对应命令的字符串 strcat(cmdbuff, tempbuff);//字符串拼接 if (strlen(cmdbuff) >1000) { return ERR_AUX_PARAERR; //参数错误,字符串拼接过长 } } //拼接AXISSTATUS for (i=0;i< iaxisNum;i++) { sprintf(tempbuff,"AXISSTATUS(%d),",iaxislist[i]);//生成对应命令的字符串 strcat(cmdbuff, tempbuff);//字符串拼接 if (strlen(cmdbuff) >1000) { return ERR_AUX_PARAERR; //参数错误,字符串拼接过长 } } int32 ostart,istart,iend,oend; //一次最多32个 bool addflag; addflag=false; int32 temp; //一次最多32个 int32 temp2; //一次最多32个 temp=endIn-startIn+1; if (temp%32 == 0) { temp=temp/32; } else { temp=temp/32+1; } //拼接IN for (i=0;i< temp;i++) { istart = startIn+32*i; iend =istart+31; if (iend >endIn) { iend=endIn; } //生成命令 sprintf(tempbuff, "IN(%d,%d),", istart,iend); strcat(cmdbuff, tempbuff);//字符串拼接 if (strlen(cmdbuff) >1000) { return ERR_AUX_PARAERR ; //参数错误,字符串拼接过长 } } temp2=endOut-startOut+1; if (temp2%32 == 0) { temp2=temp2/32; } else { temp2=temp2/32+1; } //拼接OUT for (i=0;i< temp2;i++) { ostart = startOut+32*i; oend =ostart+31; if (oend >endOut) { oend=endOut; } //生成命令 sprintf(tempbuff, "OUT(%d,%d)", ostart,oend); strcat(cmdbuff, tempbuff);//字符串拼接 if (i< temp-1) { strcat(cmdbuff, ",");//字符串拼接 } if (strlen(cmdbuff) >1000) { return ERR_AUX_PARAERR; //参数错误,字符串拼接过长 } } printf("拼接的字符串:n",cmdbuff); printf("%sn",cmdbuff); ret=ZAux_DirectCommand(handle,cmdbuff,cmdbuffAck,2048); if(ERR_OK != ret) { return ret; } //printf("%sn",cmdbuffAck); //printf("%dn",strlen(cmdbuffAck)); // if(0 == strlen(cmdbuffAck)) { return ERR_NOACK; } float ftempbuff[200]; int itempbuff[200]; ZAux_TransStringtoFloat(cmdbuffAck,iaxisNum*2,ftempbuff);//字符串转换为浮点数 //DPOS输出 for(i=0;i< iaxisNum;i++) { //printf("%fn",ftempbuff[i]); fDposlist[i]=ftempbuff[i]; } //MPOS输出 for(i=0;i< iaxisNum;i++) { //printf("%fn",ftempbuff[i+iaxisNum]); fMposlist[i]=ftempbuff[i+iaxisNum]; } ZAux_TransStringtoInt(cmdbuffAck,iaxisNum*3+temp2+temp,itempbuff);//字符串转换为整形 //AXISSTATUS输出 for(i=0;i< iaxisNum;i++) { //printf("%dn",itempbuff[i+iaxisNum*2]); iAxisstatuslist[i]=itempbuff[i+iaxisNum*2]; } //IN输出 for(i=0;i< temp;i++) { //printf("%dn",itempbuff[i+iaxisNum*3]); iIn[i]=itempbuff[i+iaxisNum*3]; } //OUT输出 for(i=0;i< temp2;i++) { //printf("%dn",itempbuff[i+iaxisNum*3+temp]); iOut[i]=itempbuff[i+iaxisNum*3+temp]; } return ERR_OK; } int _tmain(int argc, _TCHAR* argv[]) { char *ip_addr = (char *)"127.0.0.1"; //控制器IP地址 ZMC_HANDLE handle = NULL; //连接句柄 int ret = ZAux_OpenEth(ip_addr, &handle); //连接控制器 if (ERR_SUCCESS != ret) { printf("控制器连接失败!n"); handle = NULL; Sleep(2000); return -1; } printf("控制器连接成功!n"); int axis[4]={0,1,2,4}; float d_dpos[4]; float d_mpos[4]; int32 d_axis_status[4]; int d_in[10]; int d_out[10]; ret=Demo_Direct_MyGetData(handle,3,axis,d_dpos,d_mpos,d_axis_status,0,32,d_in,0,33,d_out); int i; printf("获取到的轴命令位置:n"); for (i=0;i< 3;i++) { printf("t轴%d :%f",i,d_dpos[i]); } printf("n"); printf("获取到的轴反馈位置:n"); for (i=0;i< 3;i++) { printf("t轴%d :%f",i,d_mpos[i]); } printf("n"); printf("获取到的轴状态(按位对应):n"); for (i=0;i< 3;i++) { printf("t轴%d :%d",i,d_axis_status[i]); } printf("n"); printf("获取到的输入口状态:n"); int j=0; int tempval; for (i=0;i<=32;i++) { if (((i%32)==0)&&(i >0) ) { j++; } //转换成位 tempval=d_in[j] >>(i-32*j); printf(" IN(%d):%d",i,tempval &(0x01)); if (((i%8)==0)&&(i >0) ) { printf("n"); } } printf("n"); printf("获取到的输出口状态:n"); j=0; for (i=0;i<=33;i++) { if (((i%32)==0)&&(i >0) ) { j++; } //转换成位 tempval=d_out[j] >>(i-32*j); printf(" OUT(%d):%d",i,tempval &(0x01)); if (((i%8)==0)&&(i >0) ) { printf("n"); } } printf("n"); Sleep(20000); ret = ZAux_Close(handle); //关闭连接 commandCheckHandler("ZAux_Close", ret) ;//判断指令是否执行成功 printf("connection closed!n"); handle = NULL; return 0; }

 

(2)一行命令执行多条不同类型缓冲指令

一般点胶行业、木工行业用的较多的是连续轨迹,连续轨迹之间有插入缓冲输出,如果把运动和连续轨迹分开发送的话,难免会有局限性,可以通过自己单独封装运动函数,来达到一行命令执行多个函数的效果。

例:假设控制一个XY两轴平台,从坐标点(0,0),(100,0)(输出口0输出50ms) → (100,100)(输出口0输出50ms) → (0,100)(输出口0输出50ms) → (0,0)(输出口0输出50ms)的轨迹,则可以通过自己封装,用一条函数,快速发送下去。

一行命令执行多个函数程序如下:

 

// test1.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include < windows.h > #include "zmotion.h" #include "zauxdll2.h" void commandCheckHandler(const char *command, int ret) { if (ret)//非0则失败 { printf("%s fail!return code is %dn", command, ret); } } /************************************************************* Description: //我的自定义运动函数 Input: //handle 卡链接 iMoveLen 填写的运动长度 iaxisNum 参与运动总轴数 iaxislist 轴号列表 fPoslist 距离列表 iout 缓冲输出口 outlist 缓冲输出列表(每条运动,决定是否输出,0为不输出,1为在运动后输出) outtime 缓冲输出时间 Output: // Return: //错误码 *************************************************************/ int Demo_Direct_MyMoveABS(ZMC_HANDLE handle,int iMoveLen,int iaxisNum, int* iaxislist, float* fPoslist,int iout,int *outlist,int outtime) { char cmdbuff[2048]; char tempbuff[2048]; char cmdbuffAck[20480]; //若传进来的地址为空,则退出 int ret=0; int i; //先读取剩余直线缓冲 int iBuffLen = 0; ret = ZAux_Direct_GetRemain_LineBuffer(handle,iaxislist[0],&iBuffLen); if(iBuffLen <= iMoveLen*2) { return 1002; //运动缓冲不够 } //生成命令 sprintf(cmdbuff, "BASE("); //拼接运动轴列表 for (i=0;i< iaxisNum-1;i++) { sprintf(tempbuff,"%d,",iaxislist[i]);//生成对应命令的字符串 strcat(cmdbuff, tempbuff);//字符串拼接 if (strlen(cmdbuff) >1000) { return ERR_AUX_PARAERR; //参数错误,字符串拼接过长 } } sprintf(tempbuff,"%d)n",iaxislist[i]);//生成对应命令的字符串 strcat(cmdbuff,tempbuff); //拼接运动 for (i=0;i< iMoveLen;i++) { //printf("%d,%dn",i*iaxisNum,i*iaxisNum+1); if (outlist[i]==0) //该段运动不输出 { strcat(cmdbuff, "MoveAbs("); sprintf(tempbuff,"%f,%f)n",fPoslist[i*iaxisNum],fPoslist[i*iaxisNum+1]);//生成对应命令的字符串 strcat(cmdbuff, tempbuff);//字符串拼接 } else if (outlist[i]==1) { strcat(cmdbuff, "MoveAbs("); sprintf(tempbuff,"%f,%f)n",fPoslist[i*iaxisNum],fPoslist[i*iaxisNum+1]);//生成对应命令的字符串 strcat(cmdbuff, tempbuff);//字符串拼接 strcat(cmdbuff, "Move_op2("); sprintf(tempbuff,"%d,%d,%d)n",iout,1,outtime);//生成对应命令的字符串 strcat(cmdbuff, tempbuff);//字符串拼接 } else { return ERR_AUX_PARAERR;//参数错误 } } printf("拼接的字符串:n"); printf("%sn",cmdbuff); if (strlen(cmdbuff) >1000) { return ERR_AUX_PARAERR; //参数错误,字符串拼接过长 } ret=ZAux_DirectCommand(handle,cmdbuff,cmdbuffAck,2048); return ret; } int _tmain(int argc, _TCHAR* argv[]) { char *ip_addr = (char *)"127.0.0.1"; //控制器IP地址 ZMC_HANDLE handle = NULL; //连接句柄 int ret = ZAux_OpenEth(ip_addr, &handle); //连接控制器 if (ERR_SUCCESS != ret) { printf("控制器连接失败!n"); handle = NULL; Sleep(2000); return -1; } printf("控制器连接成功!n"); ret =ZAux_Direct_SetAtype(handle,0,1);//设置轴0轴类型为1 commandCheckHandler("ZAux_Direct_SetAtype", ret) ;//判断指令是否执行成功 ret =ZAux_Direct_SetAtype(handle,1,1);//设置轴1轴类型为1 commandCheckHandler("ZAux_Direct_SetAtype", ret) ;//判断指令是否执行成功 ret =ZAux_Direct_SetUnits(handle,0,100);//设置轴0脉冲当量为100 commandCheckHandler("ZAux_Direct_SetUnits", ret) ;//判断指令是否执行成功 ret =ZAux_Direct_SetUnits(handle,1,100);//设置轴1脉冲当量为100 commandCheckHandler("ZAux_Direct_SetUnits", ret) ;//判断指令是否执行成功 ret =ZAux_Direct_SetAccel(handle,0,500);//设置轴0加速度 commandCheckHandler("ZAux_Direct_SetAccel", ret) ;//判断指令是否执行成功 ret =ZAux_Direct_SetAccel(handle,1,500);//设置轴1加速度 commandCheckHandler("ZAux_Direct_SetAccel", ret) ;//判断指令是否执行成功 ret =ZAux_Direct_SetDecel(handle,0,500);//设置轴0减速度 commandCheckHandler("ZAux_Direct_SetDecel", ret) ;//判断指令是否执行成功 ret =ZAux_Direct_SetDecel(handle,1,500);//设置轴1减速度 commandCheckHandler("ZAux_Direct_SetDecel", ret) ;//判断指令是否执行成功 ret =ZAux_Direct_SetDpos(handle,0,0);//设置轴0 DPOS清0 commandCheckHandler("ZAux_Direct_SetDpos", ret) ;//判断指令是否执行成功 ret =ZAux_Direct_SetDpos(handle,1,0);//设置轴1 DPOS清0 commandCheckHandler("ZAux_Direct_SetDpos", ret) ;//判断指令是否执行成功 ret =ZAux_Direct_SetSpeed(handle,0,100);//设置轴0速度 commandCheckHandler("ZAux_Direct_SetDecel", ret) ;//判断指令是否执行成功 ret =ZAux_Direct_SetSpeed(handle,1,100);//设置轴1速度 commandCheckHandler("ZAux_Direct_SetDecel", ret) ;//判断指令是否执行成功 ret =ZAux_Direct_SetMerge(handle,0,1);//设置开启连续插补(开启主轴的即可,如轴0,轴1插补,轴0为主轴,主轴号取决于连续插补运动指令轴列表的第一个轴号) int axis[2]={0,1}; float POS[12]={0,0,0,100,100,100,100,0,0,0}; int otlist[5]={0,1,1,1,1}; ZAux_Trigger(handle);//触发示波器 ret = Demo_Direct_MyMoveABS(handle,5,2,axis,POS,0,otlist,50);// commandCheckHandler("Demo_Direct_MyMoveABS", ret) ;//判断指令是否执行成功 Sleep(20000); ret = ZAux_Close(handle); //关闭连接 commandCheckHandler("ZAux_Close", ret) ;//判断指令是否执行成功 printf("connection closed!n"); handle = NULL; return 0; }

 

示波器采样波形如图所示:

运动控制器

 

运动控制器

本次,正运动技术全国产EtherCAT运动控制边缘控制器(二):统一的上位机API接口,就分享到这里。

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

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

审核编辑 黄宇

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分