运动控制卡应用开发教程之VC6.0

供稿:深圳市正运动技术有限公司

  • 关键词:正运动,运动控制卡
  • 摘要:今天,我们来讲解一下正运动技术运动控制卡应用开发教程之VC6.0。

今天,我们来讲解一下正运动技术运动控制卡应用开发教程之VC6.0。


在正式学习之前,我们先了解一下正运动技术的运动控制卡ECI2418和ECI2618。这两款产品分别是4轴,6轴运动控制卡。


image.png


ECI2418支持4轴脉冲输入与编码器反馈,板载24点输入,16点输出,2AD,2DA,支持手轮接口,其中特定输出支持高速PWM控制。


image.png


ECI2618支持6轴脉冲输入与编码器反馈,板载24点输入,16点输出,2AD,2DA,支持手轮接口,其中特定输出支持高速PWM控制。


image.png


ECI2418,ECI2618均使用同一套API函数,均支持C、C++、C#、LabView、Python、Delphi等开发语言,支持VC6.0、VB6.0、Qt、.Net等平台,支持Windows、Linux、WinCE、iMac等操作系统。


一、运动控制卡VC6.0开发流程


1、打开 VC++6.0,新建一个工程。


image.png


2、选择“ MFC APPWizard(exe)”,选择工程保存路径,设置工程名,选择确定。


image.png


3、在应用程序类型选择基本对话框,完成项目新建。


image.png


4、 将产品配套光盘“..\函数库\dll”文件夹中的动态链接库“zmotion.dll、 zauxdll.dll”、头文件“zauxdll2.h”和lib文件“zauxdll.lib”复制到工程文件夹中。


image.png


5、选择“Project”菜单下的“Settings…”菜单项。


6、切换到“Link”标签页,在“Object\library modules”栏中输入lib文件名:zauxdll.lib。


image.png


7、在应用程序文件中加入函数库头文件的声明,如:#include “zauxdll2.h”,并定义一个控制器的链接句柄。


image.png


8、至此,用户就可以在VC6.0中调用函数库中的任何函数,开始编写应用程序,具体函数的用法的功能可以参考光盘资料里面的:ZMotion PC函数库编程手册。


image.png


9、参考ZMotion PC函数库编程手册的链接控制器的函数说明,在ECIDlg:OnInitDialog()函数中添加链接控制器代码ZAux_OpenEth(“192.168.0.11”,&g_handle);即可链接控制器。


image.png


10、通过MOVE按钮,控制控制器进行插补运动。


(1)右键MOVE按钮,选择属性,设置按钮ID。


image.png


(2)右键MOVE按钮选择事件。


image.png


(3)新建相关事件。


image.png


(4)在事件处理函数中添加插补运动函数。


image.png



11、编译运行就可以通过PC控制控制器了。


如果编译报错:无法打开预编译的头文件:没有这样的文件或目录。


请选择“Project”菜单下的“Settings…”菜单项,然后选择c/c++进行如下设置。


image.png


二、VC6.0例程讲解


1、在我们的光盘资料里有很多VC6.0的例程,通过这些历程可以更容易的上手我们的控制器。


image.png


2、单轴运动例程


a、通过以太网链接到指定IP的控制器;


b、设置运动轴参数;


c、选择运动轴对象;


d、选择运动方式,实现持续运动和寸动;


image.png


3、实现步骤


(1)搜索IP,链接控制器。


   A、先将相关控件拖拽到UI界面,并设置对应的事件处理函数。


image.png


  B、下拉框事件处理函数,实现自动搜索IP。

  先根据ZMotion PC 编程手册,在下拉框事件处理函数添加控制器IP搜索函数“ZAux_SearchEthlist()”,然后将获取到的IP字符串进行解析,具体解析方法请参考例程。 

//自动搜索IP

void CECIDlg::OnDropdownIPList() 

