ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

无圆弧插补也画圆:三菱FX3U脉冲输出两轴联动实战拆解

无圆弧插补也画圆:三菱FX3U脉冲输出两轴联动实战拆解

前段时间我接到一个挺有意思的需求:用一台三菱FX3U的脉冲输出功能,带动两轴XY平台,在平面上画一个整圆出来。初听这个需求,很多人的第一反应是“FX3U又没有圆弧插补指令,拿什么画圆?”——没错,FX3U本体确实不带G02/G03这种圆弧插补,但真正做下来你会发现,画圆这件事的本质,是把一个圆拆成足够多段的小直线,然后用两轴同时发脉冲去逼近。这个小案例如果拆开看,恰好能把PLC运动控制里最核心的坐标系、变量定义、脉冲当量、两轴联动逻辑全部走一遍。这篇文章就按我当时的思路,从变量定义开始,把整个逻辑彻底展开聊清楚。

1. 画圆先定坐标系:变量规划与脉冲当量是整段逻辑的地基

1.1 为什么“没有圆弧插补”也能画圆

先确认一个基本概念:FX3U的脉冲输出功能,本质上是按照你给定的脉冲数和频率往某个输出端子发脉冲。它不知道什么是圆,它只认识“往X轴发多少个脉冲、往Y轴发多少个脉冲”。如果X轴和Y轴同时按某种比例发脉冲,机械末端走出来的就是一个斜向直线;把这个直线切成无数小段,每一段的角度稍微变化一点,整体轨迹就逼近圆弧。三角函数算出来的理论圆点,通过一段一段的微小直线去追,就是画圆的全部秘密。

用生活化的话来说:你在纸上画圆,圆规画的是真正的圆弧;但如果只给你一把直尺,你也能画出一个近似的圆——只要把圆分成足够多的边,多到肉眼分辨不出棱角。PLC的画圆就是“直尺法”,而这把“直尺”就是两轴同时输出的脉冲组合。这个认知是整个案例的地基,理解了它,后面所有代码都顺理成章。

1.2 一套可直接落地的软元件变量表

标题里说“先从变量定义开始”,这不是唠嗮,而是我非常强烈的建议。画圆涉及半径、圆心、当前角度、角度增量、两轴目标位置、当前实际位置、运行状态等若干数据,如果没有一张清晰的变量表,写到后面一定乱成一片。我当时在触摸屏和PLC里统一规划了这样一张软元件表,你可以直接拿去改地址用。

软元件类型/长度作用说明
D0浮点(32位)圆的半径,单位mm,例:25.0
D2浮点(32位)圆心X坐标,单位mm
D4浮点(32位)圆心Y坐标,单位mm
D10浮点(32位)当前角度,单位弧度
D12浮点(32位)每段角度增量,单位弧度
D20浮点(32位)X轴理论绝对位置,单位脉冲
D22浮点(32位)Y轴理论绝对位置,单位脉冲
D3032位整数X轴本段目标脉冲位移量
D3232位整数Y轴本段目标脉冲位移量
D4032位整数本段较大轴的输出频率,单位Hz
D5032位整数目标段数(比如360段)
D6032位整数当前已执行的段数
M0位启动按钮
M1位暂停/继续
M10位运行中标志
M11位当前段完成标志

这里有几个容易忽略的细节:

  • 浮点变量在FX3U里占用两个连续数据寄存器,比如D20实际占D20和D21,写程序时不要和别的变量挤在一起。
  • 角度我用“弧度”存,因为FX3U的三角函数指令ASIN、ACOS、SIN、COS都是按弧度计算的,如果按角度算,最后结果会差很多。
  • D30和D32我建议用32位整数,因为半径稍微大一点,一轴脉冲数就可能超过32767,16位装不下。
  • 状态标志位集中放在M区,不要去占用定位指令的特殊辅助继电器区域,避免干扰。

