The value of Zmotion is to bring customers more success!
今天,正运动小助手给大家分享一下开放式激光振镜运动控制器:C++快速调用图形库应用,本文以二维码打标、文本打标、矢量图形打标为例, 解决用户在激光打标时需要进行各种复杂的操作和函数库调用时容易出现的错误问题。
ZMC408SCAN控制器支持EtherCAT总线连接,支持最快500μs的刷新周期,支持最多达16轴运动控制,支持直线插补、任意圆弧插补、空间圆弧、螺旋插补、电子凸轮、电子齿轮、同步跟随、虚拟轴设置等;采用优化的网络通讯协议可以实现实时的运动控制。单台电脑最多支持达256个ZMC控制器同时连接。

(2)支持激光振镜控制和振镜反馈,包含2个振镜接口,支持2D振镜和3D振镜,配合不带加减速的运动指令MOVESCAN,拐角处振镜加工自动延时,完成精准高效的激光控制,提高激光加工设备的产能;
(6)板载4路高速差分脉冲输出,并带4路高速差分编码器反馈,支持EtherCAT总线驱动器的控制,支持5轴XYZAC轴的插补,支持振镜轴与运动轴混合插补。



3.参考架构

我们打标条码、二维码、不同字体样式的文本、矢量图形、位图等,都有对应的接口指令,从而实现快速调参开发,可以节省工程师大量的编程及工艺规划时间。
2.方式
3.三次文件使用步骤如下
(6)关闭文件生成。
仅需要很少的指令填上对应参数就能实现一个类型打标,将复杂的指令编程简单化,对于加工轨迹复杂、文件较大也能实现动态追加文件发送字符串运行。
1.函数名: uint32 ZmotionLaser_BarCode(int nTechnology,const char *pStrText,const char *pStrType,double dX,double dY,double dSizeX,double dSizeY,double dAngle)
(1)函数名: uint32 ZmotionLaser_SetTextStyle(const char * pStrFont,bool bThickness,bool bItalics,bool bUnderline,bool bDelete,double dHeight,double dWidthR,double dAngle,double dTilt)
(2)说明: 设置文本的状态,需要确定文本的字体、风格、尺寸、角度和倾斜等状态。该状态设置后如果不重新设置,后续所有文本的状态都按照该状态进行,配合文本指令使用进行文本打标。
三、矢量图形参数设置
2.说明: 设置某一工艺的矢量图形加工参数。该指令用于矢量图形加工时参数设置,针对矢量图形的加工复杂性,通过将参数提前写入,以在打标时快速响应。

2.操作流程
(3)准备工作完成,点击标刻进行打标,如果中途发现有异常,点击停止即可。
我们用到的头文件和定义控制器句柄,实现与控制器连接的第一步。通过ZAux_OpenEth(char *ipaddr, ZMC_HANDLE * phandle)指令连接控制器获取返回句柄。断开连接则用ZAux_Close(ZMC_HANDLE handle)。连接上就能对控制器实现交互控制了。

