The value of Zmotion is to bring customers more success!
上节课程我们介绍了全国产EtherCAT运动控制边缘控制器ZMC432H的硬件接口与功能,本节课程我们主要讲解一下正运动API函数封装原理以及自定义API封装例程。
01
功能简介
全国产EtherCAT运动控制边缘控制器ZMC432H是正运动的一款软硬件全国产自主可控,运动控制接口兼容EtherCAT总线和脉冲型的独立式运动控制器,最多支持32轴运动控制,同时支持正运动远程HMI功能,能提供网络组态显示,可实时监控和调整参数配置。
02
统一的API接口
以下为各个功能部分API指令一览表;
2、控制器信息获取
3、基本轴参数设置
4、基本运动控制
5、VR寄存器
7、Modbus寄存器
8、Flash/文件读写
更多API接口详情可以参考“ZMotion PC函数库编程手册 V2.1.1”。
03
在线命令的机制
ZAux_Execute或ZAux_DirectCommand可对Basic指令进行封装。如果使用到没有封装的命令或者想封装自己的函数,可以通过ZAux_Execute发送或ZAux_DirectCommand,或是参照已有代码修改增加相应的函数。
#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); }
04
自定义API封装介绍及例程
自定义封装API的原理实际上是利用了在线命令的机制,上位机生成由各种ZBASIC指令来达到自己想要的功能。
ZAux库是完全开源库,源代码皆可从官网下载,可以在源代码中添加用户自定义的函数,用户也可以新增库进行封装。
教学视频可点击“正运动技术PC函数库辅助库的封装”查看。
2、实用封装例程
(1)直接获取多种类型数据
// test1.cpp : 定义控制台应用程序的入口点。 #include "stdafx.h" #include #include "zmotion.h" #include "zauxdll2.h" void commandCheckHandler(const char *command, int ret) { if (ret)//非0则失败 { printf("%s fail!return code is %d\n", 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) || (endOut1000) { return ERR_AUX_PARAERR ; //参数错误,字符串拼接过长 } } temp2=endOut-startOut+1; if (temp2%32 == 0) { temp2=temp2/32; } else { temp2=temp2/32+1; } //拼接OUT for (i=0;iendOut) { oend=endOut; } //生成命令 sprintf(tempbuff, "OUT(%d,%d)", ostart,oend); strcat(cmdbuff, tempbuff);//字符串拼接 if (i1000) { return ERR_AUX_PARAERR; //参数错误,字符串拼接过长 } } printf("拼接的字符串:\n",cmdbuff); printf("%s\n",cmdbuff); ret=ZAux_DirectCommand(handle,cmdbuff,cmdbuffAck,2048); if(ERR_OK != ret) { return ret; } //printf("%s\n",cmdbuffAck); //printf("%d\n",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("%f\n",ftempbuff[i]); fDposlist[i]=ftempbuff[i]; } //MPOS输出 for(i=0;i<iaxisNum;i++) { //printf("%f\n",ftempbuff[i+iaxisNum]); fMposlist[i]=ftempbuff[i+iaxisNum]; } ZAux_TransStringtoInt(cmdbuffAck,iaxisNum*3+temp2+temp,itempbuff);//字符串转换为整形 //AXISSTATUS输出 for(i=0;i<iaxisNum;i++) { //printf("%d\n",itempbuff[i+iaxisNum*2]); iAxisstatuslist[i]=itempbuff[i+iaxisNum*2]; } //IN输出 for(i=0;i<temp;i++) { //printf("%d\n",itempbuff[i+iaxisNum*3]); iIn[i]=itempbuff[i+iaxisNum*3]; } //OUT输出 for(i=0;i<temp2;i++) { //printf("%d\n",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>(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;i0) ) { 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; }
// test1.cpp : 定义控制台应用程序的入口点。 // #include "stdafx.h" #include #include "zmotion.h" #include "zauxdll2.h" void commandCheckHandler(const char *command, int ret) { if (ret)//非0则失败 { printf("%s fail!return code is %d\n", 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;i1000) { return ERR_AUX_PARAERR; //参数错误,字符串拼接过长 } } sprintf(tempbuff,"%d)\n",iaxislist[i]);//生成对应命令的字符串 strcat(cmdbuff,tempbuff); //拼接运动 for (i=0;i1000) { 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; }
3、例程讲解可点击→正运动技术自定义API封装例程查看。
▼
更多精彩内容请关注“ 正运动小助手 ”公众号,需要相关开发环境与例程代码,请咨询正运动技术销售工程师:400-089-8936。
本文由正运动技术原创,欢迎大家转载,共同学习,一起提高中国智能制造水平。文章版权归正运动技术所有,如有转载请注明文章来源。
正运动技术专注于运动控制技术研究和通用运动控制软硬件产品的研发,是国家级高新技术企业。正运动技术汇集了来自华为、中兴等公司的优秀人才,在坚持自主创新的同时,积极联合各大高校协同运动控制基础技术的研究,是国内工控领域发展最快的企业之一,也是国内少有、完整掌握运动控制核心技术和实时工控软件平台技术的企业。主要业务有:运动控制卡_运动控制器_EtherCAT运动控制卡_EtherCAT控制器_运动控制系统_视觉控制器__运动控制PLC_运动控制_机器人控制器_视觉定位_XPCIe/XPCI系列运动控制卡等等。