1.3 脉冲当量换算:毫米坐标怎么变成脉冲坐标

画圆的时候,圆半径、圆心坐标这些参数,操作工肯定习惯用毫米,但PLC发脉冲只认“多少个脉冲”。所以第一步是先把毫米和脉冲建立关系。这里有一个非常关键的单位概念:脉冲当量,也就是“一个脉冲能带动机械末端移动多少毫米”。

拿我手头这套平台举例:X轴的伺服电机经过减速后带动丝杠,丝杠导程是10mm;伺服驱动器电子齿轮设为每圈10000个脉冲。那么脉冲当量就是10mm \div 10000 = 0.001mm/脉冲,也就是说1个脉冲移动0.001mm,非常直观。Y轴如果机械结构和X轴一样,脉冲当量也相同。

脉冲当量算好之后,半径为25mm的圆,在PLC眼里就是25000个脉冲半径。以后所有计算公式都直接在脉冲单位下进行,不再混用毫米。这一步做扎实,后面程序里数字为什么会大几百倍、几千倍,就不会莫名其妙了。

如果你用的是步进电机,也非常简单:步进驱动器细分数设为比如2000步/圈,也就是每圈2000个脉冲,配合丝杠导程10mm,脉冲当量就是10 \div 2000 = 0.005mm/脉冲。只要两轴机械一致,公式完全通用。

2. 圆弧拆解算法:从三角函数到绝对目标取整,误差怎么控

2.1 把圆离散成多少段才够:弦长和弓高误差计算

画圆的第一步是决定拆成多少段。段数太少,圆弧看起来就是多边形;段数太多,每段执行时间太短,对PLC扫描周期和输出频率的要求会变得非常苛刻。工程上一般不允许拍脑袋定这个数,而是要用弓高误差来算。

把一段圆弧近似成一条直线段,直线和圆弧之间会有一个最大间隙,这个间隙叫“弓高误差”。如果半径用脉冲数R表示,每段对应的圆心角为\Delta\theta,那么弓高误差的近似公式是:

e \approx R \times (1 - \cos(\tfrac{\Delta\theta}{2}))

回到我的参数:R=25000脉冲,把圆平均分成360段,也就是每段1°,\Delta\theta / 2 = 0.5°。\cos0.5°约等于0.9999619,代入公式:

e \approx 25000 \times (1 - 0.9999619) \approx 0.95脉冲

0.95个脉冲是什么概念?换算成毫米是0.00095mm,远远小于我一个脉冲当量0.001mm,也就是说,从几何误差的角度,360段已经完全够了,就算肉眼带放大镜也看不出棱角。

如果把段数提高到720段,弓高误差降到约0.24脉冲,但每段执行时间会缩短一半,两轴切换频率更高。所以我的实际建议是:圆周等分成360到720段,优先用360段,先用它跑通逻辑,如果视觉检查不够圆再加密。

这里顺带说一个常见误区:有些人觉得段数越多精度越高,于是直接上千段。但你还要考虑每段的执行时间。比如圆周运动速度想做到20mm/s,周长是157mm,整个圆要7.85秒走完,360段时每段约21.8毫秒;如果分1440段,每段就只有5.4毫秒。PLC一个扫描周期加上定位指令启动时间,可能就要2-3毫秒,剩下给脉冲输出的时间很短,两轴还没提起速度就又要切换目标了,实际效果反而不如360段。

2.2 在PLC里用浮点算坐标:指令与程序片段

离散段数确定后,每一段的理论坐标就按照圆的参数方程来计算:

X_i = R \times \cos\theta_i
Y_i = R \times \sin\theta_i

这里的\theta_i是第i段对应的当前角度,从0开始,每执行完一段加上\Delta\theta。我选择在PLC内部实时计算,因为没有用到任何轴反馈插补功能,只要在每次启动下一段前把目标坐标算出来即可。FX3U虽然运算速度不算快,但画圆这种低速运动场景完全够用。