//连接控制器
void CZmc_laserDlg::OnBnClickedBtnConnet()
{
char buffer[256];
int32 iresult;
if(NULL != m_Handle)
{
ZAux_Close(m_Handle);
m_Handle = NULL;
}
GetDlgItemText(IDC_IPLIST,buffer,255);
buffer[255] = '\0';
iresult = ZAux_OpenEth(buffer, &m_Handle);
if(ERR_SUCCESS != iresult)
{
m_Handle = NULL;
MessageBox(_T("链接失败"));
SetWindowText("未链接");
return;
}
SetWindowText("已链接");
for(int iAxis = 4;iAxis<=5;iAxis++)
{
iresult = ZAux_Direct_SetAtype(m_Handle,iAxis,21);
iresult = ZAux_Direct_SetUnits(m_Handle,iAxis,500);
}
OnCbnSelchangeComboLaser();
}
//断开控制器
void CZmc_laserDlg::OnBnClickedBtnClose()
{
if(NULL != m_Handle)
{
KillTimer(0); //关定时器
ZAux_Close(m_Handle);
m_Handle = NULL;
SetWindowText("未链接");
}
}
程序如下:
//修改激光器类型
void CZmc_laserDlg::OnCbnSelchangeComboLaser()
{
if(NULL == m_Handle)
{
MessageBox(_T("控制器未连接"));
return;
}
UpdateData(TRUE);
if(m_nLaserType == FIBER_408) //408 FIBER转换?板参数设置
{
int iret = ZAux_SetExioType(m_Handle,0);
m_nEnableIO = 47;
m_nLaserIO = 8;
m_nRedIO = 48;
m_nAout = 3;
m_nPwmIo = 9;
}
else if(m_nLaserType == LASER_408)
{
int iret = ZAux_SetExioType(m_Handle,-1);
m_nEnableIO = 31;
m_nLaserIO = 8;
m_nRedIO = 32;
m_nAout = 2;
m_nPwmIo = 9;
}
else if(m_nLaserType == YAG_408) //408 YAG转换板参数设置
{
int iret = ZAux_SetExioType(m_Handle,1);
m_nEnableIO = 47;
m_nLaserIO = 8;
m_nRedIO = 48;
m_nAout = 3;
m_nPwmIo = 9;
}
else if(m_nLaserType == FIBER_504) //504
{
m_nEnableIO = 5;
m_nLaserIO = 6;
m_nRedIO = 28;
m_nAout = 2;
m_nPwmIo = 7;
}
UpdateData(FALSE);
} 4.设置运动参数和二维码大小参数

实际的拐角延时则依据轨迹的实际角度自动计算对应拐角延时时间,在设定的角度范围内,延时时间呈线性分布。

程序如下:
CZmc_laserDlg::CZmc_laserDlg(CWnd* pParent /*=NULL*/)
: CDialogEx(CZmc_laserDlg::IDD, pParent)
{
m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME);
m_nEnableIO = 47;
m_nLaserIO = 8;
m_nRedIO = 48;
m_nAout = 3;
m_nAoutVal = 128;
m_nPwmIo = 9;
m_nPwmFreq = 40000;
m_dSpeed = 1000;
m_dEmpSpeed = 1000;
m_nStartDelay = 1000;
m_nLastDelay = 1000;
m_nCorDelay = 1000;
m_nLaserType = 0;
//填充参数初始化
m_FillPara.m_bEnable = true; //填充使能
m_FillPara.m_bOutline = true; //使能轮廓
m_FillPara.m_bOutlineFirst = false; //轮廓优先
m_FillPara.m_bEdge = false; //是否绕边走一次
m_FillPara.m_bAverage = true; //是否平均分布填充线
m_FillPara.m_nType = 1; //填充类型
m_FillPara.m_nAngle = 0; //填充线角度
m_FillPara.m_nNum = 0; //填充线数目
m_FillPara.m_dLineSpace = 0.1; //线间距
m_FillPara.m_dMargin = 0; //边距
m_FillPara.m_dSOffset = 0; //开始偏移
m_FillPara.m_dEOffset = 0; //结束偏移
m_FillPara.m_dLineIndent = 0; //直线缩进
//文本参数
m_dTextHigh = 30; //文本高度
m_dTextWidth = 30; //文本宽度
m_dTextAngle = 0; //文本角度
m_dTextXpos = 0;
m_dTextYpos = 0;
m_TextString = _T("");
} 5.设置填充工艺参数
由输入内容生成二维码,将我们的二维码轨迹分成小线段轨迹生成三次文件,并且将填充工艺参数等设置进去。
填充工艺: 主要是指令uint32 ZmotionLaser_SetFillParam(bool bEnable,bool bOutline,bool bOutlineFirst,bool bEdge,bool bAverage,int nType,int nAngle,int nNum,double dLineSpace,double dMargin,double dSOffset,double dEOffset,double dLineIndent,int nFillNum)的一些参数,将参数通过变量的形式做到界面上。
(1)单相填充:填充线总是从左向右填充;
(2)双向填充:填充线先是从左向右,然后从右向左进行填充,其余循环填充;
(3)弓形填充:类似于双向填充,但填充线末端之间会产生连接线;
(4)优化弓形填充:类似于弓形填充,但对象空白的地方仍会跳过去填充。

