简介:面向汇川H5U系列PLC与MCGS触摸屏开发者的三轴示教系统源码,适合工业自动化、PLC编程及触摸屏开发场景,支持离线仿真,可快速上手并用于二次开发。压缩包共3个文件,包括inscode工程配置、index.html界面文件与.gitignore过滤规则,整体仅7KB,精简但结构清晰,便于导入开发环境后直接查看和修改。源码注释详尽,本身便是一份扩展指南,并围绕示教点录入的异步处理、三轴直线插补参数设置、仿真模式数据处理、运动模式扩展方案以及通讯故障排查给出了可落地的实现思路;同时,这套系统亦可作为通用三轴控制模板,按需移植到点胶、焊接、搬运等自动化设备中。目前已有57人学习,对需要掌握汇川H5U运动控制与MCGS界面联调的开发者而言,是一份轻量且实用的参考。
1. 项目概述与方案选型
1.1 这个项目到底解决什么问题
三轴示教系统,说穿了就是让一台XYZ三轴运动平台"学会"走一遍固定轨迹,然后把轨迹存下来,以后让它自动重复。这在小型的点胶机、锁螺丝机、焊锡机、搬运码垛机上非常常见。你没看错,现在市面上很多非标设备的核心,其实就是这套东西——人工拖或者摇着手轮走一遍路径,PLC把点位记下来,自动运行的时候按顺序走这些点,配合IO输出控制胶枪、螺丝批或者焊笔的动作。
这个项目用汇川的PLC来落地,而且带了源码,对搞非标自动化、做设备集成、或者正在学汇川运动控制的工程师来说,是个非常适合拆解参考的完整案例。它不是什么高大上的AI视觉引导,也不是复杂的轨迹规划,它就是一个"通用点位示教+轨迹复现"的标准模板,但恰恰是这种基础框架,能覆盖掉现场一大半的真实需求。
1.2 硬件方案怎么定
先别急着看代码,硬件选型才是决定这套系统好不好用的第一步。三轴平台本身大家都懂,关键是控制器和伺服怎么搭。汇川这边做三轴点位示教,主流的方案有这么几条路线:
| 方案 | 控制器 | 伺服方案 | 特点 |
|---|---|---|---|
| 方案A | H5U + IS620N伺服 | EtherCAT总线 | 接线少,扩展性好,程序里用轴控指令比较顺手 |
| 方案B | AM401/AM402 + IS620N | EtherCAT总线 | 老牌运动控制PLC,资料多,适合做复杂运动 |
| 方案C | Easy系列 + 脉冲伺服 | 脉冲方向控制 | 成本最低,适合点位少、精度要求不高的场景 |
我做这个项目的时候用的是H5U加IS620N伺服走EtherCAT总线。选它的原因很直接:第一,H5U内置EtherCAT主站,带三根轴不需要额外加运动控制卡或者总线耦合器,硬件成本压下来了;第二,InoProShop这个编程软件集成了PLC和伺服调试,一个软件搞定逻辑和伺服参数配置,现场调试少带一个调试器;第三,H5U支持IEC 61131-3标准的ST、梯形图、SFC等语言,我做点位示教这种带有数据结构操作的逻辑,用ST写起来比梯形图舒服太多了。
1.3 为什么选汇川这套组合
其实做示教系统,市面上很多方案是用触摸屏的配方功能去存点位的。比如威纶通触摸屏直接内置了"点位示教"控件,配合PLC的MODBUS寄存器就能实现简单的示教存储。但为什么我最后还是决定自己用PLC源码实现?
原因在于触摸屏配方的模式有几个绕不开的坑。一是点位数量有限,屏的配方区是按固定行数做的,做多了麻烦;二是点位坐标的读取存在通信延迟,你手动移动轴的时候,屏上显示的位置和PLC实际的值有偏差,存下来的点可能"差那么一点点";三是速度和IO输出时序的联动控制,用屏的配方来实现很别扭。
自己在PLC里实现示教逻辑,坐标数据直接存在PLC的掉电保持区,读的是伺服的实际位置,IO输出的时序可以在梯形图里精确控制,整套逻辑跑下来非常顺手。这就是我这个项目的核心决策:示教的灵魂在PLC,不在屏。
2. 核心数据结构与程序框架
2.1 点表结构设计
写示教系统源码,第一件要设计的事情不是程序流程,而是数据怎么存。点位数据是整个系统的血液,每存一个点,至少要包含坐标、速度、IO动作、等待条件这些信息。
我在源码里定义的数据结构大致是这样的:
// 点位数据结构 TYPE POINT_RECORD : STRUCT X_POS : LREAL; // X轴坐标,单位mm Y_POS : LREAL; // Y轴坐标,单位mm Z_POS : LREAL; // Z轴坐标,单位mm RUN_SPEED : REAL; // 该点的运行速度百分比 IO_OUT : BYTE; // IO输出状态,bit0~bit7对应Y0~Y7 WAIT_TIME : UINT; // 到达该点后停留时间,单位ms IS_END : BOOL; // 是否轨迹结束点 RESERVED : BYTE; // 预留字段 END_STRUCT END_TYPE这里强调几个设计考量。坐标用LREAL双精度浮点,是因为在ST里做毫米和脉冲的转换计算时,REAL单精度在大坐标值下会有累积误差,用双精度稳一点。RUN_SPEED存放在点位里,是为了让程序在运行的时候能切换不同的速度,比如接近工件的时候慢速,空跑的时候快速,这样既能保护机械又能提高节拍。IO_OUT这个字节很关键,它把"走到这个位置要做什么动作"和轨迹本身绑定在一起了,这样在自动运行时,PLC可以根据当前点位直接输出对应的Y端子信号,控制胶枪开关、电磁阀通断等,完全不需要额外写散乱的IO逻辑。
2.2 示教模式与自动模式的程序架构
整套PLC程序我分成了三个大的程序块:示教管理程序、轨迹运行程序、IO与报警处理程序。这三个块在PLC的扫描周期里循环运行,但通过一个系统状态变量来切换工作模式。
状态变量我设计的是一个枚举类型:
TYPE SYS_MODE : ( MODE_MANUAL := 0, // 手动模式:点动各轴,用于示教对位 MODE_TEACH := 1, // 示教模式:记录当前坐标为点位 MODE_AUTO := 2, // 自动模式:按点位表自动运行 MODE_HOME := 3, // 回零模式:执行回原点流程 MODE_ALARM := 4 // 报警模式:触发急停或故障 ); END_TYPE这个模式切换是整个系统的"总闸"。手动模式下,触摸屏上的点动按钮直接控制伺服的点动脉动,速度是固定低速,方便精确对位。示教模式下,每按一次"记录点位",PLC就把三轴的当前实际位置连同当前设置的速度、IO状态、停留时间打包写入点表的下一个空位。自动模式下,程序自动按顺序加载点表里的点并依次执行。
这样设计的核心逻辑是"状态分离"——手动、示教、自动三个动作的代码在物理上分开,互不干扰,在调试的时候出问题也好定位。我见过很多新手喜欢把模式切换写成一个巨大的IF嵌套,最后出问题的时候连自己都绕不进去。
2.3 轴控制指令和伺服使能的处理
H5U控制IS620N伺服,在InoProShop里的轴控指令主要用MC_Power(使能)、MC_Home(回零)、MC_MoveAbsolute(绝对定位)、MC_MoveVelocity(速度运行)这些标准运动控制指令。
有一个细节比轴控指令本身更重要,就是伺服使能的处理。示教系统里,人员在机器旁边走来走去,随时可能碰到急停,如果程序里做的使能逻辑不到位,伺服一掉使能,轴就会溜车或者产生冲击。
我的处理方式是做了一个"软使能保护"逻辑:只有当急停信号(硬IO)不复位、安全门信号正常、且当前没有报警时,MC_Power的Enable输入才允许为TRUE。任何异常都会让使能断开。同时,伺服驱动器的SON信号与PLC输出的继电器回路做了硬串联,确保PLC程序挂了、驱动器也能独立断开使能。这是现场安全的基本底线,不能省。
3. 示教功能的实操实现
3.1 坐标读取:示教的核心"手感"问题
示教系统的使用者最常见的操作是什么?把轴摇到想要的位置,按一下"记录"按钮。听起来很简单,但如果坐标读取的时机不对,存下来的点和实际位置就差之毫厘谬以千里。
我源码里坐标读取用的是H5U的轴当前位置对象,比如MC_Power状态下的Axis.NcToPlc.ActPos。这个是伺服编码器的实际位置反馈,不是指令位置。为什么要用实际位置而不是指令位置?因为在低速点动或负载较重的情况下,指令位置和实际位置会有跟随误差,如果你存的是指令值,那示教的时候看起来对得准,实际跑的时候会偏。用实际反馈位置,存下来的就是伺服真实到达的位置,误差就小很多。
另外,读取坐标的时刻也要处理得讲究一点。我是在按钮信号的上升沿先做了一次"防抖延时"(建议100~200ms),等轴完全停下来之后才读取坐标。原因很朴素:你手松开机按钮的一瞬间,机械还没完全静止,如果这时候立刻读坐标,那个位置和最终静止位置可能差一两毫米。在现场你感受不到,但在精密点胶上这就是废品了。
3.2 速度处理和示教移动
示教的时候,人要在机器旁边摇轴,速度控制非常影响体验。这里我推荐的做法是:点动模式只允许用速度模式,不能用绝对定位方式移动。
什么意思呢?点动按钮按住,轴就以设定的速度持续运动,手松开就停。这样最符合人的直觉。如果按一下按钮就固定走一段距离,操作人员在离工件很近的时候很容易撞上去。而在InoProShop里,点动我用的是带速度输入的"MC_MoveVelocity"指令,速度值由触摸屏上的"点动速度"数值框控制,默认设成10~20mm/s,对绝大多数示教场景都够用了。
这里要特别提醒一个H5U的坑:MC_MoveVelocity指令在启动和停止的时候,加速度和减速度是由轴参数里的加加速参数决定的。把加速度参数调太大会导致机械冲击,调太小又感觉"肉腾腾"。我实测下来,对常见的皮带模组和丝杆模组,加速度设置在500~800mm/s²比较合适,再结合负载惯性比去做微调,手感会好很多。
3.3 点位记录的完整流程
记录一个点位的操作流程,在触摸屏上做成了两步操作:
- 第一步,先在上方的参数设置区填好"目标速度""IO输出状态""停留时间",这些会作为下一个点位的属性值。
- 第二步,按下"记录点位"按钮,系统把当前坐标和刚才填的参数打包存入点表,同时点位编号自动加一。
这个流程看起来简单,但我在代码里加了一个"点位防覆盖"的逻辑:只有在"示教模式"下,记录按钮才有效;手动模式下误触记录按钮是不会写入数据的。这样防止了现场员工在不熟悉操作的时候误改了程序的点位。
点位的存储空间我预留了200个,对于三轴的小型设备完全够用。存储区域放在PLC的掉电保持区,断电重启数据不丢。
4. 自动化运行逻辑与控制流程
4.1 从示教到自动运行的切换流程
当点表记录完毕,接下来要切换到自动模式运行。这块其实是整套系统在生产现场最常被考核的部分——稳定性。
自动模式的启动流程是这样的:
// 自动模式启动流程(伪代码) IF mode = MODE_AUTO THEN // 第一步:检查各轴是否已回零 IF NOT is_homed[0] OR NOT is_homed[1] OR NOT is_homed[2] THEN Alarm(ALARM_NOT_HOME); RETURN; END_IF // 第二步:检查点表是否为空 IF current_point_count = 0 THEN Alarm(ALARM_POINT_EMPTY); RETURN; END_IF // 第三步:开始自动循环 step := 0; auto_running := TRUE; END_IF第一道检查是回零状态,第二道是点表是否为空。这两个检测如果不过,自动模式根本起不来。这能挡掉一大半因为误操作导致的运行异常。
自动运行的循环逻辑我用的是"步进式"状态机,每一个步骤代表一个点位的执行周期:
CASE auto_step OF 0: // 等待自动启动信号,准备加载第0个点 IF auto_running THEN LoadPoint(0); auto_step := 1; END_IF 1: // 执行定位 MC_MoveAbsolute(axis_x, point_table[pt_index].X_POS, point_table[pt_index].RUN_SPEED); MC_MoveAbsolute(axis_y, point_table[pt_index].Y_POS, point_table[pt_index].RUN_SPEED); MC_MoveAbsolute(axis_z, point_table[pt_index].Z_POS, point_table[pt_index].RUN_SPEED); auto_step := 2; 2: // 等待到位 IF InPosition(axis_x) AND InPosition(axis_y) AND InPosition(axis_z) THEN // 输出IO动作,启动停留计时 Y0_OUT := point_table[pt_index].IO_OUT.0; Y1_OUT := point_table[pt_index].IO_OUT.1; wait_timer(IN := TRUE, PT := point_table[pt_index].WAIT_TIME); auto_step := 3; END_IF 3: // 等待停留结束,切换下一个点 IF wait_timer.Q THEN pt_index := pt_index + 1; IF point_table[pt_index].IS_END THEN auto_running := FALSE; auto_step := 0; ELSE LoadPoint(pt_index); auto_step := 1; END_IF END_IF END_CASE这套状态机的好处是每个步骤职责清晰,后续要加功能(比如每个点做两次重复、或者中途暂停)都在对应步骤里扩展就行,不会破坏整体框架。
4.2 到位判断的细节处理
"到位判断"是整个自动运行里最容易被忽视又最能影响设备寿命的地方。很多新手的做法是直接看MC_MoveAbsolute的Done信号——到了才置位。但实际伺服运动里,MC_MoveAbsolute在减速结束、位置到达后触发Done,这没问题,但频繁的起停会让机械结构非常受力。
我实际用的是"到位窗口"判断:给每个轴设置了一个允许的到位误差范围(比如X轴正负0.05mm,Y轴正负0.05mm,Z轴正负0.03mm),当三轴的实际位置都落在目标点周围的这个误差窗口内,并且位置误差的变化率已经很小(即速度接近零),就判定为到位。这样的好处是:如果设备上有轻微的机械抖动,在窗口内抖动不触发报警;如果要追求高速,可以在适当扩大窗口的前提下提升移动速度,让设备在"差不多到了"的时候就开始执行IO动作,节省节拍。
当然,到位窗口也不能设得太宽,否则会影响精度。对一般的点胶和锁螺丝设备,正负0.1mm以内的窗口比较合理。
4.3 回零逻辑
三轴系统的回零逻辑是自动运行的前置条件,很多人把它当成简单的事,其实这里坑不少。H5U里面做MC_Home回零,我用的是"当前位置设定为零点"的方式(即定义当前位置为原点),同时配一个硬件原点开关做辅助判断。
实际上在生产现场,我建议用"减速开关+Z相脉冲"的标准回零方式,这样每次回零的重复精度最高。但如果机械结构上没有安装回零开关,那就只能用当前位置设零的方式,这个情况下一定要在设备上做"软限位"保护,防止轴跑出去撞机械极限。我在源码里就是三轴都用软限位,位置超过设定范围立刻报警停机。
5. 常见问题与调试心得
5.1 伺服使能冲突和报警处理
做汇川伺服调试的时候,很多工程师都会遇到"使能冲突"报警。这个报警在IS620N上非常典型:你在InoProShop的调试面板里手动给伺服使能了,然后PLC程序一运行,MC_Power也尝试使能,两边的使能信号打架,驱动器直接报冲突。
这个问题我踩过一次之后学乖了,总结下来的经验是:PLC程序和调试软件不能同时对同一个轴执行使能操作。你在调试面板里确认使能之后,要在面板里先断开使能,再运行PLC程序。反过来也一样。如果已经报使能冲突,先把程序切到手动模式,断开程序侧使能,再在调试面板里复位报警。
5.2 点位记录偏了怎么办
示教完跑了几次,发现某几个点位的实际位置总是和示教的时候差了一点。这个问题排查顺序很重要,我按经验列一下优先级:
- 先看伺服是否在运行过程中发生过报警、丢步。如果伺服报警过,轴的绝对位置可能已经被重置或者偏移了,这时候需要重新回零再跑一遍。
- 检查机械间隙。皮带传动的模组如果涨紧度不够,正反向走同一个位置时会有回程间隙,这时候示教点和实际到位点必然有偏差。可以用千分表打一下同一个位置的来回重复精度,通常正反向误差超过0.1mm就要紧皮带或者考虑换丝杆结构了。
- 检查PLC的扫描周期和轴控指令是否在同一个任务里。H5U默认的轴控任务需要放在一个固定周期任务里(比如1ms或2ms),如果程序写在普通任务里,轴控指令的执行时间会有波动,后续逻辑的时序也不稳定。这是我遇到过的一个隐蔽问题。
5.3 触摸屏通信偶尔断开怎么办
在实际运行中,触摸屏和PLC的通信偶尔会断开,尤其是在示教模式下高频读取轴位置的时候。这个问题根源往往是通信负载过大——屏幕上每个数值框都在高频刷新,加上示教界面同时显示三个轴的实时位置,MODBUS或者以太网的通信报文过多,触摸屏的CPU处理不过来。
解决的办法很实用:给示教界面的坐标显示加上"500ms刷新"或者"手动刷新"模式。示教的时候操作人员不需要实时看到位置变化,点位记录后自动刷新一次坐标显示就够了,完全没有必要实时刷新。运行的时候坐标显示的刷新频率可以适当高一点,但也不需要超过100ms。这样一通优化之后,触摸屏通信明显稳定了。
5.4 关于InoProShop的调试小技巧
最后分享一个InoProShop里非常实用的调试技巧,就是在线监控+强制变量。示教系统调试点位记录逻辑的时候,我经常需要模拟"按下了记录按钮"这个动作。如果每次都在触摸屏上点,来回跑很烦。直接在InoProShop的监控窗口里,把某个临时BOOL变量强制成TRUE,再拉回FALSE,就模拟了一次按钮按下。配合断点监控,可以很清楚地看到点位表格里的写入过程。
另外InoProShop的"在线追踪"功能也很值得一用,它可以记录轴的指令位置和实际位置曲线,排查跟随误差和到位窗口的问题非常直观。我之前一直怀疑某个轴的到位信号判断时机有问题,用追踪一看,发现实际位置曲线在目标位置附近有轻微的振荡,导致到位窗口判断一直处于临界状态,后来把轴的速度环增益稍作调整,问题就消失了。这种问题光看程序是看不出来的,必须靠波形去定位。
三轴示教系统的源码工程在实际部署中,还可以按设备类型灵活扩展——比如增加一个IO输出用于控制真空吸盘、增加一个输入点用于检测是否夹取到位,或者把点表逻辑升级为支持多配方切换,一套程序管多个产品型号的轨迹。这些扩展的骨架,在这套点表加状态机的框架里都留好了口子。
本文还有配套的精品资源,点击获取