程序核心片段用指令表写出来大致是这个逻辑:

; 假设M100是每段的触发脉冲 LD M100 RAD D10 ; 当前角度弧度转换为浮点放入D10 DCOS D10 D110 ; cos值存入D110(浮点) DEMUL D20 D110 D120 ; 半径(D20) × cos → X轴理论值D120 DEINT D120 D130 ; 浮点转整数,X轴理论绝对位置 DMOV D130 D140 ; 保存X轴绝对目标 ; Y轴同理 DSIN D10 D112 DEMUL D20 D112 D122 DEINT D122 D132

这里要提醒一句:FX3U的浮点指令在程序里会占用多个数据寄存器,比如D110可能实际占D110和D111,不要为了省寄存器把结果放得太密,否则后一条指令会覆盖前一条结果。

我当时的程序里还放了一个“已执行段数计数器D60”,每走完一段加1。当D60大于等于目标段数D50时,M10自动复位,输出一个“画圆完成”标志。这个计数器也是后续调试定位问题的重要抓手,稍后会详细说。

2.3 绝对目标取整法:不让取整误差滚雪球

这是整个画圆案例里我认为最值得记下来的一点。三角函数算出来的坐标基本都是小数,比如25000 \times \cos1°约等于24996.19,但PLC发脉冲只能发整数个脉冲,所以必须取整。

很多初学者会做一步算一步的“增量法”:先算这一段X方向的增量,比如理论增量是-3.81,取整成-4,然后让X轴走-4个脉冲。这种做法看似没问题,但每一段都有取整误差,时间长了误差会一直累积,圆越走越偏。

正确做法是“绝对目标取整法”:每段都先计算该时刻X轴的绝对理论位置,取整后作为目标,然后用“本段目标绝对位置”减去“当前实际位置”,得到本段应该走的相对位移。这样即使某一小段取整出现了偏差,下一段计算时会自动以绝对位置为准修正回来,误差不会滚雪球。用公式表示:

本段位移 = 取整(当前角度的理论绝对位置) - 取整(上一段角度的理论绝对位置)

我当时先在D140里算出当前的绝对目标,再通过减法指令把D140减去当前轴位置寄存器D8140代表的实际位置,得到相对位移D30,再交给两轴定位指令。这段逻辑是整个程序里最值钱的部分,能理解它,以后做直线插补、斜线运动也都能用上。

3. 两轴联动输出:DDRVI时序、速度分配与段间停顿

3.1 DDRVI的基本用法:两轴同时开始同时结束

FX3U里有几个定位指令,DRVI是单轴相对定位,DDRVI则是“两轴同时定位”。DDRVI的奥妙在于它会让两个轴在同一时间段内完成各自指定的脉冲数,同时起步、同时结束。这正好符合我们每一段小直线的要求:X轴走\Delta X个脉冲,Y轴走\Delta Y个脉冲,两轴同步走完,轨迹就是从起点到终点的斜线。

我当时的调用逻辑大致是:

; D30 = X轴本段位移量(脉冲), D32 = Y轴本段位移量(脉冲) ; D40 = 较大轴输出频率 DDRVI D30 D32 D40 Y0 Y1

不同版本的FX3U手册里,DDRVI的操作数排列可能略有差异,有的版本把两个输出端子作为独立操作数,有的则按轴号写。你用的时候一定要打开自己固件对应的指令手册核对,我这里想强调的是它的行为逻辑:两轴按各自的脉冲数、在同一个时间段内完成运动。

这里有个非常讨巧的地方:我们不需要分别给X轴和Y轴单独算速度。DDRVI会自动按位移比例分配两轴的实际输出频率。位移大的轴跑快一些,位移小的轴跑慢一些,时间保持一致。圆的360段里,靠近0°的地方X轴位移很小、Y轴位移很大,靠近90°的地方反过来,DDRVI会把这种速度变化自动处理好。

