电子齿轮与MC_GearInPos位置同步实战:PLC代码与调试技巧
发布时间:2026/10/6 6:40:23 作者:尧图编辑部 阅读量:1,286

做运动控制的工程师几乎都会遇到一个绕不开的需求两根轴要按照固定比例同步运动——主轴转一圈从轴必须精确地转两圈主轴加减速从轴必须跟着同步变化中间不能有一丝迟滞更不能有速度跳变。这就是电子齿轮干的事。但如果只是简单地把两根轴用MC_Gear一挂很多现场会发现一个尴尬的局面耦合瞬间设备“哐当”一震同步建立后相位还慢慢偏产品废品率直线上升。问题出在哪里答案多半是你用错了功能块。今天这篇文章我拿Codesys平台上的MC_GearInPos来拆一个实战案例主轴牵引辊、从轴压印轮怎么做到“主轴走到指定位置从轴正好在那个点上进入齿轮比”从原理、参数、完整PLC代码到调试现场踩过的坑一次讲透。适合正在做电子齿轮同步、飞剪追剪、印刷套准、卷绕联动这类项目的PLC工程师和调试人员参考。1. 电子齿轮与MC_GearInPos为什么需要“位置触发”的同步1.1 电子齿轮解决的核心痛点电子齿轮的本质就是让从轴的速度与主轴保持一个恒定的比例关系而这个比例与机械传动无关是通过软件实时计算的。机械齿轮是靠齿数比锁死角度电子齿轮则把这种“锁死”提前到算法层面所以也叫虚拟齿轮。举个例子一个压印工位主轴带着产品往前走从轴带压花轮压在材料上。机械上如果做成链条或齿轮硬连接换产品规格时必须换齿轮非常痛苦用电子齿轮只需要改两个参数——齿轮比分子和分母。从轴速度 主轴速度 × 分子 ÷ 分母改起来就是触摸屏上打个数字的事。但电子齿轮真正难的不是“速度比例算不准”而是“同步关系建立的那一刻”。一旦主轴和从轴之间的速度关系不是从0开始连续过渡而是瞬间拉到位冲击、打滑、机构磨损、产品划伤全来了。很多电气工程师第一反应是挂个MC_Gear不就行了对把Execute置TRUE从轴立刻进入齿轮比。但此时主轴可能已经跑到300mm/s从轴还停在那里功能块会强制从轴速度瞬间追上主轴理论上加速度无限大实际上就是伺服报警、机械震动、断刀、伤辊。所以电子齿轮要解决的核心痛点不是“比例能不能保持”而是“怎么平滑地进入和退出这个比例关系”。这就是MC_GearInPos存在的意义。1.2 普通MC_Gear与MC_GearInPos的关键区别我的理解里普通MC_Gear是一个“无脑离合器”踩下去就挂上不管两边转速差而MC_GearInPos是一个“带同步点的智能离合器”它允许你告诉系统当主轴到达某个位置时从轴应该在哪个位置并且在此之前留一段距离给从轴做加速调整。两者最核心的差别在于MC_Gear只能保证速度比不能保证位置相位。什么意思两条轴都按2:1转但如果进入时刻的起始相位不对从轴和主轴之间的角度关系就是错的压花就会压偏。而MC_GearInPos可以在建立同步的同时强制指定“主轴到这个位置时从轴正好在那个位置”相位关系一次性锁定。材质上打个比方普通齿轮是“先接上再矫正”MC_GearInPos是“先矫正再接上”。实际项目中需要精确相位关系的场合非常多。印刷机的色标套准、飞剪的剪切断长、模切机的刀模位置、卷绕机的收卷张力这些都不仅仅是“速度成比例”而是“角度/位置严格锁定”。你如果只用MC_Gear后面还得额外写位置补偿逻辑麻烦且不稳定直接上MC_GearInPos相位锁定的问题在功能块内部就解决了。2. 算法原理与关键参数拆解2.1 电子齿轮比的计算与标定电子齿轮比的公式很简单从轴速度等于主轴速度乘以分子除以分母。但这个比例到底取多少很多新手工容易凭感觉填。先看机械关系。假设主轴辊筒直径是D1从轴辊筒直径是D2生产线要求两者表面线速度一致也就是材料不打滑、不堆积。那么主轴线速度 π × D1 × 主轴辊转速 从轴线速度 π × D2 × 从轴辊转速要让两个线速度相等就有从轴辊转速 ÷ 主轴辊转速 D1 ÷ D2。再考虑减速机速比。设主轴电机到辊筒的减速比是i1从轴是i2电机转速是辊筒转速的i倍最终电子齿轮比就变成电子齿轮比 (D1 × i2) ÷ (D2 × i1)比如我这次的项目主轴辊径80mm从轴辊径82mm加工误差造成的两边减速机都是10:1理论齿轮比就是 80/82 × 10/10 0.9756。写成分子分母就是 40/41 左右。这是我用的公式但别急着填进去。实际项目中辊径会因为包胶磨损而改变减速机本身也有回程差所以最终要在空载低速下实测确定让主轴转N圈数从轴编码器反馈转了多少圈反推实际比值再把实测值微调进去。我通常会在触摸屏上留一个“齿轮比修正”的隐藏页方便现场工程师在设备跑起来之后在线微调这个习惯救过我很多次。2.2 MC_GearInPos的输入输出参数详解在Codesys以及汇川AM系列、信捷XD5等Codesys衍生平台上MC_GearInPos功能块的输入输出参数并不完全一样但核心逻辑是一致的。我按最常见的PLCopen规范版本来拆参数名类型作用ExecuteBOOL上升沿触发建立齿轮耦合MasterAXIS_REF主轴参考站得越高语法上是主站SlaveAXIS_REF从轴被耦合的轴RatioNumeratorLREAL齿轮比分子RatioDenominatorLREAL齿轮比分母MasterSyncPositionLREAL主轴同步位置主轴到达该位置时完成耦合SlaveSyncPositionLREAL从轴同步位置与主轴同步位置对应MasterStartDistanceLREAL主轴预同步距离在此距离内开始速度调整SlaveStartDistanceLREAL从轴预同步距离AccelerationLREAL同步过程中的加速度DecelerationLREAL同步过程中的减速度JerkLREAL加加速度决定冲击程度BufferModeMC_BufferMode缓冲模式一般用Aborting输出主要有Done同步完成、Active齿轮耦合处于激活状态、Error/ErrorID错误反馈。注意Active不等于Done。Active表示耦合已经建立并且在实时保持Done表示“建立这个动作”已经执行完毕。在我的程序中耦合建立之后我主要监视ActiveDone只用来看一次完成沿。2.3 同步位置与预同步距离的几何意义这两个参数是整个MC_GearInPos的灵魂。我换成一幅动态画面来理解主轴上有一个移动的目标点当它到达MasterSyncPosition时从轴上有个预设点正好位于SlaveSyncPosition此刻开始两轴像齿轮一样锁死。为什么会需要这组位置说白了耦合的瞬间要保证“位置连续”。如果从轴当前在100mm你设定的SlaveSyncPosition是0mm那么功能块会在一瞬间把从轴从100mm拉到0mm那又是一次暴力冲击。正确做法是把SlaveSyncPosition设成从轴当前实际位置并让主轴的MasterSyncPosition等于触发耦合瞬间主轴的位置。这样耦合的瞬间两边已经对齐了冲击最小。但这条规则有一个前提——从轴和主轴的当前速度差不能太大。如果你的从轴静止、主轴已经在跑300mm/s同步点处速度还是会有阶跃只是位置没错。解决这个问题靠的正是MasterStartDistance和SlaveStartDistance。预同步距离的意思是在到达同步点之前这段距离内从轴提前开始加速或减速目标是让它在同步点处的速度等于齿轮比所要求的速度。这样一来同步点既是位置连续又是速度连续整个耦合过程无感。如果预同步距离设小了从轴来不及加速到目标速度同步点处就会出现速度阶跃。理论上预同步距离至少要大于从轴以给定加速度从当前速度加速到目标速度所走过的路程公式是S v² / (2a)其中v是速度差a是加速度。举个具体数从轴静止主轴速度300mm/s齿轮比2:1则目标从轴速度为600mm/s速度差600mm/s加速度设800mm/s²最小距离就是600²/(2×800)225mm。如果我把MasterStartDistance设为50mm明显不够从轴只能疯狂加速到了同步点还是追不上结果就是功能块报错或者冲击。所以预同步距离宁大勿小。3. 项目实战配置与完整PLC代码3.1 硬件平台与项目场景这个项目实际是一条包装材料的压印分切线。主轴是牵引伺服带一个80mm直径的送料辊从轴是压印伺服带一个82mm直径的压花轮。控制要求是材料以300mm/s前进当材料走200mm之后压花轮要在同步点进入2:1的齿轮比关系即主轴转1圈、从轴压花轮转2圈完成一个压印周期。等主轴走了800mm解除耦合压花轮抬起回到起始位置等待下一个周期。硬件上用的是支持Codesys的中型PLC两个伺服轴走EtherCAT总线伺服驱动器带绝对值编码器。主轴和从轴都是普通的旋转伺服电机带10:1行星减速机。这里要提醒一句如果你的主轴不是伺服而是外部编码器比如老设备改造主轴是编码器信号直接进PLC的快速输入口那么你要先把编码器位置映射到一个虚拟轴上然后再用MC_GearInPos把这个虚拟轴作为Master。这个操作不复杂但很多老工程师一上来直接拿编码器计数当主轴位置喂给功能块结果发现位置单位对不上齿轮比算出来的结果莫名其妙。我建议主轴统一用轴对象不管是物理伺服轴还是虚拟轴。3.2 轴组态与PLCopen单位设置轴组态这一步最容易埋雷。Codesys里每个轴都有一个单位设置主轴和从轴的位置单位、速度单位必须统一否则电子齿轮比的分子分母就是鸡同鸭讲。我的习惯是所有与材料长度有关的轴都用mm作为位置单位与角度相关的轴比如切刀、压花轮根据场景定。如果从轴是压花轮且我需要用角度来思考压印点那我可以把从轴单位设为°在轴组态时把电机转一圈映射为360°减速比10:1再算进去。但在这个项目里为了直观我统一把主轴和从轴都设为mm压花轮的周长换算成毫米行程。单位换算的具体操作在Codesys的轴接口里有一个Scaling因子对应电机每转的脉冲数与位置单位的关系。实际中就是填编码器分辨率、减速比、机械行程这几个数建议用轴组态助手生成不要手写公式太容易错位。单位一旦设置错误后面所有的同步位置、预同步距离全是错的而且调试时非常隐蔽因为速度能跑对但位置关系就是不对。3.3 完整ST代码下面是这个项目核心控制程序用Codesys标准ST语言编写直接从我的工程里整理出来的只做了脱敏和简化。PROGRAM PRG_GearInPosDemo VAR // 轴引用 stMaster : AXIS_REF : PLC_PRG.stAxis_Master; // 主轴牵引辊伺服 stSlave : AXIS_REF : PLC_PRG.stAxis_Slave; // 从轴压印轮伺服 // 功能块实例 fbMoveMaster : MC_MoveVelocity; // 主轴连续运动 fbStopMaster : MC_Stop; // 主轴停止 fbGearInPos : MC_GearInPos; // 位置触发齿轮耦合 fbGearOut : MC_GearOut; // 解除齿轮耦合 fbResetAxis : MC_Reset; // 轴错误复位 // 手动指令来自HMI bBtnStartMaster : BOOL; // 启动主轴 bBtnStopMaster : BOOL; // 停止主轴 bBtnEngageGear : BOOL; // 建立同步 bBtnReleaseGear : BOOL; // 解除同步 bBtnResetAll : BOOL; // 错误复位 // 电子齿轮参数 rRatioNumerator : LREAL : 2; // 齿轮比分子 rRatioDenominator : LREAL : 1; // 齿轮比分母 fMasterSyncPos : LREAL : 200.0; // 主轴同步位置 (mm) fSlaveSyncPos : LREAL : 0.0; // 从轴同步位置 (mm) fMasterStartDist : LREAL : 250.0; // 主轴预同步距离 (mm) fSlaveStartDist : LREAL : 250.0; // 从轴预同步距离 (mm) fGearAcc : LREAL : 800.0; // 同步加速度 (mm/s^2) fGearDec : LREAL : 800.0; // 同步减速度 (mm/s^2) fGearJerk : LREAL : 10000.0; // 加加速度 (mm/s^3) fMasterVelocity : LREAL : 300.0; // 主轴线速度 (mm/s) // 状态反馈 bMasterRunning : BOOL; bGearActive : BOOL; bGearDone : BOOL; bGearError : BOOL; wGearErrorID : WORD; bGearOutDone : BOOL; // 内部状态机变量 eState : INT : 0; bStartMasterCmd : BOOL; bGearInPosCmd : BOOL; bGearOutCmd : BOOL; bStopMasterCmd : BOOL; END_VAR// // 功能块调用段每个扫描周期都必须被调用才能保证状态持续更新 // // 主轴速度控制 fbMoveMaster( Axis : stMaster, Execute : bStartMasterCmd, Velocity : fMasterVelocity, Acceleration : 500.0, Deceleration : 500.0, Jerk : 5000.0, Direction : MC_Direction_Positive, Busy bMasterRunning ); // 主轴急停控制 fbStopMaster( Axis : stMaster, Execute : bStopMasterCmd, Deceleration : 500.0, Jerk : 5000.0 ); // 位置触发电子齿轮耦合 fbGearInPos( Execute : bGearInPosCmd, Master : stMaster, Slave : stSlave, RatioNumerator : rRatioNumerator, RatioDenominator : rRatioDenominator, MasterSyncPosition : fMasterSyncPos, SlaveSyncPosition : fSlaveSyncPos, MasterStartDistance : fMasterStartDist, SlaveStartDistance : fSlaveStartDist, Acceleration : fGearAcc, Deceleration : fGearDec, Jerk : fGearJerk, BufferMode : MC_BufferMode_Aborting, Active bGearActive, Done bGearDone, Error bGearError, ErrorID wGearErrorID ); // 解除电子齿轮耦合 fbGearOut( Execute : bGearOutCmd, Master : stMaster, Slave : stSlave, Acceleration : fGearAcc, Deceleration : fGearDec, Jerk : fGearJerk, BufferMode : MC_BufferMode_Aborting, Done bGearOutDone ); // // 状态机控制段管理启动、耦合、保持、解除、停止、复位 // CASE eState OF 0: // 待机状态 bStartMasterCmd : FALSE; bGearInPosCmd : FALSE; bGearOutCmd : FALSE; bStopMasterCmd : FALSE; IF bBtnStartMaster THEN eState : 10; END_IF 10: // 启动主轴 bStartMasterCmd : TRUE; IF bMasterRunning THEN bStartMasterCmd : FALSE; eState : 20; END_IF IF bBtnStopMaster THEN eState : 90; END_IF 20: // 等待同步触发指令 bStartMasterCmd : FALSE; IF bBtnEngageGear THEN eState : 30; END_IF IF bBtnStopMaster THEN eState : 90; END_IF 30: // 触发齿轮耦合 bGearInPosCmd : TRUE; IF bGearActive OR bGearDone THEN bGearInPosCmd : FALSE; eState : 40; END_IF IF bGearError THEN eState : 99; END_IF IF bBtnStopMaster THEN eState : 90; END_IF 40: // 齿轮耦合保持 bGearInPosCmd : FALSE; IF bBtnReleaseGear THEN eState : 50; END_IF IF bBtnStopMaster THEN eState : 90; END_IF 50: // 解除齿轮耦合 bGearOutCmd : TRUE; IF bGearOutDone THEN bGearOutCmd : FALSE; eState : 0; END_IF IF bBtnStopMaster THEN eState : 90; END_IF 90: // 停止主轴 bStartMasterCmd : FALSE; bGearInPosCmd : FALSE; bGearOutCmd : FALSE; bStopMasterCmd : TRUE; // 根据实际项目可增加停止完成判断简化处理直接返回待机 eState : 0; 99: // 错误处理 bGearInPosCmd : FALSE; IF bBtnResetAll THEN fbResetAxis(Axis : stSlave, Execute : TRUE); fbResetAxis(Axis : stMaster, Execute : TRUE); eState : 0; END_IF END_CASE3.4 程序逐段讲解为什么这么写先看功能块调用段。这里有个容易被新手忽略的细节fbGearInPos和fbGearOut必须每个周期都调用不能只在状态机的某个分支里调用一次。因为这些功能块内部有状态机需要持续扫描输入和更新输出。你把调用放在CASE分支里一旦状态切换导致功能块不再被调用它的输出就冻结了Active、Done永远不变程序直接卡死。我采用的做法是“功能块常调用 通过Execute信号的上升沿触发动作”。这样每个周期轴状态都能刷新状态机只负责切换Execute信号逻辑干净不打架。主轴启动我用了MC_MoveVelocity。为什么不用MC_MoveAbsolute或MC_MoveRelative因为主轴在这个场景里要连续走速度模式下最合适。MC_MoveVelocity只需要给速度、加减速和方向主轴就一直跑直到Execute变False或触发停止。注意如果你用MC_MoveVelocity还要切换主轴速度必须在每个速度变化时重新触发一次Execute否则速度不会更新这个我调试时踩过坑。耦合触发后fbGearInPos会根据MasterStartDistance和SlaveStartDistance提前调整从轴速度。我把预同步距离设为250mm而不是初版的50mm原因前面已经算过从轴要从0加速到600mm/s加速度800mm/s²理论最小需要225mm。250mm留了约10%余量兼顾响应速度和稳定性。如果你在现场发现从轴在预同步阶段还是追得很吃力就继续加大预同步距离或者提高加速度二选一。解除耦合用的是MC_GearOut。这个功能块执行时从轴会按照设定的减速度从当前同步速度降到0但注意它并不是“停死”而是解除主从关系之后从轴处于自由状态。如果解除后你需要从轴立刻回到某个定位位置我建议先执行MC_Halt让从轴停稳再下发定位指令否则速度突然割裂从轴容易过冲。3.5 手动与自动模式切换逻辑实际设备不可能只有自动流程手动调试模式必须有。我的建议是手动模式不要走这个状态机单独开一个手动Jog页面直接从轴和主轴各自点动。这样调试机械、找零位、验证齿轮比实测值都方便。自动模式切入之前程序要检查几个条件主轴和从轴都处于StandStill状态没报警、没运行中从轴已回原点位置有效同步位置参数已经在HMI上设定好气压、张力、限位等外部条件就位这些条件写成互锁逻辑任何一个不满足状态机就停留在待机状态。互锁没有做好后期调试会很痛苦特别是设备一多操作工误碰启动按钮轴就冲出去了。4. 调试实录常见问题与排查方法4.1 耦合瞬间从轴位置跳变设备震动这是我第一次现场调试遇到的头号问题。现象是只要bBtnEngageGear一给从轴“咔”一下压过去机械结构震得人心慌。查了半天问题出在FSlaveSyncPos的设置上。当时我从轴停在0位主轴已经跑了很远了我把MasterSyncPos设为200、SlaveSyncPos设为0想当然地以为“主轴到200从轴自然应该回到0”但功能块的逻辑是耦合瞬间从轴位置必须先被强行矫正到SlaveSyncPos设定的位置即使预同步距离内速度已经匹配上位置误差仍然会被一次补偿掉——结果就是跳变。解决办法把SlaveSyncPos设成从轴耦合前的实际位置并保证在同步点处它本来就应该在那里。更严谨一点的做法是把MasterSyncPos设为主轴当前实际位置加一点偏移让耦合时刻正好避开设备共振点。我当时是先在HMI上把 FSlaveSyncPos 改成从轴当前位置问题立刻消失设备安静得像什么事都没发生。4.2 同步保持阶段相位缓慢漂移第二个常见问题是耦合建立后运行几十秒从轴和主轴的相位差越来越大压印位置肉眼可见地偏了。这种情况我首先怀疑的不是程序而是电子齿轮比的理论值。前面说过理论齿轮比根据辊径算出来是0.9756但这个值完全依赖机械精度。辊筒加工误差、包胶磨损、减速机回程差都会让实际比值偏离理论值。排查方法很简单停机手动让主轴匀速走2000mm同时记录从轴编码器反馈行程算一下实际比值把 RatioNumerator/RatioDenominator 改成实测值。还有一种可能就是主轴速度波动太大伺服跟随性能不够。排查时用示波器比如Codesys的Trace功能或者第三方工具同时抓主轴实际速度和从轴实际速度看两条曲线的差值趋势。如果主轴自身速度纹波就大优先优化主轴伺服增益而不是调齿轮比。4.3 从轴回零与齿轮耦合的配合第三个让我印象很深的问题是上电后第一次同步可以第二次就错位。原因是断电重启后相对编码器的位置丢失从轴原点归零没执行但设备机械上已经偏了从轴带着错误位置进入耦合相位自然不对。解决办法有两个方向第一换成绝对值编码器伺服并配置好电池备份上电后MC_ReadActualPosition直接有效不需要回零第二如果只能用增量式就必须在上电流程里强制执行MC_Home回到限位或原点开关后再允许启动。我在这个项目里因为成本原因用了增量式电机所以我把“从轴已回零”写进了自动启动的互锁条件并且每次断电重启后HMI会自动弹窗提示操作工回零。4.4 常见问题速查表问题现象可能原因排查步骤解决办法耦合瞬间设备震动同步位置设置与实际位置偏差大监控耦合前从轴实际位置与SlaveSyncPos差值将SlaveSyncPos设为耦合前从轴实际位置同步过程中相位漂移理论齿轮比不准确低速空载实测主轴/从轴行程并反推比值用实测值修正RatioNumerator/RatioDenominator预同步阶段从轴追不上速度MasterStartDistance过小抓取同步点前速度曲线增大预同步距离或提高加速度解除耦合后从轴位置突变GearOut后直接执行定位观察GearOut完成时从轴是否还在低速运行先执行MC_Halt停稳后再定位断电重启后压印错位增量编码器位置丢失检查回零标志位上电强制回零或将回零状态加入互锁同步后主轴速度波动导致从轴抖动主轴伺服增益不足用Trace抓取主轴速度纹波优化主轴伺服整定消颤滤波5. 实操心得与应用扩展5.1 我踩过的几个坑第一个坑是在一台老设备上做电子齿轮改造时主轴是外部编码器我把编码器计数直接当主轴轴位置结果齿轮比完全对不上。后来改成编码器位置先映射到一个虚拟轴上虚拟轴单位设为mm再把虚拟轴作为Master源。这一步做完后面所有参数都对上了。第二个坑是预同步距离设太小。我一开始图响应快把MasterStartDistance设成50mm结果从轴每次都在同步点附近猛烈修正机构弹簧都在抖。后面我按 v²/(2a) 算了一遍才知道至少需要225mm调到250mm之后整个耦合过程平滑得像手动推上去的。第三个坑是解除耦合后从轴没有先停稳就去定位。设备跑起来之后从轴带着600mm/s的速度在转我直接给MC_MoveAbsolute结果从轴冲过目标位置又拉回来压花轮直接报废了一批材料。后来我强制解除耦合后先MC_Halt等Done了再定位问题才彻底解决。调试这类功能我的核心建议就一句话先把Trace曲线跟踪打开把主轴位置、从轴位置、从轴速度、MC_GearInPos的Active信号全抓下来看一遍。很多问题其实一眼就能从曲线上看出来根本不用猜。5.2 电子齿轮的更多应用场景电子齿轮同步的应用范围非常广我简单列几个自己接触过的飞剪/追剪旋转切刀跟随材料速度同步剪切不降低产线速度就能定长裁切MC_GearInPos负责剪切段的平滑切入印刷机版辊同步版辊周长和印刷图案长度有固定比例关系齿轮比保持相位套印准确度比机械齿轮高得多卷绕设备收卷、放卷的线速度同步根据卷径动态调整齿轮比防止材料拉伸或堆积龙门双轴两根平行轴上各带一个伺服齿轮比1:1同时用MC_GearInPos锁定相位避免龙门扭转数控同步轴在一些专用机床上主轴和分度轴之间需要精确的联动比例电子齿轮加上相位控制能替代传统挂轮机构每次启动这类项目我都会在开场就明确一个点如果只是“速度按比例走”用MC_Gear就够了如果要“位置相位也精确锁定”必须用MC_GearInPos。这个选择关乎整个系统的稳定性选错了后面会给自己挖无数坑。最后再分享一个小技巧现场调同步参数时别在负载已接上的状态下盲目试先用空载磨合把齿轮比、预同步距离、加减速度都调顺了再接负载。这样既能保护机构又能快速定位问题是机械的还是参数的。电子齿轮这门技术看着简单真正要做到“严丝合缝”还是得靠一遍遍看曲线、调参数没有捷径。