ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

NJ系列PLC+EtherCAT+ST语言实现24轴伺服控制实战解析

NJ系列PLC+EtherCAT+ST语言实现24轴伺服控制实战解析 上个月帮朋友处理一条电池生产线控制系统的改造打开Sysmac Studio的那一刻说实话有点感慨标签页里排了二十几个轴变量程序几乎见不到梯形图主体全是ST语言结构化文本通过EtherCAT总线挂着24台伺服。这种体量的多轴运动控制项目放在十年前典型的做法是一柜子脉冲输出模块加一个单独的运动控制卡光接线就能让人崩溃。现在一个欧姆龙NJ系列的机器自动化控制器加上一根网线串到伺服从站事情就全干完了。这篇文章就基于这个项目展开聊一聊NJ系列PLC配合ST语言和EtherCAT总线做24轴伺服控制时从选型、程序架构、总线配置到现场调试的完整思路尤其适合正在从传统梯形图转向ST语言、或者准备接手多轴总线项目的工程师参考。1. 为什么这条电池线选了NJEtherCATST“三件套”1.1 从CJ/NC方案到NJ方案变的不仅是硬件早些年欧姆龙阵营里做多轴运动控制主流方案是CJ系列PLC加NC运动控制模块比如CJ1W-NC系列。这个方案有个绕不开的问题PLC和NC模块本质上是两个系统在协同PLC负责逻辑NC模块负责轴运动二者通过内部数据交换区配合。程序要分成两套写排查问题也要两套思路一旦轴数超过8个数据交换、启动时序、报警联动的复杂度会指数上升。NJ系列改变了这个架构。它的运动控制和逻辑控制是在同一个CPU内完成的也就是说运动功能块在执行时和普通的布尔逻辑共享同一个任务周期二者是确定性的协同关系不是靠通信“商量”出来的配合。这一点在多轴联动场景下非常重要轴的状态、当前位置、指令位置可以直接放在变量里参与逻辑判断不需要考虑数据不同步的问题。再说轴能力。NJ系列不同的CPU型号支持轴数不同中大型型号轻松覆盖24轴级别。我在做这个项目时用的是NJ501系列轴数富余还留了几个虚轴专门用来做电子凸轮的工艺模拟。如果你拿NX1系列的小型机硬顶24轴CPU负荷和轴周期都会比较紧张所以选型第一步就是确认CPU的轴容量这件事要放在最前面。1.2 EtherCAT解决24轴布线与同步的两个痛点24台伺服用脉冲方式控制是什么概念每一台伺服至少要两条脉冲线脉冲方向加一条使能线再算上编码器反馈线盘柜里的线缆数量会非常恐怖。接线、查线、屏蔽、接地每一个环节都是故障源。而且脉冲方式的同步精度完全依赖PLC的硬件脉冲输出和中断处理轴数一多每个轴的实际刷新时序会出现微小的偏移在电池生产线这种对节拍和位置一致性要求极高的场景里是埋雷。EtherCAT用一根网线把所有伺服从站串成菊花链或者树形拓扑每个从站支持级联24台伺服的通信数据就在这同一根线上跑。它采用的机制是“飞读飞写”主站发出的以太网帧经过每一个从站时从站读取属于自己的数据同时把自己要反馈的数据写进帧里帧走完一整圈回到主站所有信息就都带回来了。这个机制的好处是从站不需要等待网络轮询延迟低且确定。同步方面EtherCAT的分布式时钟DC可以让所有从站的主控事件基于同一个时钟基准触发从站之间的同步抖动通常在亚微秒级。对于24个轴来说这意味着轴A动了轴B能在几乎相同的时间点读到这个事件并做出响应这是电池产线卷绕张力控制和多工位同步最需要的底层能力。1.3 ST语言在这类项目里的位置很多从梯形图起步的工程师一看到ST语言就头皮发麻我当年也一样。但说句实话在24轴这个体量上多用梯形图编写运动逻辑会把自己逼到墙角。梯形图擅长的是顺控逻辑一眼能看出一排触点和线圈的关系但你要在梯形图里写一个FOR循环遍历所有轴的报警状态、写一个数组做凸轮数据计算、写一段多条件分支状态机会非常痛苦。ST语言本质上和Pascal这类结构化编程语言很像有IF、CASE、FOR、WHILE等语句有数组、结构体、枚举等数据类型。它把“程序逻辑”和“电气回路”解耦了适合处理复杂运算、批量操作和状态流转。在这个项目里我大概是这么划分的按钮、急停、安全门等实打实的硬件连锁该用梯形图还是梯形图甚至直接在NJ里用梯形图块但一旦涉及到轴运动、过程状态、工艺参数计算全部用ST。这不是为了炫技而是为了让程序在24轴联动时不至于乱成一锅粥。2. 打开工程先看架构NJ程序不是“写”出来的是“排”出来的2.1 任务划分决定控制周期与扫描顺序NJ和普通PLC的一个大区别是它引入了“任务”Task的概念。任务有优先级有固定的执行周期程序是按任务为单位来调度的。处理这个项目时我首先考虑的不是写哪段功能而是怎么划分任务。运动控制有关的功能块我放在主周期任务里周期设成1毫秒。这个周期决定了伺服指令的刷新频率24轴系统的同步感完全依赖这个周期稳定不乱跳。逻辑控制、人机交互、配方处理这些实时性要求不高的内容放在低优先级的周期任务里周期可以放宽到10毫秒甚至50毫秒。报警、故障急停这类需要立刻响应的内容放进事件任务事件发生时才执行。这样做的好处是急停、安全逻辑不会被耗时长的通信处理拖慢运动控制代码的执行节奏是“心跳”式的不会因为上位机数据变化而抖动。很多NJ项目跑起来轴忽快忽慢、偶尔顿一下多半就是任务周期规划不合理把通信处理和高实时性运动控制放在同一个任务里互相抢时间。2.2 轴变量和功能块实例的规范ST语言给编程自由度很大但自由度在工程上是双刃剑。24个轴如果每个轴的Name都起得五花八门半年后你自己回来看程序都想骂人。这个项目的轴命名我用了统一的规则工艺位号物理动作轴号比如“Winding_Unwind_01”卷绕放卷1号、“TabWelding_XAxis_01”极耳焊接X轴1号。轴变量类型用的是NJ的AXIS_REF这是轴的核心数据结构包含使能、报警、当前位置、目标位置等所有信息。再一个是运动功能块实例的管理。NJ的运动控制遵循IEC 61131-3的PLCopen标准定位、点动、回原点、齿轮同步等都有现成的功能块比如MC_Power、MC_MoveAbsolute、MC_GearIn、MC_CamIn。每个功能块如果都单独建立实例24轴每个轴至少十几个运动实例程序会变得异常臃肿。实际的做法是每个轴只维护一个“轴控制状态”把该轴不同阶段需要的运动指令统一封装成自定义功能块内部根据状态切换调用相应的MC功能块。2.3 用CASE状态机把24个轴串起来多轴产线的程序如果写成一串从上到下的顺序执行基本可以断定后面会维护崩。我的习惯是每个工艺工位或者每一类轴组一个状态机用CASE语句实现。一个典型的状态机过程大概是待机、回原点、启动准备、加速运行、稳定运行、减速停止、完成等待、异常处理。CASE stAxisState OF AXIS_STATE_IDLE: // 等待启动信号 IF bStartSignal THEN stAxisState : AXIS_STATE_HOMING; END_IF; AXIS_STATE_HOMING: fbHome.Execute : TRUE; fbHome.Axis : AxisRef; IF fbHome.Done THEN fbHome.Execute : FALSE; stAxisState : AXIS_STATE_RUNNING; END_IF; AXIS_STATE_RUNNING: fbMoveAbs.Execute : TRUE; fbMoveAbs.Axis : AxisRef; fbMoveAbs.Position : rTargetPosition; fbMoveAbs.Velocity : rTargetVelocity; IF fbMoveAbs.InVelocity THEN // 速度到达可以做工艺联动判断 bInPosition : TRUE; END_IF; AXIS_STATE_ERROR: // 报警停车记录故障码 fbMoveStop.Execute : TRUE; IF fbMoveStop.Done THEN stAxisState : AXIS_STATE_IDLE; END_IF; END_CASE;用CASE的好处是状态跳转明确别人看程序时能顺着状态编号快速理解轴在干什么。每个轴的当前状态还可以映射到HMI上帮助现场操作工判断设备卡在哪个环节这对24轴产线的故障定位帮助极大。3. 24轴EtherCAT总线设计先算账再配轴3.1 通信周期怎么估算EtherCAT的通信周期不是拍脑袋定的。主站CPU的算力、从站数量、每个从站交换的数据量、以及伺服驱动的控制周期共同决定了最终能跑多快的刷新周期。这个项目24台伺服每台伺服需要进行PDO数据交换输入方向主站到从站至少要控制字、目标位置、目标速度、目标扭矩输出方向从站到主站至少状态字、实际位置、实际速度、实际扭矩折算下来每台伺服一个周期大约占十来个字节的报文空间24台伺服加起来所有数据都能塞进带宽余量里。真正花时间的是轴周期和伺服驱动周期的匹配。我先把任务周期设到1毫秒下载配置后用NJ的诊断和监控功能观察刷新时间确认CPU负荷不高之后再把任务周期往0.5毫秒试。如果周期太小导致CPU负荷过高NJ会报任务过载这时候要么降低周期要么把部分从站的数据量精简。记住一个原则周期不是越小越好比更新周期更重要的是周期稳定。一个稳定不抖动的1毫秒周期实际效果往往好过一个偶尔超时的0.5毫秒。3.2 从站拓扑与分布式时钟24台伺服的拓扑我选了菊花链为主、局部星形为辅的方式。每条链上的从站数量不要贪多尽量控制在十台以内否则末端信号质量会下降排查也麻烦。现场布线时要注意伺服设备很多有散热的排风网线走线要避开动力电缆和散热风口EtherCAT的线上传输的是标准以太网帧信号对干扰并不是免疫的屏蔽层双端接地、网线用高柔拖链线这些基本功不能省。分布式时钟DC要确认每个从站都处于DC同步模式。早期项目里遇到过某品牌伺服默认不是DC模式的情况导致产线运行时不同轴之间的响应快慢不一致位置偏差总是周期性变化。用Sysmac Studio的诊断界面能查看每个从站的同步状态建议配完第一台设备就逐站检查别等整线跑起来再返工。3.3 轴配置里那些被忽略的参数轴参数配置是NJ项目里最繁琐也最容易踩坑的环节。有几个参数值得多说一句。单位换算。伺服驱动器的位置指令本质上是编码器计数NJ轴变量里的位置单位是可以自定义的。电池产线的工艺人员在HMI上说的是毫米、度、米每分钟所以我把每个轴的指令单位设成毫米或度把电机每转的脉冲数或者编码器分辨率和丝杆导程/减速比填进去NJ自动完成换算。这里强烈建议把伺服驱动器的电子齿轮比设成1:1全部换算交给PLC做否则两边都做了换算后期匹配位置时极容易出鬼。软件限位和硬件限位。24个轴不能指望每个轴都装硬限位但软件限位必须每个轴都设置。我习惯在轴配置里填入正负软件限位然后在ST程序里再加一层范围内判断双保险。软件限位失灵或者被修改还有程序兜底。回原点方向的设定。电池产线上有的轴需要反向回原点有的轴的Z相位置和工艺基准相差半圈这些都要在轴配置阶段确定。等到现场联调再发现回原点方向反了、限位挡块撞坏了那种痛苦我相信有工程师体会过。4. ST语言控制伺服从定位到同步的工程写法4.1 点动、定位与上升沿触发先说不带任何花哨功能的基础指令写法。MC_MoveAbsolute和MC_MoveRelative这类功能块有一个共性要求Execute参数是沿触发不是电平触发。也就是说只有Execute从FALSE变成TRUE的那一刻指令才会被正式执行。如果你把Execute绑定到一个持续为TRUE的布尔量上指令只会在第一次变成TRUE时执行一次后面目标位置改了它也不会理你。这个“沿”的逻辑在ST里最稳妥的写法是显式使用R_TRIG上升沿检测功能块。实际项目里我会给每个轴封装一个“动作触发器”任何时候想要这个轴走一下就把触发变量置TRUE程序里用R_TRIG捕捉上升沿然后拉起对应的运动功能块。R_TRIG_Start(CLK : bJogForward); IF R_TRIG_Start.Q THEN fbJogAxis.Direction : AXIS_DIRECTION_POSITIVE; fbJogAxis.Execute : TRUE; END_IF;这套写的优点是动作清晰、触发可靠尤其在多个条件同时想要动一个轴时不会因为某个信号保持状态而误触发。4.2 电子齿轮、电子凸轮与张力控制24轴电池产线真正有难度的是同步控制而不是单轴定位。极片卷绕的收放卷、极耳焊接的飞行同步、送片工位之间的速度匹配这些工艺单元都要求一个轴跟随另一个轴运动。机械上齿轮和凸轮是固定的耦合电气上用MC_GearIn实现电子齿轮用MC_CamIn实现电子凸轮。电子齿轮最简单的场景是主轴速度是多少从轴按一个比例跟随。ST里用起来很直接但要注意从轴当前的使能状态和切换时机。齿轮切入时如果从轴和主轴的速度差过大会出现冲击我一般在齿轮啮合前先加一段软启动把从轴速度率限制一下让它在几个周期内慢慢追到同步速。电子凸轮在NJ里需要配置凸轮表。电池产线常见的卷绕转塔、飞剪机构主轴是连续旋转的从轴需要走走停停的间歇运动这就靠凸轮曲线实现。凸轮表的核心是建立主轴位置和从轴位置的一一映射主轴旋转一圈从轴完成一个完整的工艺循环。ST里不直接写凸轮表本身的数值而是在MC_CamIn的实例参数中指定凸轮表编号和啮合点但程序里要处理主轴位置与凸轮起点之间的相位关系。相位对了曲线才能正确执行。张力控制是电池产线绕不开的点。大部分张力控制轴用的是扭矩模式PLC给定一个扭矩值伺服输出对应的输出扭矩卷径变大时PLC需要根据卷径重新计算张力对应的扭矩补偿。这个计算逻辑用ST写比较顺实时采集卷径通过线速度和角速度换算再用张力设定值乘以卷径算出扭矩指令再配合速度限幅防止断带或者张力突变。4.3 回原点与报警处理24轴回原点如果每个轴做完原点动作再等信号整个启动流程会非常慢。我通常会把所有轴的原点请求信号一次性发出然后在程序里轮询每个轴的回原点Done状态用一个聚合变量“所有轴已回原点”作为启动允许条件。报警处理上NJ轴对象本身自带报警状态程序里可以读取AxisRef.Status或对应的错误位。但直接把原始报警扔给操作工显示是不够的我已经见过太多“轴1报警”这种让人无从下手的提示。比较好的做法是把每个轴的具体报警码读出来配合工艺名称组合成一条可读信息比如“卷绕放卷1号轴编码器电池电压低”同时给出处理建议例如“请更换电池后重新上电”。这个思路不复杂但很体现工程经验。5. 伺服调试增益、滤波、前馈的关系与调法5.1 先看波形再动参数很多人在现场一上来就调增益这是不专业的。没有波形的增益调试就是瞎试调出来的参数也许能跑但性能到底什么水平自己心里没底。这一步的正确顺序是先用伺服调试软件或NJ的轴监控功能记录轴在阶跃指令下的位置偏差、速度波形看看有没有超调、有没有震荡、响应时间多长然后再决定动哪个参数。欧姆龙自家的1S系列伺服和NJ配合可以直接用Sysmac Studio里的伺服调试界面看趋势图。第三方伺服从站只要EtherCAT通信建立好也能在控制器侧监控到实际位置和跟随偏差只是有些内部参数要通过伺服厂家的调试工具来看。我在这个项目中混用了两种通信层面的位置偏差看NJ的趋势图速度环电流环的性能用各伺服厂家的调试软件看。两边对照着判断问题出在位置环还是速度环。5.2 手动调增益的顺序与手感伺服三环的调试顺序是固定的从内向外先电流环一般不碰再速度环最后位置环。驱动器的自动调谐在很多场景下能给出一个可用的底子但产线上一旦有负载变化、机械振动、刚性不足自动调谐的参数就不够看了还是要手动修正。第一步是设置惯量比。惯量比是驱动器的实际负载惯量和电机转子惯量的比值其实是整个手动调试的地基。惯量比不对其他增益怎么调都别扭。现场判断惯量比准不准可以看电机在加减速时速度环输出的波动如果速度响应“发闷”或者有异常的低频波动多半是惯量比虚高或虚低。第二步是加速度环比例增益。速度环比例增益决定速度响应的快慢。从小往大加同时盯着速度波形发现速度在指令变化后能快速跟上且无明显振荡就先停在这个值。第三步再调速度环积分时间慢慢减小积分时间消除稳态误差但积分时间太小容易引起低频振荡。最后才是位置环增益。位置环增益决定了轴对位置的软硬程度增益越高轴越“硬”但增益太高会让跟随过程中的位置出现超调或者来回振。现场有种手感位置环增益调到位时手动推一下负载电机会有一个干脆的抵抗感而不是软绵绵地任你移动或者剧烈地弹回来。5.3 前馈、滤波与编码器线数那些事位置偏差和速度偏差主要靠前馈来消。速度前馈的作用是在指令运动方向提前给出一个速度分量让位置环不需要靠误差去“追”目标跟随误差能压到很小的水平。电池产线很多是匀速走带的应用速度前馈的优势尤其明显。转矩前馈则是针对有规律外部负载变化的场景比如卷绕张力变化提前给出一个力矩补偿让速度环的负担减小。如果机械传动结构里有共振频率单纯加增益是没有用的这时候要用陷波滤波器把共振频率对应的幅值压下去。问题是共振频率的识别我一般用伺服调试软件的振动测量功能或者手动给一个小幅正弦指令看速度反馈里哪个频率分量被放大了那就是共振点。滤波器的参数不用做太深找到频率点设一个合适的衰减宽度就够用。再回答在现场经常被问的问题伺服驱动器的编码器分辨率怎么看、能不能改。比如有些伺服软件里能看到类似“262144”这个数字这个数等于2的18次方意思是编码器单圈分辨率是18位也就是说电机转一圈编码器反馈262144个脉冲。这个数值是编码器硬件固化的不建议也不应该去改它。如果你觉得位置指令精度和设备移动量对不上正确做法是在PLC轴配置里做单位换算和电子齿轮设置而不是去动驱动器的编码器分辨率否则位置反馈数值和实际机械位置会错乱后果比参数没调好严重得多。5.4 给每台伺服建一张调试档案24台伺服每一台的机械结构、负载特性都可能有差异调完不能拍拍手就完事。我给这个项目的每台伺服都建了一张电子表格记录轴号、驱动器型号、电机型号、负载类型、惯量比、速度环增益、积分时间、位置环增益、前馈系数、陷波频率、调试日期、调试人。下次设备保养或者换驱动照着表格就能快速恢复状态不用重新从零开始试。这张表也是交接给用户的最有价值的文档之一。6. 现场踩坑记录三条最典型的故障排查链路6.1 伺服使能后偷偷溜轴这条产线调试时遇到一个现象某台负责垂直方向顶升的伺服明明没有下发任何运动指令使能后偶尔会往下滑一小段然后又停住。排查第一反应是机械制动器没有抱住。看了看梯形图逻辑抱闸控制信号确实在电机使能前就释放了释放时机有问题应该等伺服自己建立好保持转矩后再松闸。另一个可能原因是刹车的控制顺序只和伺服使能信号关联没有和轴的“实际位置无变化”关联。正常逻辑是伺服得电并输出保持力矩之后再打开抱闸停止时先让轴进入“力矩保持”状态再延时关闭抱闸。很多“溜轴”问题都出在这里而且往往是偶发的因为就差了那几十毫秒。6.2 偶发断站和同步丢失还有一个很头疼的问题某个从站偶发掉线表现为伺服突然报警EtherCAT网络红色告警重启后又恢复正常。一开始怀疑是网线或者接口接触不良把所有网线重做了一遍情况还是会在不定时出现。排查到最后发现是某个24V直流电源容量不够该从站伺服在电机快速制动瞬间拉低了母线电压导致伺服控制系统供电电压跌到阈值以下从站掉线主站检测到拓扑变化后整个网络进入错误状态。把该区域的供电单独拉了一路同时把制动电阻的容量加大问题彻底消失。这条经验提醒我们EtherCAT网络排错不要只看网络部分电源质量往往是局外真凶。6.3 ST代码运行一段时间后状态跑飞最后一个问题是程序层面。某个叠片工位的状态机运行几百个循环后会偶发进入一个未定义状态必须人工复位。乍一看以为是随机性问题后来用Sysmac Studio的在线监控蹲在某一个轴的状态变量上观察了很久发现问题出在状态机的CASE语句里某个分支的条件在极端时序下同时满足了两个不同状态的转移条件导致最后一次赋值决定了状态而这个值恰好指向了未定义的编号。这个问题的根治办法有两个一是在CASE的ELSE分支里把所有未定义状态强制拉回安全待机状态并触发一条诊断报警保证即使状态跑飞也不会“悬空”二是给状态变量定义成枚举类型并且枚举值严格和状态机分支一一对应从数据类型层面杜绝无效状态。从那以后我再也没有因为状态机跑飞在半夜被电话叫醒过。这些年做下来我的体会是大型多轴项目的真正难点不在某个功能的实现技巧而在于把24个轴和复杂的工艺需求梳理成一个清晰的程序骨架。骨架对了轴再多也只是纵向扩展。如果你正要接手类似的项目开工之前先别急着写代码花几天时间把每个轴的工艺动作、互相之间的时序关系画成图理清楚了再动手。这一步省下来的调试时间远超你的想象。
返回列表