伺服驱动器APCM模式编程总结经过一个多月的努力,终于将触摸屏控制伺服驱动器工作于APCM模式的程序做好了。
这段时间,在赵老师的指导下,我不断查找资料、上机实验、询问客服等方法,终于将触摸屏控制伺服驱动器工作于APCM模式的不同控制方式下的几个程序做了出来。
在这个过程中,我收获了很多的知识,不仅是关于触摸屏与伺服电机的专业知识,更多的是在程序设计中怎样与实践结合,怎样从使用方便的角度去设计程序。
我编写的程序包括APCM模式的单次定位方式程序、APCM模式的连续定位方式、APCM模式的连续速度模式和两轴联动的APCM单次绝对位置定位模式,以及内部速度通信调速模式。
在这里,我将各个程序的编写方法及宏指令总结如下。
首先说明编写程序及调试所用的主要设备:两台珠海运控PSDA0633A6伺服驱动器及两台BPA6系列60型C60-30伺服电机、一台威纶通MT6070iH触摸屏。
一、APCM模式的连续定位方式使用APCM模式,需先将51号参数设为5,然后断电再上电,该模式才会有效。
伺服驱动器工作在APCM模式的单次定位方式,需在单次定位控制方式页面打开时,设定65号参数为11850(APCM控制字为10111110001010)。
屏幕上需设定速度参数设定、伺服ON、伺服OFF、启动、停止、故障处理等6个主要控制键,分别用于切换到速度设定窗口、打开伺服、关闭伺服、启动电机、停止电机和故障处理等。
在屏幕上还要设置一个趋势图元件,来形象显示电机的实时速度,同时趋势图元件还可以查看过去某个时刻的速度、观察速度曲线等功能。
我在该定位方式的控制控制页面上还添加了伺服准备好、伺服ON、正转、反转、驱动器报警等运行状态显示元件来实时显示伺服驱动器的运行状态。
为了根据需要实现电机的正反转,还用到了两个置位开关,位地址都为0x52,但是在这里我将这两个置位开关做成透明的,然后在上面添加两个位地址也为0x52的位状态指示灯,这样在点击正转或反转的按键后,相应的位状态指示灯就会亮,表明正转(反转)设定有效。
同时在控制页面上还添加了一个保存参数的按键,用来将设定的参数保存在伺服驱动器里。
控制页面上所用的元件的地址都是根据伺服驱动器手册里的Modbus协议分配的地址来设定的。
在做这个连续定位方式的程序过程中,曾经遇到两个问题:第一个问题是,在设定好电机的加减速时间后(运行速度设定为600转),电机从0转开始启动,加速到600转,然后按停止键,电机瞬时停止,可以在趋势图上观察到启动的时候速度曲线是斜线,停止的时候速度曲线是一条竖直线,这说明启动的时候电机按设定的加减速时间启动了,但是停止的时候没按设定的加减速时间停止。
如果将电机从0转加速到3000转,可以在趋势图上观察到电机按设定的加减速时间启动了,按下停止键,电机会瞬时停止转动,同时会发生很大的噪声,这时在趋势图上观察到停止的时候速度曲线是一条竖直线。
反复分析了这种情况,最后找到了出现这种情况的原因是在电机停止的宏指令里,没有在减速指令后加上一条延时指令来给电机时间减速,而是直接执行停止指令,这样电机刚接收到减速指令,马上就又接收到停止指令,电机来不及减速,转速直接从3000转跌到0转,这样就产生了很大的震动和噪声。
后来我在电机停止的宏指令里添加了电机从设定的运行速度减速到启动速度的延时时间,这个问题才得以解决。
第二个问题是,我在调试的过程中,发现加减速时间的设定值超过8100mm时,不论设定的加减速时间是多少,电机都在两秒钟左右的时间内加速到运行速度。
特别是把加减速时间设定为8200mm时,按启动键,电机不启动,同时还会发出转速瞬时下降时的那种噪声。
起初我以为是个别驱动器的问题,但是换了个驱动器之后发现问题依然存在。
这个情况要等问过他们厂家的在线客服之后才明白是怎么回事。
二、APCM模式的连续速度方式APCM模式的连续速度方式程序的编写基本上与APCM模式的连续定位方式一样,但是在控制页面打开的时候要把65号参数设定为3635(APCM控制字为0000111001001000)。
控制页面上同样需要设定速度参数设定、伺服ON、伺服OFF、启动、停止、故障处理等6个主要控制按键。
在该控制页面上也需要添加上正反转按键、趋势图、状态显示指示灯、保存参数等元件。
需要指出的一点是,这两种控制方式如果用于调速的话,不是很方便,因为速度参数的设定位置只有一个地址,且在电机的运行过程中,设定电机向相反方向运转,该指令不会马上执行,必需在电机停止后再启动,驱动器才会执行反转指令。
三、APCM模式的单次定位方式APCM模式的单次定位方式适合于进行精确的位置控制。
伺服驱动器工作在APCM模式的单次定位方式,需在单次定位控制方式页面打开时,设定65号参数为12170(APCM控制字为0010111110001010)。
单次定位方式的控制按键跟连续定位方式的控制按键相似,也要设定速度参数设定、伺服ON、伺服OFF、启动、停止、故障处理、保存参数等按键和位状态显示指示灯,不同的是这这段程序中,我选择的是绝对位置控制,这样,如果输入的脉冲总数是正值,则电机正转,输入脉冲式负值,则电机反转,同时还可以进行原点校正、回归原点、点动控制等功能(点动控制只在该控制方式里有效,在连续控制方式里无效)。
在单次定位方式里,可以准确设定电机运行的脉冲数目,这样电机就能够准确的运行一段距离。
该方式适合于用通信方式进行精确的距离控制。
四、内部速度调速使用内部速度调速模式,需先将51号参数设为0,然后断电再上电,该模式才会有效。
内部速度模式控制页面的参数设置也跟上面几种模式一样,需要设定速度参数按键、伺服ON、伺服OFF、停止、故障处理、正转、反转、保存参数、趋势图以及状态显示等元件。
与上面的模式不同的是,内部速度模式可以设定八级速度,而且可以在这八及速度中任意切换,点正转(反转)按键后,电机会马上按设定的加减速时间减速然后反转(正转)。
这种模式比APCM模式更适合用于调速。
五、两轴联动的APCM单次绝对位置定位模式这个程序可以同时控制两个电机带动一个工作台分别向X、Y方向移动。
在这个程序的控制页面上,除了上面所叙述的参数设定、伺服ON、伺服OFF、启动、停止和故障处理等参数外,还需要设定一个坐标系。
坐标系里,X轴和Y轴的最大值都是5mm,坐标系的四个方向设定四个上下左右的箭头,点一下箭头,电机就向相应的方向运行0.01mm(1丝),同时可以在坐标系里用鼠标进行目标位置的选取,也可以在专门的数值输入框里输入目标坐标。
设定好目标坐标后,会有两条黄色的水平和数值的虚线相交叉,交叉点即为选取的目标点。
在该控制页面上,我还进行了电机速度的实时显示、电机已运行距离的实时显示,目标位置的设定和目标位置的径向距离和电机当前位置相对于原点的径向距离的显示。
点击电机速度显示框、电机已运行距离显示框或目标位置设定方框时都有一个相对应的放大的窗口弹出来,这样可以更加清晰地观察和设定参数。
在这个程序里,可以进行配方数据的上传和下载。
在坐标系下,我添加了一个直径为5毫米、圆心在原点的圆,这样在目标位置选取的时候,可以直观里看到选取的目标位置的径向距离有没有超过最大值5mm,也可以观察目标位置径向距离显示元件,这样更精确一些。
同时,在控制页面的下方,我还添加了X轴、Y轴脉冲总数的显示元件,显示X轴、Y轴方向要执行的脉冲总数,还在控制页面下方添加了两个数据显示元件(地址类型为配方地址),来实时显示并记录电机当前位置,来显示当前电机的位置,并实时记载电机当前位置,这样可以在断电或者伺服OFF时,保存当前电机位置,不至于在重新上电或伺服ON时,电机上次运行的位置丢失。
在这几种模式程序的编写中,有几点经验是相同的:1、在这几种模式的程序的开始,都使用了快选窗口,在快选窗口里可以进行登录、注销、重新启动、控制画面切换等操作,这种方式也是实际应用中必不可少的,因为它方便、快捷。
2、在这几种模式的程序里,除了可在各种模式的控制窗口里正常进入报警处理窗口外,还另外添加了一个报警处理弹出窗口,同时在公共窗口添加了一个与报警弹出窗口等大小的直接窗口,并设定弹出窗口为报警处理窗口,这样不管当前页面为哪个页面,如果有警情,报警处理弹出窗口都可以自动弹出来,方便操作人员及时进行报警处理。
3、因为保存参数按键不常使用,所以我在保存参数的安全选项里设定最少按键时间为2秒钟,这样可以避免误触保存参数按键,造成原来保存的参数丢失。
同时还设定了该按键在伺服OFF时有效,伺服ON时无效,这样可以避免在伺服驱动器上电时电机自动运行。
4、在选择位状态指示灯时,要用不同状态颜色反差比较大的指示灯,这样便于识别。
此外,还需要指出的一点是,A6系列的驱动器在进行485联机通信时,不可以使用2号机器编号,因为据客服人员讲,驱动器软件里存在漏洞,不能识别2号机器编号。
所以在联机通信时,要使用1号和2号以后的机器编号。
同时还需要注意的是,在用485方式进行联机通信的时候,要采用手拉手的方式,就是触摸屏连一个伺服驱动器,这个驱动器再连下一个,这样一个连一个,不能出现分支的情况。
因为前面几种模式程序的编写的主要目的是练习,是为编写两轴联动的APCM单次绝对位置定位模式这个程序打基础的,所以在这里只附带两轴联动的APCM单次绝对位置定位模式程序宏指令以及对应语句的解释。
/************************初始化指令*****************************/ macro_command main()short a,bint pulsex,pulseya=3714 //APCM控制字:0000111010000010 b=127 //X轴5mm距离对应的屏上坐标长度SetData(b, "Local HMI", LW, 5, 1) //将X轴移动的定位虚线移动到原点SetData(b, "Local HMI", LW, 8, 1) //将Y轴移动的定位虚线移动到原点SetData(a, "MODBUS RTU", 4x, 1#102, 1) //将APCM控制字写进1号伺服65号参数SetData(a, "MODBUS RTU", 4x, 3#102, 1) //将APCM控制字写进2号伺服65号参数SetData(b, "Local HMI", LW, 13, 1)SetData(b, "Local HMI", LW, 14, 1) //将显示电机轴当前位置的元件移到原点GetData(pulsex, "Local HMI", RW, 20, 1)GetData(pulsey, "Local HMI", RW, 22, 1) //得到关机前电机X Y轴向已运行脉冲数SetData(pulsex, "MODBUS RTU", 4x, 1#145, 1) //将关机前电机X Y轴向已运行冲SetData(pulsey, "MODBUS RTU", 4x, 3#145, 1) //数写入已运行脉冲数0x90号的参end macro_command //数里/************************X Y轴停止*****************************/ macro_command main()bool a,ba=trueb=falseSetData(a, "MODBUS RTU", 0x, 1#3, 1)SetData(b, "MODBUS RTU", 0x, 1#3, 1) //X轴脉冲减速信号SetData(a, "MODBUS RTU", 0x, 3#3, 1)SetData(b, "MODBUS RTU", 0x, 3#3, 1) //Y轴脉冲减速信号SetData(a, "MODBUS RTU", 0x, 1#4, 1)SetData(b, "MODBUS RTU", 0x, 1#4, 1) //X轴脉冲到位信号SetData(a, "MODBUS RTU", 0x, 3#4, 1)SetData(b, "MODBUS RTU", 0x, 3#4, 1) //Y轴脉冲到位信号end macro_command/*************读取目标距离写入电机并记录本次电机轴位置*************/ macro_command main()float distance,distance1,distancex,distancey,x,y,c,d,g,h,j,k,l,mint pulsex,pulsey,pulsexx,pulseyy //pulsexx pulseyy:上次记录的已运行脉冲数short a,b,beishu,speedx,speedy,speedbool OFFspeed=40OFF=falseGetData(distancex, "Local HMI", LW, 0, 1)GetData(distancey, "Local HMI", LW, 2, 1) //读取目标距离元件里设定的X Y轴坐标distance1=distancex*distancex+distancey*distanceySQRT(distance1, distance)SetData(distance, "Local HMI", LW, 15, 1) //计算目标位置的径向距离c=distancex/5*127d=distancey/5*127 //计算当前设定目标位置在新坐标系上相对原点的位置x=c+438y=244-d //目标位置在屏幕原始坐标系上的坐标a=x-311b=y-117 //目标位置相对相对新坐标系左上角在X Y轴的变化距离SetData(a, "Local HMI", LW, 5, 1)SetData(b, "Local HMI", LW, 8, 1) //将目标位置的变化距离传给移动图形虚线pulsex=distancex*80000pulsey=distancey*80000 //将目标位置的坐标由毫米转化为脉冲数SetData(pulsex, "MODBUS RTU", 4x, 1#41, 1) //将需要运行的脉冲总数写入SetData(pulsey, "MODBUS RTU", 4x, 3#41, 1) //相应伺服SetData(OFF, "Local HMI", LB, 1, 1) //将触发该宏指令的位地址置1 GetData(pulsexx, "Local HMI", RW, 20, 1) //读取上次运行结束时X Y轴GetData(pulseyy, "Local HMI", RW, 22, 1) //已运行脉冲数j=pulsexx*1.0/80000k=pulseyy*1.0/80000 //计算出上次电机轴的位置(单位:mm) l=distancex-jm=distancey-k //计算两次目标位置之间的距离if l<=0 theng=(-1)*lelseg=lend if //计算X轴方向两次目标之间距离的绝对值if m<=0 thenh=(-1)*melseh=mend if //计算Y轴方向两次目标之间距离的绝对值if g==0 or h==0 thenSetData(speed, "MODBUS RTU", 4x, 1#44, 1) //如果有一个方向的目标位置相对上SetData(speed, "MODBUS RTU", 4x, 3#44, 1) //次没有变化,则将另一方向上的电机else if g>h then //速度设为40rpmbeishu=40/g //如果X轴向目标距离变化距离大于Y轴目标距离变化距离speedx=g*beishu //求出40除以最大变化距离得出的整数值speedy=h*beishu //将该整数值乘以每个轴向目标距离变化距离,取结果//的整数值作为该轴向的电机运行速度值SetData(speedx, "MODBUS RTU", 4x, 1#44, 1) //将求出的各轴电机运行速度值SetData(speedy, "MODBUS RTU", 4x, 3#44, 1)// 赋给相应伺服2B号参数else if g<=h then //如果Y轴向目标距离变化距离大于或等于X轴目标距离//变化距离beishu=40/h //求出40除以最大变化距离得出的整数值speedx=g*beishu //将该整数值乘以每个轴向目标距离变化距离,取结果speedy=h*beishu //的整数值作为该轴向的电机运行速度值SetData(speedx, "MODBUS RTU", 4x, 1#44, 1) //将求出的各轴电机运行速度值SetData(speedy, "MODBUS RTU", 4x, 3#44, 1) // 赋给相应伺服2B号参数end ifend macro_command/****************读取触碰点坐标并将各项参数写入伺服****************/ macro_command main()short x,y,a,b,e,f,speed,beishu,speedx,speedyfloat c,d,g,h,j,k,l,m,distance,distance1int pulsex,pulsey,pulsexx,pulseyyspeed=40GetData(x, "Local HMI", LW, 9042, 1)GetData(y, "Local HMI", LW, 9043, 1) //读取本次光标所点位置坐标e=x-311f=y-117 //计算出光标所点位置相对新坐标系左上角的变化距离SetData(e, "Local HMI", LW, 5, 1)SetData(f, "Local HMI", LW, 8, 1) //将光标位置变化传给移动图形虚线a=x-438b=244-yc=(a*1.0)/127*5 //计算出目标位置在新坐标系X轴上的坐标d=(b*1.0)/127*5 //计算出目标位置在新坐标系Y轴上的坐标pulsex=c*80000pulsey=d*80000 //求出各轴相对应的脉冲数pulsex=pulsex-pulsex%800pulsey=pulsey-pulsey%800 //修正发送的脉冲为800的倍数,因为驱动器接受//800个脉冲丝杠运行1丝(0.01mm)c=pulsex*1.0/80000d=pulsey*1.0/80000 //计算目标位置在新坐标系上的X Y坐标SetData(c, "Local HMI", LW, 0, 1)SetData(d, "Local HMI", LW, 2, 1) //准确显示目标位置在新坐标系上的X Y坐标distance1=c*c+d*dSQRT(distance1, distance)SetData(distance, "Local HMI", LW, 15, 1) //计算目标位置的径向距离SetData(pulsex, "MODBUS RTU", 4x, 1#41, 1)SetData(pulsey, "MODBUS RTU", 4x, 3#41, 1) //将各轴上脉冲数写入相应伺服GetData(pulsexx, "Local HMI", RW, 20, 1)GetData(pulseyy, "Local HMI", RW, 22, 1) //读取上次各轴已运行脉冲数j=pulsexx*1.0/80000k=pulseyy*1.0/80000 //计算上次电机位置l=c-jm=d-k //计算两次目标位置之间的距离if l<=0 then //本段程序注释与上个计算速度的程序的注释一样,在次就不注释g=(-1)*lelseg=lend ifif m<=0 thenh=(-1)*melseh=mend ifif g==0 or h==0 thenSetData(speed, "MODBUS RTU", 4x, 1#44, 1)SetData(speed, "MODBUS RTU", 4x, 3#44, 1)else if g>h thenbeishu=40/gspeedx=g*beishuspeedy=h*beishuSetData(speedx, "MODBUS RTU", 4x, 1#44, 1)SetData(speedy, "MODBUS RTU", 4x, 3#44, 1)else if g<=h thenbeishu=40/hspeedx=g*beishuspeedy=h*beishuSetData(speedx, "MODBUS RTU", 4x, 1#44, 1)SetData(speedy, "MODBUS RTU", 4x, 3#44, 1)end ifend macro_command/*********将反馈回的脉冲传给图形工作台并保存当前电机轴位置*********/ macro_command main()int pulsex,pulseyshort x,y,x1,y1,a,bfloat distance,distance1GetData(pulsex, "MODBUS RTU", 4x, 1#145, 1)GetData(pulsey, "MODBUS RTU", 4x, 3#145, 1) //读取各轴已运行脉冲数distance1=(pulsex*1.0/80000)*(pulsex*1.0/80000)+(pulsey*1.0/80000)*(pulsey*1.0 /80000)SQRT(distance1, distance) //计算出当前电机轴位置在新坐标系上的径向距离SetData(distance, "Local HMI", LW, 17, 1) //显示当前电机的径向位移x=(pulsex*1.0)/80000/5*127y=(pulsey*1.0)/80000/5*127 //当前电机轴在屏幕坐标系上的位置a=127+xb=127-ySetData(a, "Local HMI", LW, 13, 1)SetData(b, "Local HMI", LW, 14, 1) //将电机轴坐标变化传给移动图形工作台SetData(pulsex, "Local HMI", RW, 20, 1)SetData(pulsey, "Local HMI", RW, 22, 1) //保存当前电机轴位置end macro_command/*********************原点校正图形工作台回归**********************/ macro_command main()int bshort aa=127b=0SetData(a, "Local HMI", LW, 13, 1)SetData(a, "Local HMI", LW, 14, 1) //移动图形图形工作台到原点SetData(b, "MODBUS RTU", 4x, 1#145, 1)SetData(b, "MODBUS RTU", 4x, 3#145, 1) //将已运行脉冲数置0 SetData(b, "Local HMI", RW, 20, 1)SetData(b, "Local HMI", RW, 22, 1) //记录原点校正后的电机轴坐标(0.00,0.00 ) end macro_command/*********************X轴报警清楚复位**********************/macro_command main()bool OFFOFF=falseDELAY(1000) //报警清除地址置ON后延时1s,清楚报警SetData(OFF, "MODBUS RTU", 0x, 1#9, 1) //报警清除位地址复位end macro_command/*********************Y轴报警清楚复位**********************/macro_command main()bool OFFOFF=falseDELAY(1000) //报警清除地址置ON后延时1s,清楚报警SetData(OFF, "MODBUS RTU", 0x, 3#9, 1) //报警清除位地址复位end macro_command/*********************X轴恒距点动递加**********************/macro_command main()int pulse,pulsexshort speed,a,bbool OFF,ONspeed=40ON=trueOFF=falseGetData(pulse, "MODBUS RTU", 4x, 1#145, 1) //读取当前已运行脉冲数pulsex=pulse+800 //将目标脉冲数设定为当前已运行脉冲数+800 a=pulsex*1.0/80000/5*127 //目标位置X轴距离b=127+aSetData(b, "Local HMI", LW, 5, 1) //移动X轴向移动的虚线到目标位置SetData(pulsex, "MODBUS RTU", 4x, 1#41, 1) //写入脉冲个数SetData(speed, "MODBUS RTU", 4x, 1#44, 1) //写入运行速度SetData(ON, "MODBUS RTU", 0x, 1#5, 1)SetData(OFF, "MODBUS RTU", 0x, 1#5, 1) //启动DELAY(2000)GetData(pulse, "MODBUS RTU", 4x, 1#145, 1) //读取当前已运行脉冲SetData(pulse, "Local HMI", RW, 20, 1) //保存电机轴当前位置end macro_command/*********************X轴恒距点动递减**********************/macro_command main()int pulse,pulsexshort speed,a,bbool OFF,ONspeed=40ON=trueOFF=falseGetData(pulse, "MODBUS RTU", 4x, 1#145, 1) //读取当前已运行脉冲pulsex=pulse-800 //将目标脉冲数设定为当前已运行脉冲数-800 a=pulsex*1.0/80000/5*127 //目标位置X轴距离b=127+aSetData(b, "Local HMI", LW, 5, 1) //移动X轴向移动的虚线到目标位置SetData(pulsex, "MODBUS RTU", 4x, 1#41, 1) //写入脉冲个数SetData(speed, "MODBUS RTU", 4x, 1#44, 1) //写入运行速度SetData(ON, "MODBUS RTU", 0x, 1#5, 1)SetData(OFF, "MODBUS RTU", 0x, 1#5, 1) //启动DELAY(2000)GetData(pulse, "MODBUS RTU", 4x, 1#145, 1) //读取当前已运行脉冲SetData(pulse, "Local HMI", RW, 20, 1) //保存电机轴当前位置end macro_command/*********************Y轴恒距点动递加**********************/ macro_command main()int pulsey,pulseshort speed,a,bbool OFF,ONspeed=40ON=trueOFF=falseGetData(pulse, "MODBUS RTU", 4x, 3#145, 1) //读取当前已运行脉冲pulsey=pulse+800 //将目标脉冲数设定为当前已运行脉冲数+800 a=pulsey*1.0/80000/5*127 //目标位置Y轴距离b=127-aSetData(b, "Local HMI", LW, 7, 1) //移动Y轴向移动的虚线到目标位置SetData(pulsey, "MODBUS RTU", 4x, 3#41, 1) //写入脉冲SetData(speed, "MODBUS RTU", 4x, 3#44, 1) //写入速度SetData(ON, "MODBUS RTU", 0x, 3#5, 1) //启动SetData(OFF, "MODBUS RTU", 0x, 3#5, 1)DELAY(2000)GetData(pulse, "MODBUS RTU", 4x, 3#145, 1) //读取当前已运行脉冲SetData(pulse, "Local HMI", RW, 22, 1) //保存电机轴当前位置end macro_command/*********************Y轴恒距点动递减**********************/ macro_command main()int pulsey,pulseshort speed,a,bbool OFF,ONspeed=40ON=trueOFF=falseGetData(pulse, "MODBUS RTU", 4x, 3#145, 1) //读取当前已运行脉冲pulsey=pulse-800 //将目标脉冲数设定为当前已运行脉冲数-800 a=pulsey*1.0/80000/5*127 //目标位置Y轴距离b=127-aSetData(b, "Local HMI", LW, 7, 1) //移动Y轴向移动的虚线到目标位置SetData(pulsey, "MODBUS RTU", 4x, 3#41, 1) //写入脉冲SetData(speed, "MODBUS RTU", 4x, 3#44, 1) //写入速度SetData(ON, "MODBUS RTU", 0x, 3#5, 1) //启动SetData(OFF, "MODBUS RTU", 0x, 3#5, 1)DELAY(2000)GetData(pulse, "MODBUS RTU", 4x, 3#145, 1) //读取当前已运行脉冲SetData(pulse, "Local HMI", RW, 22, 1) //保存电机轴当前位置end macro_command/*************8*************原点回归***************************/ macro_command main()int pulse,pulsex,pulseyfloat distance,g,h,l,mshort a,speed,speedx,speedy,beishubool ON,OFFpulse=0a=127distance=0speed=40ON=trueOFF=falseSetData(pulse, "MODBUS RTU", 4x, 1#41, 1)SetData(pulse, "MODBUS RTU", 4x, 3#41, 1) //将两轴脉冲总数置为0 SetData(a, "Local HMI", LW, 5, 1)SetData(a, "Local HMI", LW, 8, 1) //虚线回归原点SetData(distance, "Local HMI", LW, 0, 1)SetData(distance, "Local HMI", LW, 2, 1) //目标距离元件置0GetData(pulsex, "MODBUS RTU", 4x, 1#145, 1)GetData(pulsey, "MODBUS RTU", 4x, 3#145, 1) //读取已运行脉冲数l=pulsex*1.0/80000m=pulsey*1.0/80000 //计算出本次电机位置if l<=0 then //本段程序注释与上边计算速度的程序的注释一样,在次不再注释g=(-1)*lelseg=lend ifif m<=0 thenh=(-1)*melseh=mend ifif g==0 or h==0 thenSetData(speed, "MODBUS RTU", 4x, 1#44, 1)SetData(speed, "MODBUS RTU", 4x, 3#44, 1)else if g>h thenbeishu=40/gspeedx=g*beishuspeedy=h*beishuSetData(speedx, "MODBUS RTU", 4x, 1#44, 1)SetData(speedy, "MODBUS RTU", 4x, 3#44, 1)else if g<=h thenbeishu=40/hspeedx=g*beishuspeedy=h*beishuSetData(speedx, "MODBUS RTU", 4x, 1#44, 1)SetData(speedy, "MODBUS RTU", 4x, 3#44, 1)end ifSetData(ON, "MODBUS RTU", 0x, 1#5, 1)SetData(OFF, "MODBUS RTU", 0x, 1#5, 1) //启动X轴伺服电机SetData(ON, "MODBUS RTU", 0x, 3#5, 1)SetData(OFF, "MODBUS RTU", 0x, 3#5, 1) //启动Y轴伺服电机end macro_command/*************8**********读取上次电机轴位置***********************/ macro_command main()int pulsex,pulseyshort x,y,a,b,cc=1GetData(pulsex, "Local HMI", RW, 20, 1)GetData(pulsey, "Local HMI", RW, 22, 1) //读取上次电机轴位置(已运行脉冲数) SetData(pulsex, "MODBUS RTU", 4x, 1#145, 1) //将上次电机轴位置(已运行脉冲数) SetData(pulsey, "MODBUS RTU", 4x, 3#145, 1)//写入各个伺服驱动器0x90号参数x=(pulsex*1.0)/80000/5*127y=(pulsey*1.0)/80000/5*127 //计算当前工作台位置a=127+xb=127-ySetData(a, "Local HMI", LW, 13, 1)SetData(b, "Local HMI", LW, 14, 1) //将工作台变化传给移动图形工作台SetData(c, "Local HMI", LB, 20, 1)end macro_command赵群辉2011-1-19。