{

  /*自动搜索IP地址*/

    char buffer[10240];

  int32 iresult;

    /*搜索当前网段下的 IP 地址   详情请参考:zmotion pc 编程手册*/

    iresult = ZAux_SearchEthlist(buffer, 10230, 100);

    if(ERR_OK != iresult)

    {

        return;

    }

    CComboBox   *m_pEthList;

    m_pEthList = (CComboBox *)GetDlgItem(IDC_IPList);

    if(NULL == m_pEthList)

    {

        return;

    }

    /*从字符串转换成IP*/

    int ipos =0;

    const char * pstring;

    pstring = buffer;


    for(int j= 0; j< 20;j++)

    {

        char buffer2[256];

        buffer2[0] = '\0';


        /*跳过空格*/

        while(' ' == pstring[0])

        {

            pstring++;

        }


        ipos = sscanf(pstring , "%s", &buffer2);

        if(EOF  == ipos)

        {

            break;

        }

        /*跳过字符*/

        while((' ' != pstring[0]) && ('\t' != pstring[0]) && ('\0' != pstring[0]))

        {

            pstring++;

        } 

        if(CB_ERR != m_pEthList->FindString(0, buffer2))

        {

            continue;

        }

        if('\0' == buffer2)

        {

            return;

        } 

        /*加入*/

        m_pEthList->AddString(buffer2);

    }

    return;  

}

  C、点击链接按钮链接控制器。


  根据ZMotion PC 编程手册,在链接按钮点击事件处理函数中添加网口连接控制器的函数“ZAux_OpenEth()”,即可实现链接控制器的功能。 


//链接控制器

void CECIDlg::OnLink() 

{

  char   buffer[256]; 

  int32 iresult;

  /*如果已经链接先关闭控制器链接*/

  if(NULL != g_handle)

  {

      ZAux_Close(g_handle);

    g_handle = NULL;

  }

  /*获取下拉框里的IP地址*/

  GetDlgItemText(IDC_IPList, buffer, 55);

  buffer[255] = '\0';

  /*通过网口方式与控制器进行连接*/

  iresult = ZAux_OpenEth(buffer, &g_handle);

  /*如果链接成功*/

    if(ERR_SUCCESS == iresult)

    {

    SetWindowText("已链接");

    /*开起定时器,用于信息更新*/

    SetTimer( 1, 100, NULL );

    }

}

  D、点击断开按钮断开链接控制器。


  根据ZMotion PC 编程手册,在断开按钮点击事件处理函数中添加断开链接控制器的函数“ZAux_Close()”,即可实现断开链接控制器的功能。


//关闭链接

void CECIDlg::OnClose() 

{

  if(NULL != g_handle)

  {

    /*关定时器*/

    KillTimer(1);

    /*关闭链接*/

    ZAux_Close(g_handle);        

    g_handle = NULL;

    SetWindowText("未链接");

  }  

}

(2)选择轴,并对所选择的dpos和当前速度以及运动状态进行监控。


  A、先将相关控件拖拽到UI界面,并设置对应的事件处理函数。


image.png


  B、通过X、Y、Z、R 4个单选按钮的事件处理函数,实现对轴的选择。


//选择X轴

void CECIDlg::OnRadioX() 

{

        UpdateData( true );

        m_nAxis = 0;

        UpdateData( false );

}

//选择Y轴

void CECIDlg::OnRadioY() 

{

        UpdateData( true );

        m_nAxis = 1;

        UpdateData( false );


}


//选择Z轴

void CECIDlg::OnRadioZ() 

{

        UpdateData( true );

        m_nAxis = 2;

        UpdateData( false );


}

//选择R轴

void CECIDlg::OnRadioR() 

{

        UpdateData( true );

        m_nAxis = 3;

        UpdateData( false );        

}

  C、通过定时器实现对轴状态的实时更新。


//定时器

void CECIDlg::OnTimer(UINT nIDEvent) 

