產品分類

      當前位置: 首頁 > 傳感測量產品 > 數據采集產品 > 運動控制卡

      類型分類:
      科普知識
      數據分類:
      運動控制卡

      運動控制卡應用開發教程之硬件比較輸出

      發布日期:2022-10-09 點擊率:36

      • 關鍵詞:正運動技術,運動控制卡


      • 摘要:今天,正運動小助手為大家分享一下應用C++開發一個硬件比較輸出例程。



      今天,正運動小助手為大家分享一下應用C++開發一個硬件比較輸出例程。


      我們主要從新建MFC項目,添加函數庫講起,再了解PC函數用,最后通過項目實戰——硬件比較輸出例程講解,來讓大家熟悉運動控制卡的PC開發。


      image.png

      image.png


      在正式學習之前,我們先了解一下正運動技術的運動控制卡ECI2828。這款產品是8軸運動控制卡。


      正運動技術ECI2828 EtherCAT總線型運動控制卡,相對之前發布的ECI2618,新增了EtherCAT總線接口,電機軸數增加到8個,板載24+16點輸入,16+16點輸出(每個軸接口含2路通用輸入和2路通用輸出,可以做伺服使能、報警清除、到位信號、報警信號等控制);每軸輸出脈沖頻率可達10MHz;通過 CAN 總線,可擴展到512 個隔離輸入或輸出口。ECI2828支持硬件比較輸出、精準輸出、飛拍等功能。


      image.png


      image.png


      運動控制卡ECI2828,支持C++、C#、LabVIEW、VB、Delphi、Linux、.Net平臺、iMac、Python、Matlab等,統一的上位機API函數接口,具有開放、兼容、簡單、易用等功能特性。


      一新建MFC項目 添加函數庫


      1.在VS2015菜單“文件”→“新建”→ “項目”,啟動創建項目向導。


      image.png


      2.選擇開發語言為“Visual C++”和程序類型“MFC應用程序”。


      image.png


      3.下一步即可。


      image.png


      4.選擇類型為“基于對話框”,下一步或者完成。下一步則往后繼續配置,完成就直接完成即可。這里就不需要再配置了,無關緊要的,只要這個類型選好就行,其他的可以在項目中編輯。


      image.png


      5.找到正運動技術廠家提供的光盤資料,路徑如下(64位庫為例):

      (1)進入光盤資料找到PC函數文件夾。


      (2)選擇函數庫2.1。


      (3)Windows平臺。


      image.png


      (4)根據需要選擇對應的函數庫這里選擇64位庫。


      image.png


      (5)解壓C++的壓縮包,里面有C++對應的函數庫。


      image.png


      (6)函數庫具體路徑如下。


      image.png


      6.將廠商提供的C++的庫文件和相關頭文件復制到新建的項目里面。


      image.png


      7.在項目中添加靜態庫和相關頭文件。

      靜態庫:zauxdll.lib, zmotion.lib


      相關頭文件:zauxdll2.h, zmotion.h


      (1)先右擊頭文件,接著依次選擇:“添加”→“現有項”。


      image.png


      (2)在彈出的窗口中依次添加靜態庫和相關頭文件。


      image.png


      8.聲明用到的頭文件和定義控制器連接句柄。


      image.png


      至此項目新建完成。


      二查看PC函數手冊 了解PC函數用法


      1.PC函數手冊也在光盤資料里面,具體路徑如下:


      image.png


      2.PC編程,一般先根據控制器連接方式選擇對應的連接函數連接控制器,返回控制器句柄。接著用返回的控制器句柄,實現對控制器的控制。


      3.比如通過網口連接控制器,先使用ZAux_OpenEth()鏈接控制器,獲取控制器句柄handle。


      image.png


      4.通過獲取到的控制器句柄,使用ZAux_Direct_SetTable,來設置控制器的TABLE寄存器的數值。

      image.png


      5.通過獲取到的控制器句柄,使用ZAux_Direct_HwPswitch2,來啟動并設置控制器的硬件比較輸出的模式。

      image.png

      image.png


      6.通過獲取到的控制器句柄,使用ZAux_Direct_Regist()來啟動并設置控制器的鎖存方式。

      image.png


      三項目實戰之硬件比較輸出例程講解


      1.硬件比較輸出


      運動控制器內有位置比較單元,硬件比較輸出是通過比較軸是否到達設定位置,來操作輸出口動作,一般使用時將編碼器位置與設定位置比較,當編碼器的位置到達一個設定比較位置時,觸發相應輸出口電平翻轉一次。


      如下圖所示,到達設置的位置1,電平翻轉,到達位置2電平再次翻轉,到達位置3電平再翻轉,直達比較完所有的點后,電平維持最后一次翻轉后的狀態。


      image.png


      2.例程以建立板卡的連接,然后設置并開啟硬件比較輸出,將硬件比較輸出的輸出口和鎖存的輸入口進行連接,從而通過鎖存記錄硬件比較輸出的位置。

      (1)為了實驗室測試方便,采用自發脈沖,同一軸編碼器接收脈沖模式測試。同一個DB26軸接口的脈沖軸和編碼器軸的連接方式(用于鎖存硬件比較輸出的位置),PUL+接EA+、PUL-接EA-、DIR+接EB+、DIR-接EB-。(或者直接通過脈沖型伺服電機進行位置反饋。)


      (2)例程界面。


      image.png


      3.例程簡易流程圖。


      image.png


      4.通過網口連接控制器,獲取控制器連接句柄。

      //連接控制器

      void Ctest_PswitchDlg::onBnClickedOpen()

      {

        char   buffer[256]; 

        int32 iresult;

        //從下拉框中獲取IP地址

        GetDlgItemText(IDC_IPLIST,buffer,255);

        buffer[255] = '?';

        //通過網口連接控制器

        iresult = ZAux_OpenEth(buffer, &g_handle);

        if(ERR_SUCCESS != iresult)

        {

          g_handle = NULL;

          MessageBox(_T("鏈接失敗"));

          SetWindowText("未鏈接");

          return;

        }

        SetWindowText("已鏈接");

        SetTimer(0,100,NULL);

      }

      5.通過運動按鈕的事件處理函數去設置硬件比較輸出的模式,并開始軸運動。

      (1)通過對UI界面的控件添加對應的變量,實現硬件比較輸出的模式的參數輸入。


      image.png


      (2)運動按鈕事件處理函數。

      //運動

      void Ctest_PswitchDlg::onBnClickedStartmove()      

      {

        m_RegistCount = 0;

        ShowRegistList();

        UpdateData(TRUE);

      //設置軸參數

        ZAux_Direct_SetAtype(g_handle, m_AxisNum, 1);

        ZAux_Direct_SetUnits(g_handle, m_AxisNum, 1000);

        ZAux_Direct_SetSpeed(g_handle, m_AxisNum, 200);

        ZAux_Direct_SetAccel(g_handle, m_AxisNum, 2000);

        ZAux_Direct_SetDecel(g_handle, m_AxisNum, 2000);

        //關閉硬件比較輸出(停止并刪除沒有完成的比較點)

        ZAux_Direct_HwPswitch2(g_handle, m_AxisNum, 2, 0, 0, 0, 0, 0, 0);

        //開啟硬件比較輸出  MODE:1

        if (m_POS_IfOpen == false)           //比較完成一次后需要重新調用HwPswitch           

        {

          //將比較點填入TABLE

          ZAux_Direct_SetTable(g_handle, m_POS_StartTable, m_POS_EndTable- m_POS_StartTable+1, fPointPos);

          //開啟硬件比較輸出

          ZAux_Direct_HwPswitch2(g_handle, m_AxisNum, 1, m_POS_out, m_POS_OutStatus, m_POS_StartTable, m_POS_EndTable, m_POS_dir, 0);

        }

        else

        {

          //關閉硬件比較輸出

          ZAux_Direct_HwPswitch2(g_handle, m_AxisNum, 2, 0, 0, 0, 0, 0, 0);      

        }

      //打開示波器

        ZAux_Trigger(g_handle);

        ZAux_Direct_SetDpos(g_handle, m_AxisNum, 0);

      //開始軸運動(絕對位置)

        ZAux_Direct_Single_MoveAbs(g_handle, m_AxisNum, m_Start_Pos);

        ZAux_Direct_Single_MoveAbs(g_handle, m_AxisNum, m_End_Pos); 

      }

      6.根據設置情況判斷是否開啟鎖存,并設置鎖存模式。

      //啟動或停止鎖存

      void Ctest_PswitchDlg::onBnClickedRegistStart()    

      {

        int iret = 0;

        UpdateData(TRUE);

        if(m_Regist_IfOpen == FALSE)

        {

          m_RegistCount = 0;

          //必須是編碼器軸才可以鎖存

          iret = ZAux_Direct_SetAtype(g_handle,m_RegistAxis,6);        

          //設置鎖存模式

          int ReglistListSel  = ((CComboBox *) GetDlgItem(IDC_REGIST_MODE))->GetCurSel() ;

          if(ReglistListSel >= 0 && ReglistListSel <=3)

          {

            RegistMode =  ReglistListSel +1;

          }

          else if(ReglistListSel == 4 || ReglistListSel ==5)

          {

            RegistMode = 10 + ReglistListSel;

          }

          else if(ReglistListSel > 5 || ReglistListSel < 9)

          {

            RegistMode = 12 + ReglistListSel;    

          }

          //開啟鎖存

          iret = ZAux_Direct_Regist(g_handle,m_RegistAxis,RegistMode);

          SetTimer(1,5,NULL);


          m_Regist_IfOpen = TRUE;

          SetDlgItemTextA(IDC_REGIST_START,_T("停止鎖存"));

          ((CComboBox *)GetDlgItem(IDC_REGIST_MODE))->EnableWindow(FALSE);

          ShowRegistList();

        }

        else

        {

          KillTimer(1);

          m_Regist_IfOpen = FALSE;

          SetDlgItemTextA(IDC_REGIST_START,_T("啟動鎖存"));

          ((CComboBox *)GetDlgItem(IDC_REGIST_MODE))->EnableWindow(TRUE);

        }

      }

      7.通過定時器1,更新鎖存信息。

      void Ctest_PswitchDlg::onTimer(UINT_PTR nIDEvent)        //定時器刷新

      {

        if(NULL != g_handle)

        {  

          CString str;

          if(nIDEvent == 1)

          {

            int iret = 0;

            int MarkStatus = 0;

            float RegistPos;

            //判斷鎖存是否觸發

            if(RegistMode >= 0 && RegistMode < 4)

            {

              iret = ZAux_Direct_GetMark(g_handle,m_RegistAxis,&MarkStatus);  

            }

            else if(RegistMode >= 14 || RegistMode < 16)

            {

              iret = ZAux_Direct_GetMarkB(g_handle,m_RegistAxis,&MarkStatus);  

            }

            else if(RegistMode >= 18 || RegistMode < 20)

            {  

              float tempc;

              iret = ZAux_Direct_GetParam(g_handle,"MARKC",m_RegistAxis,&tempc);  

              MarkStatus = (int)tempc;

            }

            else if(RegistMode >= 20 || RegistMode < 22)

            {

              float tempd;

              iret = ZAux_Direct_GetParam(g_handle,"MARKD",m_RegistAxis,&tempd);  

              MarkStatus = (int)tempd;

            }

            //讀取鎖存的位置

            if(MarkStatus == -1)

            {

              if(RegistMode >= 0 && RegistMode < =4)

              {

                iret = ZAux_Direct_GetRegPos(g_handle,m_RegistAxis,&RegistPos);        

              }

              else if(RegistMode >= 14 || RegistMode < 16)

              {

                iret = ZAux_Direct_GetRegPosB(g_handle,m_RegistAxis,&RegistPos);  

              }

              else if(RegistMode >= 18 || RegistMode < 20)

              {  

            iret = ZAux_Direct_GetParam(g_handle,"REG_POSC",m_RegistAxis,&RegistPos);

              }

              else if(RegistMode >= 20 || RegistMode < 22)

              {

            iret = ZAux_Direct_GetParam(g_handle,"REG_POSD",m_RegistAxis,&RegistPos);        }

              m_RegistList.InsertItem(m_RegistCount,"");

              str.Format(_T("%d"), m_RegistCount);

              m_RegistList.SetItemText(m_RegistCount,0,str);

              str.Format(_T("%.3f"), RegistPos);

              m_RegistList.SetItemText(m_RegistCount,1,str);  

              m_RegistCount++;

      //重新觸發鎖存

              iret = ZAux_Direct_Regist(g_handle,m_RegistAxis,RegistMode);    

            }

            str.Format(_T("鎖存觸發狀態:%d 次數:%d"), MarkStatus,m_RegistCount);

            SetDlgItemTextA(IDC_STATUS_REGIST,str);  

          }

        }

        CDialogEx::onTimer(nIDEvent);

      }

      8.通過停止按鈕的事件處理函數來停止運動。


      //停止

      void Ctest_PswitchDlg::onBnClickedStopmove()      

      {

      int iret = ZAux_Direct_Single_Cancel(g_handle, m_AxisNum, 2);  

      }         

      9.編譯運行演示。


      (1)將硬件比較輸出的輸出口(out0)和鎖存的輸入口(in0)用導線進行連接,將軸0的DB26接口上的脈沖軸和編碼器軸進行連接。


      (2)編譯并運行例程。


      image.png


      (3)同時通過ZDevelop軟件連接同一個控制器,通過示波器對運動過程進行監控。


      image.png


      本次,正運動技術的C++開發之硬件比較輸出就分享到這里,更多精彩內容請關注“正運動小助手”公眾號。


      本文由正運動技術原創,歡迎大家轉載,共同學習,一起提高中國智能制造水平。文章版權歸正運動技術所有,如有轉載請注明文章來源。



      下一篇: PLC、DCS、FCS三大控

      上一篇: VPLC系列機器視覺運動

      推薦產品

      更多
      主站蜘蛛池模板: 久久精品一区二区三区AV| 深田咏美AV一区二区三区| 无码人妻精品一区二区三区99性| 国产成人午夜精品一区二区三区| 中文字幕一区二区三区四区 | 亚洲国产成人久久综合一区 | 日本中文字幕一区二区有码在线| 久久精品日韩一区国产二区| 久久国产免费一区二区三区| 一区二区三区在线看| 日韩三级一区二区| 色一乱一伦一图一区二区精品| 无码国产亚洲日韩国精品视频一区二区三区 | 国产乱人伦精品一区二区 | 91一区二区在线观看精品| 久久久久人妻精品一区三寸蜜桃 | 秋霞无码一区二区| 无码人妻少妇色欲AV一区二区| 国产亚洲一区二区在线观看| 国产AV国片精品一区二区| 一区二区日韩国产精品| 精品无码成人片一区二区| 国产精品成人一区无码| 波多野结衣电影区一区二区三区 | 黑人一区二区三区中文字幕| 国产在线观看91精品一区| 国产激情一区二区三区在线观看| 成人h动漫精品一区二区无码| 色一情一乱一区二区三区啪啪高 | 日韩精品无码一区二区中文字幕| 无码人妻AⅤ一区二区三区| 一区二区三区四区免费视频| 日韩精品无码免费一区二区三区 | 日韩AV片无码一区二区不卡| 国产精品日韩欧美一区二区三区| 午夜一区二区在线观看| 波多野结衣av高清一区二区三区| 一级毛片完整版免费播放一区| 国产成人高清视频一区二区| 亚洲国产成人一区二区三区 | 天天爽夜夜爽人人爽一区二区|