3.2 速度分配逻辑:为什么不需要单独算两轴频率

如果不用DDRVI,而是两条独立的PLSY指令分别发脉冲,那你就得手动维护两轴的频率,让每一段的X轴频率和Y轴频率呈特定的三角函数关系,否则走出来的轨迹完全不是圆。这是很多人觉得画圆难的核心原因。

DDRVI把这个难点消解了:你只要给一个“合成速度”,它自动分解给两轴。这个合成速度具体指哪一根轴,不同手册叫法不一样,但结果都是两轴在同一时间内走完各自的位移。我在程序里用了一个最简单的策略:把每段时间固定,然后根据本段最大位移轴算出频率。比如本段较大的一轴要走2500个脉冲,计划20毫秒走完,那频率就是2500 \div 0.02 = 125000Hz,如果超过FX3U的100kHz上限,就自动把每段时间拉长,保证不超频。

这个“时间固定、按最大轴算频率”的套路,让我在实际调试中省了很多事。你不需要在程序里实时算sin、cos,然后去微调每个轴的速度,DDRVI会帮你完成近似直线插补。

3.3 段间过渡的实际感受:停顿、加减速和缓解办法

理论上每段都是完美的斜线,但实际执行中段与段之间有一个无法忽略的问题:PLC执行完一段DDRVI后,要等定位完成标志置位、扫描程序到下一段、再启动新的DDRVI,这中间会有几毫秒的间隙。对步进系统来说,这个间隙会让轨迹在每个离散点出现一个极小的“停一下再走”的效应;对伺服系统来说,每停一次就要重新整定一次,路径上容易出现肉眼可见的棱角。

我当时调试时测试了三组数据:每段执行时间在50毫秒左右,间隙约2毫秒,停顿占比4%,实际画的圆肉眼看不出棱角;把每段时间压到10毫秒,间隙占比20%,圆上明显出现小台阶。所以并不是段数越多越好,还要保证每段执行时间不要过短。

缓解办法有几个方向:

  • 提高定位完成标志的响应速度,把下一段启动逻辑放在紧贴定位指令后面的一个扫描周期内,不要中间夹太多无关指令。
  • 在驱动器侧把步进细分调高一点,让同样脉冲数下的机械分辨率更高,小台阶被机械系统平均掉。
  • 如果项目要求高,可以考虑用带表格定位或连续插补的定位模块,但那是另一个成本层级了。

对大多数演示和中等精度要求,FX3U+DDRVI逐段走完全足够。

4. 实机调试:圆不圆、不闭合、象限点起刺的原因排查

4.1 用监控数据定位“差多少”

程序写完之后,真正花时间的从来都是调试。第一个问题就是:怎么量化判断圆画得准不准?肉眼只能看出“圆不圆”,看不出“差了多远”。我的做法是直接监视PLC里的位置寄存器。

FX3U的Y0轴当前值存储在某些32位数据寄存器里,走完一整圈后,两轴应当回到起点,也就是X和Y的相对位移都归零。如果读回来的值不是0,比如X轴还有+15个脉冲,说明某一段X轴实际发出去的脉冲数比理论值多了15个,可能是丢脉冲、反向间隙或者程序计算错误。

走完一圈后我还会顺带看一下D60已执行段数是否等于360。如果程序中途因为某个段计算没通过而跳过,计数器会漏记,这个从数据上很容易发现。

4.2 四个常见“圆病”的症状、原因和对策

我把调试中常见的现象整理成一张表,排查起来会非常快:

现象可能原因处理思路
圆的多边形感明显,像切了很多刀离散段数太少,弓高误差大增加段数到360/720,或增大每段执行时间
画几圈之后圆整体偏移或越来越不圆用了增量取整法导致误差累积改为绝对目标取整法,用绝对位置差算位移
某个象限点有明显凹坑或尖角反向间隙、方向信号切换延迟给该轴做反向间隙补偿,检查方向端子接线
速度越快越不圆,低速圆正常伺服跟随误差或步进丢步降低画圆速度,检查加减速时间设置