{

  if(NULL == g_handle)

  {

    MessageBox(_T("链接断开"));

    return ;

  }

  if(1 == nIDEvent)

  {  /*获取当前轴位置*/

    CString string;

    float position = 0;

    ZAux_Direct_GetDpos( g_handle,m_nAxis,&position);          

    string.Format("当前位置:%.2f", position );

    GetDlgItem( IDC_CurDPOS )->SetWindowText( string );

    /*获取当前轴速度*/

    float NowSp = 0;

    ZAux_Direct_GetVpSpeed( g_handle,m_nAxis,&NowSp);          

    string.Format("当前速度:%.2f", NowSp );

    GetDlgItem( IDC_CurSPEED)->SetWindowText( string );

    /*判断当前轴状态*/

    int status = 0; 

    ZAux_Direct_GetIfIdle(g_handle, m_nAxis,&status);           

    if (status == -1)

    {

      GetDlgItem( IDC_CurSTATE )->SetWindowText( "当前状态:停  止" );

    }else

    {

      GetDlgItem( IDC_CurSTATE )->SetWindowText( "当前状态:运动中" );

    }  

  }

  CDialog::OnTimer(nIDEvent);

}

(3)实现in0-in7,out0-out7状态的读取。


image.png


  使用接口ZAux_GetModbusIn() 和ZAux_GetModbusOut(),对io状态进获取。并封装成一个子函数将该函数添加到定时器超时处理函数中,用于io状态的更新。

//IO监控

void CECIDlg::IOGet()

{

  uint8 in, out, i=0,j=0,k=0;

  char  buff[128]={0};

  /*获取输入口状态*/

  ZAux_GetModbusIn (g_handle, 0, 7, &in);  //获取in0-in7状态

  /*十进制转二进制*/

  itoa(in, buff, 2);

  j=0;

  for( i=0; i<8; i++)

  {

    if((48 == buff[i])||(49 == buff[i]))

    {

      j++;  

    }  

  }

  for(i=0 ; i<(8-j); i++)

  {

    for(k=7; k>0; k--)

    {

      buff[k] = buff[k-1];

    }

    buff[0]=48;

  }

  sprintf(buff, "输入口IN0-7 状态:%c %c %c %c %c %c %c %c", buff[7], buff[6],buff[5],buff[4],buff[3],buff[2],buff[1],buff[0]);

  GetDlgItem( IDC_IN )->SetWindowText( buff );

  /*获取输出口状态*/

  ZAux_GetModbusOut (g_handle, 0, 7, &out);//获取out0-out7状态

  /*十进制转二进制*/

  itoa(out, buff, 2);

  j=0;

  for( i=0; i<8; i++)

  {

    if((48 == buff[i])||(49 == buff[i]))

    {

      j++;  

    }  

  }

  for(i=0 ; i<(8-j); i++)

  {

    for(k=7; k>0; k--)

    {

      buff[k] = buff[k-1];

    }

    buff[0]=48;

  }

  sprintf(buff, "输出口OUT0-7状态:%c %c %c %c %c %c %c %c",buff[7], buff[6],buff[5],buff[4],buff[3],buff[2],buff[1],buff[0]);

  GetDlgItem( IDC_OUT )->SetWindowText( buff );  

}

(4)对控制器参数进行设置。


  A、先将相关控件拖拽到UI界面,并设置参数生效按钮的事件处理函数。


image.png


  B、设置各个编辑框的成员变量,先右键编辑框选择建立类导向,再选择成员变量进行设置。


image.png

image.png


  C、然后在参数生效按钮的事件处理函数中添加参数设置的相关函数接口,对控制器参数进行设置。


//控制器参数设置

void CECIDlg::OnSetPara() 

