今天,正運動技術為大家分享一下應用ZMC408SCAN開放式激光振鏡運動控制器的C++開發,實現激光振鏡打標。
除了C++還支持使用其他上位機軟件來開發,上位機程序運行時需要動態庫“zmotion.dll”,上位機開發調試時可以把ZDevelop軟件同時連接到控制器輔助調試。
01 ZMC408SCAN控制器介紹
ZMC408SCAN是正運動技術新推出的一款支持EtherCAT總線的開放式激光振鏡運動控制器,專為工業激光+振鏡+運動控制方面的應用而設計。通過EtherCAT總線和脈沖軸接口能實現多軸聯動運動控制。
ZMC408SCAN支持ETHERNET、EtherCAT、USB、CAN、RS485、RS232等通訊接口,通過CAN、EtherCAT總線可以連接各個擴展模塊,從而擴展數字量、模擬量或運動軸。
(1)ZMC408SCAN內置高精度PSO位置同步輸出功能,在加工圓角、曲線部分時即使進行了減速調整,在高速加工的場合,也能控制激光輸出的間距保持恒定;
(2)支持激光振鏡控制和振鏡反饋,包含2個振鏡接口,支持2D振鏡和3D振鏡,配合不帶加減速的運動指令MOVESCAN,拐角處振鏡加工自動延時,完成精準高效的激光控制,提高激光加工設備的產能;
(3)通過指令在運動中靈活的調節激光開光/關光延時,響應快,精確到us級別的控制,且設置過程簡單,大大縮短了工程師的調參時間;
(4)自帶LASER激光器控制接口,支持IPG、YLR、YLS等類型激光電源,還帶一個EXIO擴展IO接口,通過定制轉接板,靈活控制市場上主流的各種激光器;
(5)支持PC同時控制16個ZMC408SCAN控制器同時工作,形成一種振鏡陣列的激光加工;
(6)板載4路高速差分脈沖輸出,并帶4路高速差分編碼器反饋,支持EtherCAT總線驅動器的控制,支持5軸XYZAC軸的插補,支持振鏡軸與運動軸混合插補;
(7)支持直線插補、任意圓弧插補、空間圓弧、螺旋插補、電子凸輪、電子齒輪、同步跟隨、虛擬軸設置等多種運動控制功能。
02 系統架構
下圖為ZMC408SCAN開放式激光控制器的參考架構,支持多種不同類型的激光器控制。
03 上位機和控制器通訊
上位機和控制器通訊調用正運動封裝好的函數庫,提供運動控制和激光控制等眾多函數庫接口,激光振鏡的系統架構參見下圖。
本例采用EtherNET網口連接控制器,通過函數ZAux_OpenEth()建立通訊連接,用戶可在設置好的界面中選擇當前網段下的控制器IP完成連接,控制器出廠IP地址192.168.0.11,參見下圖。
04 激光控制 一、指令介紹
下面是我們程序中用到的接口函數,主要包含激光控制和激光振鏡控制兩部分,程序的實現可直接使用封裝好的接口函數發送命令給控制器。
本例采用FIBER激光器和2D激光振鏡,用到下面的函數接口:
ZAux_Direct_MoveScanAbs:振鏡軸多軸絕對直線插補SCAN運動,不帶加減速過程,我們這里用來控制振鏡軸運動,通過小線段的形式擬合圓形軌跡;
ZAux_Direct_MoveOpDelay:緩沖輸出延時,提前開光時將延時時間設置為負數;
ZAux_Direct_MoveDelay:緩沖輸出延時,我們這里用來延時關光。
激光功率設置: 提供模擬量ZAux_Direct_SetDA、PWM的占空比ZAux_Direct_SetPwmDuty和頻率ZAux_Direct_SetPwmFreq等方式控制 設置振鏡軸拐角處自動延時:
ZAux_Direct_SetCornerMode
1.振鏡軸直線插補
ZAux_Direct_MoveScanAbs絕對運動,ZAux_Direct_MoveScan相對運動。
指令27 | ZAux_Direct_MoveScanAbs | ||||||||||
指令原型 | int32 __stdcall ZAux_Direct_MoveScanAbs(ZMC_HANDLE handle, int imaxaxises, int *piAxislist,float *pfDisancelist) | ||||||||||
指令說明 | 振鏡軸多軸相對直線插補Scan運動。 | ||||||||||
輸入參數 |
|
||||||||||
輸出參數 | / | ||||||||||
返回值 | 成功返回值為0,非0詳見錯誤碼說明。 | ||||||||||
詳細說明 |
插補運動距離X= 運動時間T=X/主軸速度 插補運動時只有主軸速度參數有效,主軸是軸列表數組的第一個軸,運動參照這個軸的參數。 |
2.設置開關光
輸出狀態為0關光,輸出狀態為1開光。
指令1 | ZAux_Direct_SetOp | ||||||||
指令原型 | int32 __stdcall ZAux_Direct_SetOp(ZMC_HANDLE handle, int ionum,uint32 iValue); | ||||||||
指令說明 | 打開輸出口,參見軟件手冊里面的“OP”指令。 | ||||||||
輸入參數 |
|
||||||||
輸出參數 | / | ||||||||
返回值 | 成功返回值為0,非0詳見錯誤碼說明。 | ||||||||
詳細說明 |
ZIO擴展板的IO通道號與撥碼有關,起始值為(16 +撥碼組合值*16),EIO總線擴展IO使用NODE_IO指令,只能設置為8的倍數,詳細查看硬件手冊。 注意IO映射編號要大于控制器自身最大的IO編號,不能與控制器的編號重合。 最多可操作32個輸出口。 |
3.開關光延時
指令13 | ZAux_Direct_MoveDelay | ||||||||
指令原型 | int32 __stdcall ZAux_Direct_MoveDelay(ZMC_HANDLE handle, int iaxis, int itimems) | ||||||||
指令說明 | 運動緩沖里面寫入延時。 | ||||||||
輸入參數 |
|
||||||||
輸出參數 | / | ||||||||
返回值 | 成功返回值為0,非0詳見錯誤碼說明。 | ||||||||
指令示例 |
ZAux_Direct_Single_Move(handle, 0, 100);//軸0正向運動100 ZAux_Direct_MoveDelay(handle, 0,1000);//軸0正向運動100后延時1s,才執行下一條緩沖 |
||||||||
詳細說明 | 前面的運動指令結束時速度會自動降為0,然后延時等待。 |
4.提前/延時開關光
正數時間延時,負數時間提前開關光。
指令14 | ZAux_Direct_MoveOpDelay | ||||||||
指令原型 | int32 __stdcall ZAux_Direct_MoveOpDelay(ZMC_HANDLE handle, float uTime, int nAxis) | ||||||||
指令說明 | 軸緩沖中MOVEOP精準高速輸出口提前/延時輸出。 | ||||||||
輸入參數 |
|
||||||||
輸出參數 | / | ||||||||
返回值 | 成功返回值為0,非0詳見錯誤碼說明。 | ||||||||
指令示例 |
ZAux_Direct_MoveOpDelay(handle,0,-1.5); //后面軸0的MOVE_OP輸出口提前1.5ms動作。 ZAux_Direct_Single_Move(handle, 0, 100);//軸0正向運動100 ZAux_Direct_MoveOp(handle, 0,0, 1);//軸0正向運動100后把out0的狀態置為1 |
||||||||
詳細說明 | 不影響插補軸速度曲線,只對MOVE_OP輸出口進行延時操作,設置負值時表示提前輸出。 |
5.設置激光能量(功率)
通過改變模擬量輸出的電壓值來控制激光能量大小。
指令7 | ZAux_Direct_SetDA | ||||||||
指令原型 | int32 __stdcall ZAux_Direct_SetDA(ZMC_HANDLE handle, int ionum, float fValue); | ||||||||
指令說明 | 打開模擬量輸出口,參見軟件手冊里面的“AOUT”指令。 | ||||||||
輸入參數 |
|
||||||||
輸出參數 | / | ||||||||
返回值 | 成功返回值為0,非0詳見錯誤碼說明。 | ||||||||
詳細說明 |
12位刻度值范圍0~4095對應0~10V電壓。 16位刻度值范圍0~65536對應0~10V電壓。 |
6.PWM占空比
通過設置PWM的占空比來調整激光頻率,在開始打軌跡之前一定要先設置好。
指令4 | ZAux_Direct_SetPwmDuty | ||||||||
指令原型 | int32 __stdcall ZAux_Direct_SetPwmDuty(ZMC_HANDLE handle, int ionum, float fValue); | ||||||||
指令說明 | pwm占空比設置,參見軟件手冊里面的“PWM_DUTY”指令。 | ||||||||
輸入參數 |
|
||||||||
輸出參數 | / | ||||||||
返回值 | 成功返回值為0,非0詳見錯誤碼說明。 | ||||||||
詳細說明 |
PWM只能通過設置占空比為0來關閉,不能通過設置PWM頻率為0實現,PWM頻率一定要在PWM開關之前調整。 占空比指有效電平占整個周期的比例。 一個周期中先輸出有效電平,再輸出無效電平。 PWM的實際輸出受輸出口的控制,必須輸出口打開,PWM才能輸出,否則輸出被屏蔽掉。可以先開PWM功能,然后再開輸出口,這樣實現激光電源的首脈沖抑制功能。 |
7.PWM頻率
指令3 | ZAux_Direct_SetPwmFreq | ||||||||
指令原型 |
int32 __stdcall ZAux_Direct_SetPwmFreq(ZMC_HANDLE handle, int ionum, float fValue); |
||||||||
指令說明 | pwm 頻率設置, 參見軟件手冊里面的“ PWM_FREQ”指令。 | ||||||||
輸入參數 |
|
||||||||
輸出參數 | / | ||||||||
返回值 | 成功返回值為0,非0詳見錯誤碼說明。 | ||||||||
詳細說明 | PWM只能通過設置占空比為0來關閉,不能通過設置PWM頻率為0實現,不要將頻率設為0,PWM頻率一定要在PWM開關之前調整。 |
8.振鏡軸拐角延時
指令15 | ZAux_Direct_SetCornerMode | |||||||||||||||||
指令原型 | int32 __stdcall ZAux_Direct_SetCornerMode(ZMC_HANDLE handle, int iaxis, int iValue); | |||||||||||||||||
指令說明 | 設置振鏡軸SCAN指令拐角延時模式。針對非Scan運動指令意義不同。 | |||||||||||||||||
輸入參數 |
|
|||||||||||||||||
輸出參數 | / | |||||||||||||||||
返回值 | 成功返回值為0,非0詳見錯誤碼說明。 | |||||||||||||||||
詳細說明 |
mode:不同的位代表不同的意義,位可以同時使用。
|
9.拐角延時起始角度
指令16 | ZAux_Direct_SetDecelAngle | ||||||||
指令原型 | int32 __stdcall ZAux_Direct_SetDecelAngle(ZMC_HANDLE handle, int iaxis, float fValue); | ||||||||
指令說明 | 設置拐角減速角度,開始減速角度,單位為弧度。 | ||||||||
輸入參數 |
|
||||||||
輸出參數 | / | ||||||||
返回值 | 成功返回值為0,非0詳見錯誤碼說明。 | ||||||||
詳細說明 |
拐角延時時間以ZSMOOTH為參考,一定要設置合理的FORCE_SPEED。 角度轉換弧度公式:角度值*(PI/180) 減速角度是指電機的參考角度相對上一條運動的變化值。如下圖。 此角度值不是實際軌跡的角度,是換算到電機變換的角度,此角度值僅為參考。 ![]() 下一插補運動軌跡處于下方時取絕對值。 直線與圓弧相連時按照圓弧的切線方向計算角度。 與STOP_ANGLE一起使用,當實際運動的角度處于DECEL_ANGLE(上限)與STOP_ANGLE(下限)之間線性自動計算延時時間。 |
10.拐角延時結束角度
指令17 | ZAux_Direct_SetStopAngle | ||||||||
指令原型 | int32 __stdcall ZAux_Direct_SetStopAngle(ZMC_HANDLE handle, int iaxis, float pfValue); | ||||||||
指令說明 | 設置停止減速角度。 | ||||||||
輸入參數 |
|
||||||||
輸出參數 | / | ||||||||
返回值 | 成功返回值為0,非0詳見錯誤碼說明。 | ||||||||
詳細說明 |
拐角延時時間以ZSMOOTH為參考,一定要設置合理的FORCE_SPEED。 角度轉換弧度公式:角度值*(PI/180) 減速角度是指電機的參考角度相對上一條運動的變化值。如下圖。 此角度值不是實際軌跡的角度,是換算到電機變換的角度,此角度值僅為參考。 ![]() 下一插補運動軌跡處于下方時取絕對值。 直線與圓弧相連時按照圓弧的切線方向計算角度。 與STOP_ANGLE一起使用,當實際運動的角度處于DECEL_ANGLE(上限)與STOP_ANGLE(下限)之間線性自動計算延時時間。。 |
二、程序流程
先建立控制器通訊,獲取連接句柄,激光器選擇及參數設置,然后編輯紅光與激光口控制開關,運動參數設置,軌跡參數進行小線段處理,開始運動,停止運動。
三、主要程序展示
初始化定義相關變量,初始化軸參數,配置好FIBER轉接板的方向為輸出,后續的激光軌跡加工控制由按鈕觸發。
在運動之前我們要設置好空移速度、打標速度、開關光延時、軌跡圓半徑、標刻行列數、圓心距等參數。運動開始直接調用這些相關參數執行,獲取完軌跡后調用3次文件執行。
1.初始化408FIBER轉換板針腳定義,不同激光器類型定義一套不同的輸出口,輸出口可以在選擇激光器類型后對應在界面上進行修改。
408 FIBER轉換板參數初始化程序:
void CZmc_fontToMoveDlg::OnCbnSelchangeComboLaser() { // TODO: 在此添加控件通知處理程序代碼 UpdateData(TRUE); if(m_nLaserType == FIBER_408) //408 FIBER轉換板參數設置 { char cmdbuffAck[2048] = ""; int iresult = ZAux_Execute(m_Handle,"EXIO_DIR(0, $8FFFF)",cmdbuffAck,2048); m_nEnableIO = 47; //使能io m_nLaserIO = 8; //出關io m_nRedIO = 48; //紅光io m_nAout = 3; //功率io m_nPwmIo = 9; //頻率io } else if(m_nLaserType == YLR_408) { m_nEnableIO = 31; //使能io m_nLaserIO = 8; //出關io m_nRedIO = 32; //紅光io m_nAout = 2; //功率io m_nPwmIo = 9; //頻率io } else if(m_nLaserType == YAG_408) //408 YAG轉換板參數設置 { char cmdbuffAck[2048] = ""; int iresult = ZAux_Execute(m_Handle,"EXIO_DIR(0, $AFBBF)",cmdbuffAck,2048); m_nEnableIO = 47; //使能io m_nLaserIO = 8; //出關io m_nRedIO = 48; //紅光io m_nAout = 3; //功率io m_nPwmIo = 9; //頻率io } else if(m_nLaserType == FIBER_504) //504 { m_nEnableIO = 5; //使能io m_nLaserIO = 6; //出關io m_nRedIO = 28; //紅光io m_nAout = 2; //功率io m_nPwmIo = 7; //頻率io } UpdateData(FALSE); }2.設置拐角延時與激光功率,再調用運動執行,程序如下。
void CZmc_fontToMoveDlg::OnBnClickedBtnMove() { // TODO: 在此添加控件通知處理程序代碼 UpdateData(TRUE); //設置拐角減速此ZSMOOTH為拐角延時 int iresult = ZAux_Direct_SetCornerMode(m_Handle,SCAN_AxisX,2); //設置精準輸出 iresult = ZAux_Direct_SetParam(m_Handle,"AXIS_ZSET",SCAN_AxisX,3); //設置拐角延時 iresult = ZAux_Direct_SetZsmooth(m_Handle,SCAN_AxisX,m_nCorDelay); //設置拐角起始角度,減速時間在DecelAngle-StopAngle線性變化 iresult = ZAux_Direct_SetDecelAngle(m_Handle,SCAN_AxisX,0); //設置拐角結束角度 iresult = ZAux_Direct_SetStopAngle(m_Handle,SCAN_AxisX,90/180*3.1415926); //設置激光功率 iresult = ZAux_Direct_SetDA(m_Handle,m_nAout,m_nAoutVal); //設置激光頻率 iresult = ZAux_Direct_SetPwmDuty(m_Handle,m_nPwmIo,0.5); iresult = ZAux_Direct_SetPwmFreq(m_Handle,m_nPwmIo,m_nPwmFreq); //獲取軌跡數據,(0,0)為圓外接起點,5*5間距畫半徑為5的小圓 Cal_WorkData(m_fStartX, m_fStartY, m_nStepDis, m_nColNum, m_nRowNum, m_fRadius); Run_3FileMode(); }
3.圓弧轉小線段是將我們的設置的圓弧軌跡轉換為小線段存起來,然后轉換后由3次文件的形式加載執行。
圓弧轉小線段程序如下:
void CZmc_fontToMoveDlg::Cal_WorkData(float fStartX, float fStartY, float iStepDis, int iColNum, int iRowNum, float fRadius) { //圓弧轉小線段 int ilen = -1; double ArcX; double ArcY; //獲取單個整圓轉換長度 int iret = ZMotionOptimize_TransArcSeges(m_Handle,fStartX - fRadius, fStartY, fStartX + fRadius, fStartY + 2 * fRadius, 0, -2 * PI, m_refDistance, &ArcX, &ArcY, &ilen); if (iret != 0 || ilen < 0) { CString StrErr; StrErr.Format("圓弧轉小線段失敗錯誤碼:%d",iret); MessageBox(StrErr); return; } double *ArcToLineX; double *ArcToLineY; ArcToLineX = (double*)malloc(sizeof(double)*ilen); ArcToLineY = (double*)malloc(sizeof(double)*ilen); //獲取數據 iret = ZMotionOptimize_TransArcSeges(m_Handle, fStartX - fRadius, fStartY, fStartX + fRadius, fStartY + 2 * fRadius, 0, -2 * PI, m_refDistance, ArcToLineX, ArcToLineY, &ilen); //軌跡總長度 m_GraphTotalLen = ilen * iColNum * iRowNum; m_GraphData = (struct_GraphPos*)malloc(sizeof(struct_GraphPos)*m_GraphTotalLen); //申請分配內存 //填寫數據 int iAcr = 0; for (int icol = 0; icol < iColNum ; icol++) { for(int irow = 0 ;irow
4.這里程序完成空移,然后移動完成之前,如果下一條運動指令執行的是軌跡運動,那么提前將激光打開。
//空移到打標點起始點 void CZmc_fontToMoveDlg::Zscan_Z3pFile_StartString(struct_GraphPos *iGraphData) { char cmdbuff[2048] = ""; char tempbuff[2048] = ""; //生成命令 sprintf(tempbuff, "BASE(%d,%d) ",SCAN_AxisX,SCAN_AxisY); //設置打標軸 strcat(cmdbuff, tempbuff); //空移到起點 sprintf(tempbuff, "FORCE_SPEED = %f ",m_dEmpSpeed); //設置空移速度 strcat(cmdbuff, tempbuff); sprintf(tempbuff, "MOVESCANABS(%f,%f) ",(*iGraphData).fposx,(*iGraphData).fposy); //移動 strcat(cmdbuff, tempbuff); //設置提前開光 if (m_nStartDelay < 0) //提前出光 { sprintf(tempbuff, "MOVEOP_DELAY = %f ",m_nStartDelay/1000); strcat(cmdbuff, tempbuff); } else { sprintf(tempbuff, "MOVE_DELAY(%f) ",m_nStartDelay/1000); strcat(cmdbuff, tempbuff); } //開光 sprintf(tempbuff, "MOVE_OP(%d,1) MOVE_DELAY(10) MOVE_OP(%d,1) ",m_nEnableIO,m_nLaserIO); strcat(cmdbuff, tempbuff); //判斷命令長度是否發送 strcat(g_MoveStr,cmdbuff); Zscan_Z3pFile_Down(); } //生成打標直線段字符串 void CZmc_fontToMoveDlg::Zscan_Z3pFile_LineString(struct_GraphPos *iGraphData) { char cmdbuff[2048] = ""; char tempbuff[2048] = ""; //生成命令 //空移到起點 sprintf(tempbuff, "FORCE_SPEED = %f ",m_dSpeed); //設置打標速度 strcat(cmdbuff, tempbuff); sprintf(tempbuff, "MOVESCANABS(%f,%f) ",(*iGraphData).fposx,(*iGraphData).fposy); //移動 strcat(cmdbuff, tempbuff); //判斷命令長度是否發送 strcat(g_MoveStr,cmdbuff); Zscan_Z3pFile_Down(); }
5.延時關光是在打標軌跡完成后,將激光延時關閉。
延時關光程序如下:
void CZmc_fontToMoveDlg::Zscan_Z3pFile_EndString(struct_GraphPos *iGraphData) { char cmdbuff[2048] = ""; char tempbuff[2048] = ""; //生成命令 sprintf(tempbuff, "FORCE_SPEED = %f ",m_dEmpSpeed); //設置空移速度 strcat(cmdbuff, tempbuff); sprintf(tempbuff, "MOVESCANABS(%f,%f) ",(*iGraphData).fposx,(*iGraphData).fposy); //移動 strcat(cmdbuff, tempbuff); //延時關光 if(m_nLastDelay >0) { //延時關光 sprintf(tempbuff, "MOVEOP_DELAY = 0 MOVE_DELAY(%f) ",m_nLastDelay/1000); strcat(cmdbuff, tempbuff); } else { sprintf(tempbuff, "MOVEOP_DELAY = %f ",m_nLastDelay/1000); strcat(cmdbuff, tempbuff); } //關光 sprintf(tempbuff, "MOVE_OP(%d,OFF) ",m_nLaserIO); strcat(cmdbuff, tempbuff); //判斷命令長度是否發送 strcat(g_MoveStr,cmdbuff); Zscan_Z3pFile_Down(); }
四、最終效果
首先點擊下拉框選擇控制器IP,點擊連接,依次設置好激光器參數、運動參數,設置好后輸入打軌跡的參數,點擊運動開始打圓形軌跡,點擊停止結束。
通過Zdevelop軟件的示波器采樣運動結果:先從其他位置空移到起始位置,然后提前1ms開光,走完一個圓形軌跡,關閉激光(延時關光),再空移到下一個圓形軌跡的起點,開光(提前1ms開光),又走完一個軌跡后,關光(延時5ms關光),如此循環執行,直到設置的行列數打完停止(打軌跡中也能點擊停止)。
XY模式下的軌跡,軌跡包括了圓形打標軌跡和空走軌跡:
本次,正運動技術開放式激光振鏡運動控制器:C++快速開發,就分享到這里。
審核編輯:彭靜
-
控制器
+關注
關注
113文章
16727瀏覽量
180916 -
接口
+關注
關注
33文章
8831瀏覽量
152664 -
C++
+關注
關注
22文章
2116瀏覽量
74372 -
激光振鏡
+關注
關注
1文章
21瀏覽量
3409
原文標題:開放式激光振鏡運動控制器:C++快速開發
文章出處:【微信號:伺服與運動控制,微信公眾號:伺服與運動控制】歡迎添加關注!文章轉載請注明出處。
發布評論請先 登錄
相關推薦
開放式激光振鏡+運動控制器(五):ZMC408SCAN控制器

評論