象限点问题是最能体现“机械细节”的一块。圆在0°、90°、180°、270°时,某一轴会切换方向。丝杠存在反向间隙时,方向一换,螺母要先把间隙吃掉才会真正推动工作台,反映到轨迹上就是象限点附近多了一条小凹痕。如果是伺服系统,方向切换瞬间还有个位置环整定过程。这个坑在你做任意圆形轨迹时都会遇到,属于跑不掉的经验。

4.3 一个完整的调试checklist

下面这份清单是我在调试时从头到尾过一遍的流程,照着顺序走可以少走很多弯路:

  1. 确认两轴脉冲当量一致,把半径从毫米换算成脉冲数。
  2. 先用慢速、大半径、大段执行时间跑第一圈,避免运动过快导致撞限位。
  3. 单步方式只执行一段,核对D30和D32的数值方向是否符合预期。
  4. 连续执行10段左右,暂停,用位置寄存器看是否到达理论位置。
  5. 完整跑一圈,检查已执行段数是否等于目标段数。
  6. 用指针表和百分表打表,如果圆度不达标,优先检查反向间隙和段间停顿。

如果调试时发现某轴的位移方向总反,最简单的是在DDRVI指令的方向输出端子或驱动器参数里把方向反转,不要随便改坐标公式里的正负号,否则后续算椭圆、螺旋线时会把自己绕晕。

5. 从画圆案例里提炼出的运动控制经验

5.1 方法论:绝对坐标差、变量分区、参数外置

做这个案例最大的收获,与其说是“FX3U能画圆”,不如说是把一套运动控制方法论跑通了一遍。它有三个核心原则,可以迁移到几乎所有两轴轮廓控制场景:

第一,始终用绝对坐标差来计算相对位移,而不是直接累加每一步的取整结果。这是所有插补逻辑里的通用思想,不管控制器是PLC还是运动控制卡,用绝对坐标作为基准,误差就不会累积。

第二,变量分区要清晰,参数区和运行状态区分开。把手写变量表变成你写程序的习惯。半径、圆心、段数、速度这些参数集中在固定区域,运行中的理论坐标、实际坐标、计数标志放另一片区域,调试时一目了然。

第三,参数外置到触摸屏。我把半径、段数、圆周速度都做到触摸屏上,现场改圆的大小、快慢不用重新下载程序。调试画圆时,能一边改参数一边看图形,效率翻倍。

5.2 这个逻辑还能扩展成什么

理解了“用直线逼近圆”,后面很多看似复杂的轨迹都可以顺势做出来。

椭圆其实只需要把两轴半径改成不同的值,公式从 x = R\cos\theta 变成 x = R_x\cos\theta、y = R_y\sin\theta,其他逻辑完全不动。螺旋线则是把半径随时间线性增大。甚至可以直接把一条任意曲线离散成若干点,存进PLC的数据表格,用同样的“绝对目标取整法”一段段走。这也解释了为什么现在很多运动控制卡都内置电子凸轮、轮廓插补功能——本质上都是在帮用户把轮廓点化、再把点翻译成脉冲。

如果你手头没有触摸屏,也可以先用电脑串口监控D区的值来验证算法;把PLC跑起来后,读回来一段当前值做曲线拟合,通常偏差都出在机械振动和反向间隙上,而不是软件计算上。

最后再分享一个我后来一直沿用的习惯:第一次跑新轨迹之前,先在纸上手算三五个数据点,比如0°、45°、90°对应的坐标差,然后用单步模式验证PLC算出来的位移和你手算的一致,再放开来跑。这个习惯看起来原始,但能瞬间暴露单位、公式、符号方向的问题,比直接看机器画歪了再回头查程序高效得多。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进