简介:面向工业自动化与PLC编程开发者,资源围绕汇川H5U PLC与MCGS触摸屏实现三轴示教系统,覆盖示教点录入异步处理、三轴直线插补参数配置、圆弧插补逻辑及离线仿真调试,可直接作为三轴运动控制模板移植到同类应用场景。包内共3个文件,以HTML界面文件为主,配合inscode工程入口与gitignore配置,ZIP压缩包整体仅7KB,结构轻量,便于快速查看、运行、二次开发及离线仿真验证。目前已有57人学习,适合需要落地三轴控制项目的工程师参考。源码附带详细注释,既说明触摸屏界面设计与PLC运动控制指令的对应关系,也给出仿真模式下的数据处理方式、运动模式扩展方法以及通讯故障的解决思路,便于读者按需裁剪功能,或将其改造成其他轴控项目的基础模板。
1. 项目拆解:三轴示教系统到底在解决什么问题
做设备开发这么多年,我接到的需求里,“示教”二字出现的频率一直不低。它本质上解决的是一个很现实的问题:工艺路线复杂多变,每条路径的坐标点位、运行速度、停留时间都不一样,如果每次更换产品都要重新写一遍PLC程序,那调试周期会拖到让人崩溃。
三轴示教系统的核心思路,就是把人从代码里解放出来。操作员只需要通过触摸屏或手控器,手动把设备移动到目标位置,记录下这个点的坐标,再录完一整条轨迹的若干个点,系统就能自动把这些点串起来,生成可执行的运行程序。下次要复现同样的动作,直接调用编号就能跑。说白了,就是把“改代码”变成了“录点位”,把工程师从现场反复修改程序的泥潭里拉出来。
这套系统的核心构成并不复杂:上位交互层(触摸屏)、控制层(PLC)、执行层(三台伺服+丝杠/皮带结构)。汇川的H5U系列PLC在中小型设备里做示教系统很合适,单机支持轴数足够多,EtherCAT总线速度也快,最关键的是它把电子凸轮、插补、比较中断这些都做进了系统底层,不用自己拼凑一堆复杂逻辑。我这个项目用的是汇川H5U-1614MTD + SV660N伺服 + IT7000触摸屏,下面把完整的设计思路和源码核心逻辑拆开讲清楚。
2. 硬件选型与系统架构设计
2.1 为什么选H5U而不是小型PLC
很多朋友喜欢用汇川EASY系列或者H1U这类小型机做运动控制,如果只是单轴定位、简单启停,小机型确实够用,价格还便宜。但三轴示教系统有一个明确的分水岭:总线周期和轴组联动能力。示教系统要求三轴同时采集位置、同步执行插补动作,小型PLC走脉冲输出的话,脉冲频率上限、加减速曲线、多轴同步精度都会被物理接口限制住。
H5U在架构上有几个实打实的优势。第一,EtherCAT从站数量最多支持32个,三台伺服加远程IO绰绰有余;第二,内置MC_MoveAbsolute、MC_MoveDirectAbsolute、MC_MovePath等符合PLCopen规范的运动指令,开发时不用自己在底层写梯形图去做插补;第三,H5U支持后台任务,示教过程中可以一边处理HMI的写入指令,一边保持高速位置采集不卡顿,这个在低价位PLC里非常少见。
还有一个很实际的点,汇川的InoProShop软件把PLC编程和伺服调试打通了。伺服驱动器的参数可以直接在InoProShop里批量配置、监控、备份,示教系统里三台伺服参数是高度相似的,批量修改能省掉大量重复劳动。
2.2 伺服选型和机械传动配套
三轴示教系统的伺服选型,有一个核心矛盾:精度和速度往往互相牵制。X轴通常是长行程传动,负载重,选大惯量伺服配高刚性丝杠;Y轴行程中等,速度和精度要兼顾;Z轴一般要承受加工头或者点胶阀的重量,还要考虑断电自锁,所以必须配带抱闸的伺服电机。
我的选型方案是SV660N系列,X轴用1.5kW电机配2005研磨丝杠,Y轴用750W电机,Z轴用750W带抱闸电机。这个配置在负载20kg以内的三轴平台上是比较稳的。SV660N接在EtherCAT总线上,分辨率是23位绝对值编码器,理论上定位精度可以做到微米级,实际机械装配下来稳定在0.02mm以内没问题。
这里提醒一句:示教系统对机械回程间隙非常敏感。如果用的是普通滚珠丝杠,正反向切换时丝杠间隙会直接影响重复定位精度。有条件的话,配预压型螺母或者直接上研磨级丝杠,示教点位重复精度会好看很多。
2.3 控制架构和程序任务划分
整个系统的程序架构,我划分成了三个任务模块:
- 通讯任务:负责和IT7000触摸屏走Modbus TCP通信,接收手动示教指令、点位编号、速度设定值,回传当前位置、运行状态、报警信息。
- 示教任务:也叫“录点模式”。操作员通过HMI上的方向按钮把轴移到目标位置,按下“记录”按钮,PLC把当前三轴坐标写入点位数组对应的索引位置。
- 运行任务:自动模式下手动触发,程序从点位表里读取目标坐标,按设定速度执行插补运动,轨迹走完后自动停止或循环。
这三个任务之间通过全局变量和数据块进行数据交换,互不干扰,这也是H5U这种中大型PLC相比小型PLC编程时的一个明显优势——程序组织可以真正做到模块化,后面维护起来不用在一大片梯形图里大海捞针。
3. 核心代码逻辑:示教点数据的存储与处理
3.1 点位数据结构设计
示教系统的根基是点位数据。最开始我图省事,直接建了三个数组分别存X、Y、Z坐标,后来发现一个问题:如果每个轴的数据单独存,删除中间某个点位时,后面的点都要往前挪一次,不同轴的数组必须同步挪,代码又啰嗦又容易出错。
后面改成了结构化数组,用H5U的DUT(Data Unit Type)功能定义一个点位结构体:
TYPE POINT_DATA : STRUCT X : REAL; // X轴绝对坐标,单位mm Y : REAL; // Y轴绝对坐标,单位mm Z : REAL; // Z轴绝对坐标,单位mm Speed : REAL; // 该点运行速度,单位mm/s DwellTime : REAL; // 该点停留时间,单位s IsValid : BOOL; // 该点是否已示教(有效点位) END_STRUCT END_TYPE然后在全局变量区建点位表:
VAR_GLOBAL PointTable : ARRAY[1..100] OF POINT_DATA; // 点位表,最多支持100个点位 CurrentPointIndex : INT; // 当前正在示教或运行的点位索引 TotalPointCount : INT; // 已示教的有效点位总数 END_VAR用结构体存点位最大的好处是扩展性。后面有客户跟我说要加“该点是否需要输出气缸动作”的需求,我只需要在结构体里加一个BOOL变量,运行逻辑里判断一下,整套代码不用动筋骨。做设备的人应该都懂,这种“留了一手”的设计有多重要。
3.2 手动示教与点位记录
示教功能的核心逻辑,是把手动模式下伺服的实际位置实时采集进PLC,并写入点位表。H5U的EtherCAT从站状态可以通过系统变量读取,用MC_ReadActualPosition指令读每个轴的绝对位置。
这里有一个非常容易踩的坑:位置单位换算。伺服驱动器的电子齿轮比设置不同,PLC读到的轴位置可能是什么unit(用户单位)、pulse(脉冲)、mm(毫米)等不同单位的数值。我的项目里把驱动器和PLC统一设置成mm作为用户单位,读取出来的数直接用,省掉了每次运算都要做单位转换的麻烦。
示教记录的核心逻辑用结构化文本(ST)写,比梯形图清晰太多:
// 手动示教:将当前位置记录到指定点位索引 IF bTeachRecord THEN PointTable[CurrentPointIndex].X := MC_ReadActualPosition(AxisX); PointTable[CurrentPointIndex].Y := MC_ReadActualPosition(AxisY); PointTable[CurrentPointIndex].Z := MC_ReadActualPosition(AxisZ); PointTable[CurrentPointIndex].Speed := rTeachSpeed; // 从HMI读取设定速度 PointTable[CurrentPointIndex].DwellTime := rDwellTime; // 从HMI读取停留时间 PointTable[CurrentPointIndex].IsValid := TRUE; TotalPointCount := MAX(TotalPointCount, CurrentPointIndex); bTeachRecord := FALSE; // 记录完成,复位触发信号 END_IF这段逻辑不复杂,但有几个细节处理能让现场操作体验好很多。
第一,HMI上记录按钮用的是“上升到沿触发”,按一次只记一个点,防止操作员长按按钮导致同一个点重复记录。第二,点位索引可以在HMI上手动切换,方便补录中间点。第三,所有手动运动都是点动模式,我设置了慢速、中速、快速三档速度切换,定位粗调快速走,最后微调用慢速,效率高还不容易超调。
3.3 点位运行与轨迹插补
点位记录完成后,自动运行的逻辑有两种选择:PTP(点到点运动)和CP(连续轨迹插补)。
PTP模式用MC_MoveAbsolute指令,走的是每个轴独立定位,三轴同时启动但速度曲线互不干涉。这种模式适合点位之间不需要“走直线”的工艺,比如点胶、焊接、螺丝锁付——每个点单独定位,到达后执行动作,再移动到下一个点。
CP模式用的是MC_MoveDirectAbsolute或MC_MovePath,走的是笛卡尔空间插补,三轴严格同步,走出来的轨迹是三维空间里的直线或圆弧。这种模式适合需要“走轨迹”的工艺,比如涂胶轨迹、切割轨迹、轨迹跟踪。
我的代码里做了一版支持两种模式的切换:
// 自动运行:根据点位表顺序执行,支持PTP/CP切换 CASE runState OF 0: // 待机状态,等待触发 IF bStartAuto THEN CurrentPointIndex := 1; runState := 1; END_IF 1: // 启动运动 IF bRunMode_PTP THEN // PTP模式:三轴独立绝对定位 MC_MoveAbsolute(AxisX, PointTable[CurrentPointIndex].X, rRunSpeed); MC_MoveAbsolute(AxisY, PointTable[CurrentPointIndex].Y, rRunSpeed); MC_MoveAbsolute(AxisZ, PointTable[CurrentPointIndex].Z, rRunSpeed); ELSE // CP模式:三轴空间直线插补 MC_MoveDirectAbsolute(AxisGroup, PointTable[CurrentPointIndex].X, PointTable[CurrentPointIndex].Y, PointTable[CurrentPointIndex].Z, rRunSpeed); END_IF runState := 2; 2: // 等待到位 IF bAllAxisInPosition THEN // 到位后延时,执行点动作 runState := 3; END_IF 3: // 到位停留 IF PointTable[CurrentPointIndex].DwellTime > 0 THEN // 执行停留计时 DwellTimer(IN := TRUE, PT := PointTable[CurrentPointIndex].DwellTime); IF DwellTimer.Q THEN // 停留结束,切换下一个点 CurrentPointIndex := CurrentPointIndex + 1; DwellTimer(IN := FALSE); IF CurrentPointIndex > TotalPointCount THEN runState := 0; // 全部点位执行完 bStartAuto := FALSE; ELSE runState := 1; END_IF END_IF ELSE // 无停留时间,直接切换下一点 CurrentPointIndex := CurrentPointIndex + 1; IF CurrentPointIndex > TotalPointCount THEN runState := 0; bStartAuto := FALSE; ELSE runState := 1; END_IF END_IF END_CASE这个状态机的框架几乎是所有示教系统的通用骨架。如果你自己写示教程序,完全可以照这个逻辑根据你的PLC型号改一版。
3.4 速度规划与拐角处理
点位之间的速度规划,是区分“能用”和“好用”的关键。如果每个点之间都是急停急走,三轴平台机械冲击很大,运行时间也会拖长,而且动作看起来非常生硬。工业上处理这个问题的办法叫“前瞻速度规划”,通俗说就是让设备在到达下一个点位前就开始提前减速,通过判断轨迹夹角来决定拐角处允许的最大通过速度。
H5U的运动库在这方面已经内置了部分处理能力。MC_MoveDirectAbsolute指令自带S曲线加减速和拐角平滑策略,只需要在轴组配置里设定好加速度、减速度和急停时间(Jerk),实际的运动效果就会好很多。
我项目里的实际配置是:加速度500mm/s²,减速度500mm/s²,急停时间50ms。点与点之间的距离如果小于5mm,速度自动降低到设定值的60%去走。这个参数在20kg负载的三轴平台上是比较合适的,既保证效率又不会让机械振动太大。如果你的平台更轻、刚性更好,可以把加速度往上调,效率会明显提升。
4. 实操中的常见问题与排查技巧
4.1 伺服使能冲突和EtherCAT总线报警
我做这套系统时遇到频率最高的坑是伺服使能冲突。现象是:HMI上点了伺服使能,PLC侧也写入了使能信号,但伺服就是没反应,或者报使能冲突报警。
排查思路分两步。第一,检查PLC程序里是不是有两个地方在同时控制同一个伺服轴的使能信号。H5U软件里可以用“交叉引用”功能查这个信号被哪些地方写过,如果伺服使能同时被HMI关联的变量和运动指令的轴使能位控制,就会冲突。第二,检查EtherCAT配置里的从站映射,确认伺服驱动器的控制字(Controlword)和状态字(Statusword)地址没有重复映射到其他变量。
EtherCAT断站报警也遇到过。表现是设备运行一段时间后,某个伺服突然报同步丢失,停机后重新上电又能恢复。这种情况大概率是接线问题,EtherCAT网线要用带屏蔽层的专用电缆,接地要可靠,而且从站之间的网线长度不要超过20米。还有一个容易忽略的点:终端电阻。EtherCAT不是CAN总线,不需要加终端电阻,但如果你的网络里节点间距过远,信号衰减造成的偶发断站也会出现,排查的时候别漏了这个方向。
4.2 示教点位跑偏和重复定位精度差
这是示教系统用户最崩溃的问题:录好的点位,今天跑是对的,明天跑就偏了0.5mm;或者同一段轨迹,跑第一次和跑第三次位置不一样。
机械层面,重点检查三个位置:联轴器是否松动、丝杠螺母座是否松动、伺服电机编码器线是否接触良好。电气层面,最容易被忽略的是伺服驱动器参数里“惯量比”设置不对。SV660N的刚性参数默认值是自动,但如果你手动改过速度环增益,位置环的响应就会变硬,机械结构稍有间隙,就会表现出定位过冲或者回程误差。
我调试时的一个经验:先把示教系统里所有轴的伺服参数用InoProShop导出一份初始配置备份,调完机械后再逐项恢复伺服自动调谐,让伺服自己重新学一遍负载惯量。不要一开始就手动硬调伺服参数,容易越调越糟糕。
还有一个高级技巧:如果是绝对值编码器,示教点位存的是绝对坐标,理论上断电后重新上电位置不会丢。但如果用的是增量编码器,断电后必须回原点,否则点位表里记录的坐标全是相对参考点的偏差,跑出来全偏。在这个项目里我强烈建议用带绝对值编码器的伺服,客户现场的体验完全不一样。
4.3 HMI通信超时和点位擦写不同步
IT7000触摸屏和H5U走Modbus TCP通信,最常用的方式是Moudbus从站地址映射。H5U里可以把全局变量区的数据映射成Modbus寄存器地址,然后HMI通过读写寄存器来交互。
有一个坑是HMI上点位表数据的写入,是多个寄存器连续写,比如X坐标一个REAL要占2个寄存器,Y、Z再加4个,速度又占2个。如果HMI上点的“保存”按钮触发的是分多次写入,中途PLC侧如果正好在读取点位表,就可能读到一组不完整的数据,导致轨迹跳变。
我的解决方案是给点位表加了一个“写入有效标志”寄存器。HMI上做点位数据编辑时,先置“正在写入”标志,写入完成后清掉标志。PLC侧读取点位数据前先检查这个标志,如果为真就等待,直到写入完成再读取。这个思路叫“软件握手”,简单又可靠。
4.4 程序下载后示教点位丢失的问题
开发调试阶段最烦的一件事:程序一更新重新下载,刚才在HMI上辛辛苦苦示教的点位全没了。
原因是PLC程序的变量区在下载代码时会被重新初始化。如果要让点位数据在程序更新后还能保留,要么把点位数据存到PLC掉电保持区(H5U的保持型变量区),要么在程序下载后用备份功能从旧程序导出点位数据再导入到新程序里,要么在HMI侧做数据存储,让HMI在PLC启动后自动回写点位表。
我的做法是三管齐下:点位表变量定义在掉电保持区,平时执行自动备份到U盘,客户现场如果误操作清空了数据,可以从备份文件一键恢复。这套机制实际用下来救了很多次场。
5. 源码框架说明和二次开发建议
5.1 程序文件结构和功能块划分
整套源码在InoProShop里的工程结构是这样的:
- PLC_PRG(主程序):初始化调用、运行模式切换、故障复位逻辑。
- PRG_Teach(示教功能块):手动点动控制、点位记录逻辑、点位测试。
- PRG_AutoRun(自动运行功能块):点位顺序执行状态机、插补控制逻辑。
- PRG_Communication(通信功能块):Modbus寄存器映射、HMI数据交互。
- PRG_Alarm(报警管理功能块):轴报警实时采集、历史报警记录。
- DUT类型定义:点位数据结构、报警结构体。
这种划分方式的好处是,如果有人只需要改通信协议,就不用动运动控制的部分;如果有人要加第4个轴,主要在点位结构体、轴组配置和AutoRun功能块里三处改动就行,不需要全局翻代码。
5.2 二次开发的核心扩展方向
当前源码已经支持100个点位、PTP/CP双模式,实际项目里最常被要求扩展的三个方向是:
第一,圆弧插补。当前示教只支持空间直线插补,如果工艺里有圆弧轨迹,需要在点位表中增加圆弧半径、圆心坐标、方向等字段,然后在执行逻辑里接入MC_MoveCircularAbsolute指令。H5U支持空间圆弧插补,数据结构和处理逻辑都具备,扩展工作量不大。
第二,多轨迹管理。比如一个产品要打磨4个不同的面,每面一条轨迹,需要把点位表扩展成二维数组,增加一个“轨迹编号”维度,运行模式里增加轨迹选择逻辑。
第三,外设联动。示教系统通常不只是三轴动,还需要在特定点位触发气缸、真空阀、胶阀、相机拍照等。目前的DwellTime已经预留了这个空间,但我建议单独建一个“点位动作表”,用来配置每个点位的输出信号状态,这样示教操作员可以在HMI上自由编辑,不需要改PLC代码。
可以说,示教系统的核心是数据结构,不是运动指令。指令只是执行者,真正决定整套系统灵活性和扩展性的,是点位数据怎么存、怎么管理、怎么让操作员方便地编辑和调用。
6. 现场调试心得与最后提醒
这套系统交付到客户现场之后,我个人最深的体会是:示教系统的开发难度不在写代码,而在“现场工况的适配”。每个客户的工艺习惯不同,对操作界面的要求也不同,有的人习惯用摇杆,有的人坚持用HMI方向按钮,有的人希望示教速度能达到200mm/s快速走完然后精准微调,有的人只想要“越慢越好,别撞机就行”。
所以如果你要复刻或者移植这套源码,我最想说的三点是:
第一,点位数据的防呆设计一定要做足。比如记录点位时,要判断当前位置是否超出软限位,如果在软限位之外,直接拒绝记录并给HMI返回错误提示。不要等到运行的时候撞了机才发现点位越界。
第二,速度参数在HMI上一定要做成可调,不要写死在PLC里。现场调试的时候,操作员会根据实际工艺频繁调整运行速度,如果每次都要连电脑改程序,效率低到离谱。
第三,建议留一套手动“单步执行”功能。自动运行模式下,可以一行一步走下去,每一步停下来检查工艺效果是否符合预期。这个功能调试大有益处,试想一下,一整套轨迹跑完才发现第三点位置偏了,又要改又要重新跑,时间成本太高了。
示教系统在自动化设备里只是基础功能模块,但正是因为基础,才值得把数据结构和操作流程打磨到位。一套好的示教框架,能在未来接项目的时候直接复用,省掉大量重复开发时间,这比省那点设备硬件成本有价值得多。
本文还有配套的精品资源,点击获取