DMC2000运动控制卡常见软件问题的解决方案一、0脉冲速度初始化故障二、多轴插补数据类型引起冲突三、用曲线拟合算法,替代库函Arc插补一、0脉冲速度初始化故障示例介绍: Set_move_speed(3200,6400); //设置插补矢量速度 Set_move_accel(0.1); //设置加速时间 Start_move_xy(0,6400,6400); //进行直线插补 If(Motion_done(0)==0|| //可以Wait_for_done,Wait_for_all之类函数 Motion_done(1)==0){ //脉冲在输出时,做其它事情 …dos.th } else{//脉冲输出完毕 …nextoperator //无法执行到此处} 原因分析:库函数故障;当第一次运行时,速度寄存器未填入有效数据,具体原因未明。 Set_move_speed 设置多轴运动的矢量速度 Set_move_accel 设置多轴运动的矢量加速时间 Start_move_xy 让指定卡号的第1,2轴以插补方式运动到指定位置 Move_xy 同Start_move_xy,需等待完成 Start_move_zu 让指定卡号的第3,4轴以插补方式运动到指定位置 Move_zu 同Start_move_zu,需等待完成 Arc_xy 让指定卡号的第1,2轴作圆弧运动,需等待完成 Arc_zu 让指定卡号的第3,4轴作圆弧运动,需等待完成附带检测函数: Wait_for_all 等待指定的多轴并完成 Wait_for_done 等待运动并完成Motion_done 检测当前运动状态故障现象:当程序执行到Motion_done等检测函数时,发现它们无法返回完成的状态,原因不是检测函数的故障。而是X,Y无法取得速度值,进而也无法完成指定的脉冲输出,这就是为什么检测函数返回不了脉冲输出完成的状态。此问题是库函数的小毛病。解决方法: Start_r_move(0,0,3200,6400,0.1); //驱动X轴,但其输出脉冲为0个,不会损失位置 Start_move_xy(0,6400,6400); //再次驱动,问题解决了。二、多轴插补数据类型引起冲突示例介绍: int marray[2>={0,1}; //指定驱动轴号(期望是X,Y运动) double pos[2>={6400,12800}; //X=6400Y=12800 double LowSpeed[2>={6400,6400}; double HighSpeed[2>={12800,12800}; double Taccel[2>={0.1,0.1}; Map_axes(2,marray); Move_all(2,marray,pos,LowSpeed,HighSpeed,Taccel);相关函数: Map_axes 为多轴运行配置指定的轴号 Move_all 启动多轴运动 Start_move_all 启动多轴运行,并等待完成故障现象:当调用Map_axes(),Move_all(),Start_move_all()函数时,出现被操作的驱动轴变得混乱,如Y轴不动,X轴走出Y轴的距离。原因分析: int 为4字节(在VC编程环境) WORD 为2字节 当发生int转成WORD时,int数组后面的数据被裁切而遗失。即marray[1>会无效。所以上例的XY值实质上为:X=marray[0>&0x000f=0;Y=(marray[0>&0xf0000>>16)=0;可以看出Y为0,是X轴的值,当驱动时,每个轴以最后配置的对应数据有效。则Y为X轴时,已对应数据索引第1个,即pos[1>=12800个脉冲了。这就是为什么X轴走Y轴的脉冲,而Y轴不动作,从以上得知,Y轴从未直正被指定驱动。据此原理,修改起来就简单了,只需要将marray[0>的数据初始化如下:marray[0>=0x00010000; //低16位两字节,为0,指向X轴,高16位两字节,为1,指向Y轴但是用此种方法初始化marray不受程序员的欢迎,通常我们建议用以下的方法进行解决.解决方法: WORDmarray[2>={0,1}; //将int变为WORD Map_axes(2,(int*)marray); //为获取编译通过,需将WORD数组转成(int*)方式三、用曲线拟合算法,替代库函Arc插补示例介绍: voidOnButtonArc(){Arc_xy(0,1000,1000,360);//进行圆弧插补 }voidOnTimer()//定时器内取位置{ longCurX=Get_position(0);//取X轴位置 longCurY=Get_Position(1);//取Y轴位置}相关函数: Arc_xy XY圆弧插补函数 Arc_zu ZU圆弧插补函数 Get_Position 取位置函数故障现象:1.当进行圆弧插补时,不响应其它事件2.取得位置,不准确原因分析: 1.不响应其它事件,原点是:函数库进行圆弧插补时,实质上同样进行的纯软件算法处理,内部使用软件查询位置方式,从而形成单一任务响应。2.位置读取不准确暂未明了。解决方法: 参见下列源代码:voidArc(intch1,intch2,doublecen1,doublecen2, doubleangle,doublespeed,FUNCTIONpfn){//cen1和cen2为绝对位置 if(fabs(angle) doublex=cen1;doubley=cen2; doublecurx=GetMM(ch1,TRUE); //取当前位置 doublecury=GetMM(ch2,TRUE); doubler=sqrt((x-curx)*(x-curx) (y-cury)*(y-cury));//计算半径 double startPAI=atan2(cury-y,curx-x);//计算起始角度 double dt=1; //圆弧精度值(超小,精度越高,过小可能要考虑计算溢出的问题) double l=r*fabs(angle)*PAIUT;//弧长 doubletmpStep=(dt/r)*(angle>0.0?1.0:-1.0);//步长PAI单位 intn=int(l/dt); double tx,ty; double tm=startPAI (angle)*PAIUT;///180.0*PAI); for(inti=0;i { tx=x r*cos(startPAI); ty=y r*sin(startPAI); ConLine2(ch1,ch2,tx,ty,speed);//使直线插补函数 startPAI =tmpStep; while(IsRunning(ch1)!=0|| IsRunning(ch2)!=0 )if(pfn)pfn();//响应函数 } tx=x r*cos(tm); ty=y r*sin(tm); ConLine2(ch1,ch2,tx,ty,speed,NULL); while(IsRunning(ch1)!=0||IsRunning(ch2)!=0 )if(pfn)pfn(); return;}//其它函数及数据类型声明//直线插补intConLine2(intch1,intch2,doublepos1,doublepos2,doublespeed,FUNCTIONpfn){//指向绝对位置(毫米单位) speed=MMPulse(XCH,speed); pos1=MMPulse(ch1,pos1); //毫米转成脉冲 pos2=MMPulse(ch2,pos2); Set_move_speed(speed,speed); Set_move_accel(0.0f); Start_r_move(XCH,0,speed,speed,0);//此问题,请参见[0脉冲> Start_move_xy(0,pos1,pos2); if(!pfn)return2; while(IsRunning(ch1)!=0|| IsRunning(ch2)!=0) pfn(); return1;}//函数指针声明typedefvoid(*FUNCTION)(void);//检测是否在运动函数intIsRunning(intch){//停止返回0 returnMotion_done(ch)==0;//为1正在运行}
来源:中国自动化网