{

  /*刷新参数*/

  UpdateData(true);

  /*设置脉冲当量*/

  ZAux_Direct_SetUnits(g_handle, m_nAxis, m_units);

  /*设定速度,加减速*/

  ZAux_Direct_SetLspeed(g_handle, m_nAxis, m_LSpeed);

  ZAux_Direct_SetSpeed(g_handle, m_nAxis, m_speed);

  ZAux_Direct_SetAccel(g_handle, m_nAxis, m_acc);

  ZAux_Direct_SetDecel(g_handle, m_nAxis, m_dec);

  /*设定S曲线时间 设置为0表示梯形加减速*/ 

  ZAux_Direct_SetSramp(g_handle, m_nAxis, m_sramp);  

}

(5)控制控制器运动。


  A、在UI界面再添加两组单选框、寸动距离编辑框,以及两个按钮。


image.png


  B、两组单选框用于运动方向和运动方式的设置,通过他们的事件处理函数对标志位变量m_moveatype和m_movedir进行设置。


//设置为正方向

void CECIDlg::OnRadioFwd() 

{

        UpdateData( true );

        m_movedir = 1;

        UpdateData( false );

}

//设置为负方向

void CECIDlg::OnRadioRev() 

{

        UpdateData( true );

        m_movedir = -1;

        UpdateData( false );


}


//设置为寸动

void CECIDlg::OnRadioMove() 

{

        UpdateData( true );

        m_moveatype = 0;

        UpdateData( false );


}

//设置为持续运动

void CECIDlg::OnRadioVmove() 

{

        UpdateData( true );

        m_moveatype = 1;

        UpdateData( false );


}

  C、通过启动按钮的事件处理函数来启动控制器进行运动。


//启动

void CECIDlg::OnRun() 

{

  if(NULL == g_handle)

  {

    MessageBox(_T("链接断开状态"));

    return ;

  }

  /*刷新参数*/

  UpdateData(true);

  int status = 0; 

  ZAux_Direct_GetIfIdle(g_handle, m_nAxis,&status);  //判断当前轴状态

  /*已经在运动*/

  if (status == 0) 

  return; 

  /*设定轴类型 1-脉冲轴类型*/   

  ZAux_Direct_SetAtype(g_handle, m_nAxis, 1);

  /*触发示波器,方便通过ZDevelop软件里面的示波器对运动情况进行监控*/

  ZAux_Trigger(g_handle);

  if( 1 == m_moveatype )

  {  /*持续运动*/

    ZAux_Trigger(g_handle);

    ZAux_Direct_Single_Vmove(g_handle, m_nAxis, m_movedir);  

  }

  else

  {  

    /*寸动*/

    ZAux_Direct_Single_Move(g_handle, m_nAxis, m_distance*(m_movedir));

  }

  UpdateData(false);      

}

  D、通过停止按钮的事件处理函数来停止控制器运动。

//停止

void CECIDlg::OnStop() 

{

  ZAux_Direct_Single_Cancel(g_handle,m_nAxis,2);  

}

(6)编译运行演示。


  A、编译运行示教例程


image.png


  B、同时通过ZDevelop软件连接同一个控制器,对运动控制效果进行观察。


  以下是轴参数的显示,IN/OP显示,示波器中 DPOS  MSPEED显示。


image.png


今天,正运动技术运动控制卡应用开发教程之VC6.0就分享到这里。更多精彩内容,请关注我们的公众号。



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


关于正运动技术


正运动技术是一家专注于运动控制技术研发与应用的国家级高新技术企业,主要从事运动控制器、运动控制卡、IO扩展模块、运动显控一体机等系列产品的研发、生产、销售和服务。


公司汇集了来自华为、中兴等公司的优秀人才,在坚持自主创新的同时,积极联合各大高校致力于运动控制技术研究与应用,是国内工控领域发展最快的企业之一,也是国内完整掌握运动控制核心技术和实时工控软件平台技术的企业。

发布时间:2020年9月25日 9:32  人气:   审核编辑(王静 )
更多内容请访问(深圳市正运动技术有限公司
相关链接

我有需求