void CZmc_laserDlg::OnEnChangeEditText()
{
UpdateData(TRUE);
//打开打标库3次文件功能
int rtn = ZmotionLaser_OpenFile3(m_Handle);
if(CheckError(rtn,"ZmotionLaser_OpenFile3")) return;
rtn = ZmotionLaser_SetOutputLimits(55); //设置输出口最大编号限制
if(CheckError(rtn,"ZmotionLaser_OpenFile3")) return;
rtn = ZmotionLaser_SetScanAxis(4,5); //设置振镜轴号
if(CheckError(rtn,"ZmotionLaser_SetScanAxis")) return;
rtn = ZmotionLaser_SetOutput(m_nLaserIO,m_nEnableIO,m_nRedIO); //设置开光光控制
if(CheckError(rtn,"ZmotionLaser_SetOutput")) return;
rtn = ZmotionLaser_AoutInit(m_nAout,255); //设置模拟量功率设置
if(CheckError(rtn,"ZmotionLaser_AoutInit")) return;
rtn = ZmotionLaser_SetPowerEnable(false); //关闭动态修改功率
if(CheckError(rtn,"ZmotionLaser_SetPowerEnable")) return;
rtn = ZmotionLaser_SetLightInstruct(1);
if(CheckError(rtn,"ZmotionLaser_SetLightInstruct")) return;
rtn = ZmotionLaser_SetLightString("MOVE_OP(8,ON)\n","MOVE_OP(8,OFF)\n");
if(CheckError(rtn,"ZmotionLaser_SetLightInstruct")) return;
//设置加工工艺参数
int ipower = (int)(m_nAoutVal*100/256);
rtn = ZmotionLaser_SetVectPar(ipower, m_nPwmFreq, m_dSpeed, m_dEmpSpeed, m_nStartDelay, m_nLastDelay, m_nLastDelay, 10, m_nCorDelay,m_nLastDelay ,1);
if(CheckError(rtn,"ZmotionLaser_SetVectPar")) return;
//设置填充参数
rtn = ZmotionLaser_SetFillObject(m_FillPara,1);
if(CheckError(rtn,"ZmotionLaser_SetFillObject")) return;
//开始填充
rtn = ZmotionLaser_FillStart();
if(CheckError(rtn,"ZmotionLaser_FillStart")) return;
//加工文本字符
CString strBarCode;
m_ListBarCode.GetLBText(m_ListBarCode.GetCurSel(),strBarCode);
rtn = ZmotionLaser_BarCode(1,m_TextString,strBarCode,m_dTextXpos,m_dTextYpos,m_dTextHigh,m_dTextWidth,m_dTextAngle);
if(CheckError(rtn,"ZmotionLaser_BarCode")) return;
//结束填充
rtn = ZmotionLaser_FillEnd();
if(CheckError(rtn,"ZmotionLaser_FillEnd")) return;
char* MoveStr = NULL;
int nRow = 0;
MoveStr = ZmotionLaser_GetProcessString(false);
MoveStr = ZmotionLaser_GetProEndString(nRow);
OnShowGraph(); //显示图形
//生成加工三次文件
rtn = ZmotionLaser_CreateFile3(".//ZscanLaser.z3p",true);
if(CheckError(rtn,"ZmotionLaser_CreateFile3")) return;
rtn = ZmotionLaser_CloseFile3();
if(CheckError(rtn,"ZmotionLaser_CloseFile3")) return;
}通过Zpj文件方式下载三次文件到控制器ROM,开启一个未使用或者一个确认停止的任务号运行该文件。
程序如下:
void CZmc_laserDlg::OnBnClickedBtnMark()
{
if(NULL == m_Handle)
{
MessageBox(_T("控制器未连接"));
return;
}
//运行生成的3次文件
int rtn = ZAux_Down3FileRom(m_Handle,".//ZscanLaser.z3p","Text123.z3p");
if(CheckError(rtn,"ZAux_Down3FileRom")) return;
rtn = ZAux_Direct_StopTask(m_Handle,1);
if(CheckError(rtn,"ZAux_Direct_StopTask")) return;
rtn = ZAux_Run3FileRom(m_Handle,"Text123.z3p",1,0); //任务1运行3次文件
if(CheckError(rtn,"ZAux_Down3FileRom")) return;
} 7.完成打标
停止加工,主要是将任务停止,然后停止所有的轴运动,关掉激光。
void CZmc_laserDlg::OnBnClickedBtnStop()
{
int rtn = ZAux_Direct_StopTask(m_Handle,1);
if(CheckError(rtn,"ZAux_Direct_StopTask")) return;
rtn = ZAux_Direct_Rapidstop(m_Handle,3);
if(CheckError(rtn,"ZAux_Direct_Rapidstop")) return;
rtn = ZAux_Direct_SetOp(m_Handle,m_nLaserIO,0); //关光
Sleep(10);
rtn = ZAux_Direct_SetOp(m_Handle,m_nEnableIO,0);
SetDlgItemTextA(IDC_BTN_LASER,"激光(关)");
}8.二维码打标界面

9.界面参数配置讲解&打标效果展示

通过该例程我们可以实现产品包装生产日期、金属元件、硬质塑料产品上的标注打标,还能在金属物品上进行纪念语等的打标,多种字体样式可选择。
程序如下:
//标刻
void CZmc_laserDlg::OnBnClickedBtnMark()
{
if(NULL == m_Handle)
{
MessageBox(_T("控制器未连接"));
return;
}
UpdateData(TRUE);
//打开打标库3次文件功能
int rtn = ZmotionLaser_OpenFile3();
if(CheckError(rtn,"ZmotionLaser_OpenFile3")) return;
rtn = ZmotionLaser_SetOutputLimits(55); //设置输出口最大编号限制
if(CheckError(rtn,"ZmotionLaser_OpenFile3")) return;
rtn = ZmotionLaser_SetScanAxis(4,5); //设置振镜轴号
if(CheckError(rtn,"ZmotionLaser_SetScanAxis")) return;
rtn = ZmotionLaser_SetOutput(m_nLaserIO,m_nEnableIO,m_nRedIO);//设置开光控制
if(CheckError(rtn,"ZmotionLaser_SetOutput")) return;
rtn = ZmotionLaser_AoutInit(m_nAout,255); //设置模拟量功率设置
if(CheckError(rtn,"ZmotionLaser_AoutInit")) return;
rtn = ZmotionLaser_SetPowerEnable(false); //关闭动态修改功率
if(CheckError(rtn,"ZmotionLaser_SetPowerEnable")) return;
rtn = ZmotionLaser_SetLightInstruct(1);
if(CheckError(rtn,"ZmotionLaser_SetLightInstruct")) return;
rtn = ZmotionLaser_SetLightString("MOVE_OP(8,ON)\n","MOVE_OP(8,OFF)\n");
if(CheckError(rtn,"ZmotionLaser_SetLightInstruct")) return;
//设置加工工艺参数
int ipower = (int)(m_nAoutVal*100/256);
rtn = ZmotionLaser_SetVectPar(ipower, m_nPwmFreq, m_dSpeed, m_dEmpSpeed, m_nStartDelay, m_nLastDelay, m_nLastDelay, 10, m_nCorDelay,m_nLastDelay ,1);
if(CheckError(rtn,"ZmotionLaser_SetVectPar")) return;
//设置填充参数
rtn = ZmotionLaser_SetFillObject(m_FillPara,1);
if(CheckError(rtn,"ZmotionLaser_SetFillObject")) return;
//设置文本字体参数
CString strFont;
m_ListFont.GetLBText(m_ListFont.GetCurSel(),strFont);
rtn = ZmotionLaser_SetTextStyle(strFont,m_FontThickness,m_FontItalics,m_FontUnderline,m_FontDelete,m_dTextHigh,m_dTextWidth,m_dTextAngle,m_dTextTilt);
if(CheckError(rtn,"ZmotionLaser_SetTextStyle")) return;
//开始填充
rtn = ZmotionLaser_FillStart();
if(CheckError(rtn,"ZmotionLaser_FillStart")) return;
//加工文本字符
rtn = ZmotionLaser_Text(1,m_TextString,m_dTextXpos,m_dTextYpos,m_dTextAccuracy);
if(CheckError(rtn,"ZmotionLaser_Text")) return;
//结束填充
rtn = ZmotionLaser_FillEnd();
if(CheckError(rtn,"ZmotionLaser_FillEnd")) return;
char* MoveStr = NULL;
int nRow = 0;
MoveStr = ZmotionLaser_GetProcessString(false);
MoveStr = ZmotionLaser_GetProEndString(nRow);
//生成加工三次文件
rtn = ZmotionLaser_CreateFile3(".//ZscanLaser.z3p",true);
if(CheckError(rtn,"ZmotionLaser_CreateFile3")) return;
rtn = ZmotionLaser_CloseFile3();
if(CheckError(rtn,"ZmotionLaser_CloseFile3")) return;
//运行生成的3次文件
rtn = ZAux_Down3FileRom(m_Handle,".//ZscanLaser.z3p","Text123.z3p");
if(CheckError(rtn,"ZAux_Down3FileRom")) return;
rtn = ZAux_Direct_StopTask(m_Handle,1);
if(CheckError(rtn,"ZAux_Direct_StopTask")) return;
rtn = ZAux_Run3FileRom(m_Handle,"Text123.z3p",1,0); //任务运行3次文件
if(CheckError(rtn,"ZAux_Down3FileRom")) return;
}2.界面参数配置讲解&打标效果展示

通过该例程我们可以实现一些图案的打标,如产品LONG打印、图案打印、金属牌上打印图案做项链等。

程序如下:
//显示图形
void CZmc_laserDlg::OnShowGraph()
{
CDC*dc = GetDlgItem(IDC_PIC_SHOW)->GetDC();
CRect rectClient;
GetDlgItem(IDC_PIC_SHOW)->GetClientRect(rectClient);
CBrush brush(RGB(255, 255, 255));
dc->FillRect(&rectClient, &brush);
//画一个外框
int iwidth = rectClient.Width();
int iheight = rectClient.Height();
dc->MoveTo(0,0);
dc->LineTo(iwidth-1,0);
dc->LineTo(iwidth-1,iheight-1);
dc->LineTo(0,iheight-1);
dc->LineTo(0,0);
int rtn=0;
rtn = ZMotionCad3_DeleteChain((Struct_ZCad_Item *) m_pGraph->m_pVectorData);
rtn = ZMotionCad3_DeleteChain((Struct_ZCad_Item *) m_pGraph->m_pImageData);
m_pGraph->m_pImageData = NULL;
m_pGraph->m_pVectorData = ZMotionCad3_ImportVectGraph(m_FileName, 1016,1,0.001); //导入图形生成轨迹
if (m_pGraph)
{
uint32 uiresult;
//元素尺寸
float left, bottom, width, height;
uiresult = ZMotionCad3_GetRange((Struct_ZCad_Item *)m_pGraph, &left, &bottom, &width, &height);
float top;
//转成显示坐标
top = -(bottom + height);
//显示的区域
double WinWidth = rectClient.Width() - 8;
double WinHeight = rectClient.Height() - 8;
// 实际的区域
double ObjectWidth = width;
double ObjectHeight = height;
double ObjectPixWidth, ObjectPixHeight;
if (ObjectWidth*WinHeight SetViewportOrg(ZeroPoint.x-left*dUnitsPerMm, ZeroPoint.y-top*dUnitsPerMm);
ZMotionCad3_Draw(dc->m_hDC, (Struct_ZCad_Item *) m_pGraph, 0, 1.0f/dUnitsPerMm); //绘图
}
}3.界面参数配置讲解&打标效果展示
本次,正运动技术开放式激光振镜运动控制器:C++快速调用图形库应用,就分享到这里。
正运动技术专注于运动控制技术研究和通用运动控制软硬件产品的研发,是国家级高新技术企业。正运动技术汇集了来自华为、中兴等公司的优秀人才,在坚持自主创新的同时,积极联合各大高校协同运动控制基础技术的研究,是国内工控领域发展最快的企业之一,也是国内少有、完整掌握运动控制核心技术和实时工控软件平台技术的企业。主要业务有:运动控制卡_运动控制器_EtherCAT运动控制卡_EtherCAT控制器_运动控制系统_视觉控制器__运动控制PLC_运动控制_机器人控制器_视觉定位_激光振镜控制器等等。