1. 项目背景与核心挑战
去年接手的一个汽车零部件生产线改造项目,客户要求在现有狭小空间内集成四台伺服电机驱动的传送带和一台六轴工业机器人,控制系统指定使用三菱FX5u系列PLC。这个项目最棘手的地方在于:传统梯形图编程方式根本无法处理如此复杂的多轴协同逻辑,必须采用结构化编程方案。
现场环境比预想的更复杂:伺服电机需要实时响应机器人抓取动作,传送带速度要根据工件类型动态调整,所有设备共用同一个安全回路。第一次上电调试时,机器人经常在传送带未准确定位时就启动抓取动作,导致频繁报警停机。经过三周日夜调试,最终通过结构化程序框架+事件触发机制解决了这个难题。
2. 结构化程序设计框架
2.1 程序模块划分原则
整个项目程序按功能划分为以下核心模块(括号内为实际使用的软元件地址范围):
- 主控程序(MAIN) - 负责流程调度和异常处理(M0-M499)
- 伺服控制模块(SERVO) - 管理4台MR-JE-40A伺服(D1000-D1299)
- 机器人通信模块(ROBOT) - 处理与安川GP25的Ethernet/IP通信(D2000-D2199)
- HMI接口模块(HMI) - 与GS2107触摸屏数据交换(D3000-D3099)
- 安全逻辑模块(SAFETY) - 急停/光栅/双手按钮处理(X0-X27)
关键技巧:每个模块的软元件地址范围预留20%余量,后期调试时发现这个预留空间救了命 - 新增的伺服补偿参数刚好能塞进预留区域。
2.2 全局变量定义规范
在GX Works3中建立全局标签数据库时,采用"设备_功能_参数"的命名规则:
structured_text复制// 伺服相关
Servo1_TargetPos : DINT := D1000; // 1号伺服目标位置
Servo2_ActualSpeed : INT := D1010; // 2号伺服实际转速
// 机器人状态
Robot_CurrentTool : USINT := D2000; // 当前工具号
Robot_AlarmCode : WORD := D2001; // 报警代码
实测发现,比起直接使用D寄存器地址,这种带语义的标签使程序可读性提升300%以上。特别是在凌晨三点排查故障时,能快速定位到相关变量。
3. 伺服控制实战技巧
3.1 多轴同步启动方案
传统做法是依次启动各伺服使能(SET M50→SET M51→...),实际测试发现这种方式会导致轴间同步误差>2mm。改进方案:
- 使用PLSV指令同时发送4轴使能脉冲
- 通过D1370-D1373设置各轴启动延迟(单位0.1ms)
- 增加以下补偿逻辑:
structured_text复制IF Servo_AllReady THEN // 所有伺服准备就绪
MOV K0 D1370 // 1号轴无延迟
MOV K2 D1371 // 2号轴延迟0.2ms
MOV K3 D1372 // 3号轴延迟0.3ms
MOV K1 D1373 // 4号轴延迟0.1ms
PLSV K4 // 同时触发4轴
END_IF;
实测同步精度提升到±0.1mm,但要注意:延迟参数必须现场用示波器校准,我们最后采用的数值与初始计算值偏差达40%。
3.2 位置跟随的两种实现方式
当机器人需要抓取传送带上的工件时,关键是要实现位置实时跟随。我们对比测试了两种方案:
| 方案 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 高速计数器比较中断 | 响应快(≤1ms) | 占用硬件资源 | 定位精度要求±0.5mm |
| 定时扫描+软PLC计算 | 不占硬件 | 延迟大(约10ms) | 精度要求±2mm以上 |
最终在1、2号工位采用方案1(C251计数器+Y10输出),3、4号工位用方案2。调试中发现一个手册没写的细节:FX5u的高速计数器在频率超过200kHz时,比较指令会有约3μs的随机抖动,需要通过以下滤波程序消除:
structured_text复制// 在中断程序开头添加
LD M8000 // 运行监控
AND > D100 K200 // 频率>200kHz
OUT M100 // 滤波使能
LD M100
MC N0 // 滤波处理开始
...
MCR N0 // 滤波处理结束
4. 机器人通信关键点
4.1 Ethernet/IP通信配置
安川GP25机器人作为EIP从站,需要特别注意以下几点:
- 在GX Works3的模块配置中,输入/输出各分配32字节(实际只用前20字节)
- 通信周期设置为8ms(默认16ms会导致动作卡顿)
- 添加以下心跳检测程序防止通信超时:
structured_text复制// 心跳包发送
LD SM400
OUT Y20 // 通信指示灯
LD X20 // 机器人应答信号
AND M8000
MOV K0 D2005 // 清零超时计数器
LD X20
ANI M8000
INC D2005 // 超时计数+1
LD >= D2005 K300 // 5秒超时判定
OUT M200 // 触发报警
4.2 坐标转换算法
机器人需要获取传送带上的工件坐标,我们采用"伺服脉冲值→机械坐标→机器人坐标"的三步转换:
- 读取伺服当前位置(D1340-D1343)
- 通过机械参数计算实际坐标(公式见下图)
- 转换到机器人基坐标系:
code复制机器人X = (传送带X × cosθ) - (传送带Y × sinθ) + 基准X
机器人Y = (传送带X × sinθ) + (传送带Y × cosθ) + 基准Y
现场调试时发现cosθ/sinθ值必须保留6位小数,否则累计误差会导致末端偏移。最终采用D浮点数运算,比常规浮点精度提升10倍。
5. 安全回路设计陷阱
5.1 急停逻辑的隐藏风险
最初的安全回路设计存在致命缺陷:急停信号(X0)直接切断所有伺服使能(Y10-Y13)。实际测试发现:
- 伺服立即掉使能会导致机械臂因惯性前冲
- 机器人未收到减速指令可能损坏夹具
改进后的分级停止方案:
- 急停触发后首先发送减速指令(Y14)
- 延迟200ms后再切断伺服使能
- 500ms后触发机器人紧急停止(Y15)
structured_text复制// 急停处理程序
LD X0 // 急停信号
SET M100 // 触发急停
OUT Y14 // 发送减速指令
LD M100
TMR T0 K200 // 200ms定时器
LD T0
OUT Y10-Y13 // 切断伺服使能
LD T0
TMR T1 K300 // 再延时300ms
LD T1
OUT Y15 // 触发机器人急停
5.2 光栅屏蔽的注意事项
在自动换模工序需要临时屏蔽安全光栅(X10-X13),必须满足三个条件:
- 模式开关打到"维护"位置(X25=ON)
- 双手按钮持续按下(X26+X27)
- 换模完成信号未触发(M210=OFF)
对应的互锁逻辑:
structured_text复制LD X25 // 维护模式
AND X26 // 左手按钮
AND X27 // 右手按钮
ANI M210 // 未完成信号
OUT M150 // 光栅屏蔽使能
LD M150
AND X10-X13 // 光栅信号
MOV K0 D500 // 屏蔽期间清零报警计数
现场发生过因员工单手操作导致光栅误触发的事故,后来在程序中增加了双手按钮必须持续按压≥3秒的判断逻辑。
6. 调试中遇到的典型问题
6.1 伺服电机偶尔丢脉冲
现象:设备运行几小时后,2号轴会累积约5个脉冲的误差。
排查过程:
- 检查编码器电缆(正常)
- 测量电源电压(发现24V有0.3V波动)
- 更换开关电源后问题依旧
- 最终发现是接地不良导致干扰
解决方案:
- 在伺服驱动器PE端增加独立接地线
- 脉冲指令线改用双绞屏蔽电缆
- 程序中添加以下补偿算法:
structured_text复制// 丢脉冲补偿
LD SM400 // 常ON
CMP D1010 K0 // 检查2号轴实际速度
<= M10 // 速度为0时补偿
LD M10
AND <> D1005 D1006 // 比较目标/实际位置
MOV D1005 D1006 // 强制同步位置
6.2 机器人偶尔抓偏
现象:每约50次抓取会出现1次位置偏移,误差约3mm。
根本原因:Ethernet/IP通信周期(8ms)与机器人控制周期(4ms)不同步,导致坐标数据更新不及时。
最终解决方案:
- 在机器人侧增加坐标预测算法
- PLC程序中添加以下同步锁存逻辑:
structured_text复制// 坐标数据同步
LD M8000
MOV D2000 D2990 // 锁存X坐标
MOV D2001 D2991 // 锁存Y坐标
MOV D2002 D2992 // 锁存Z坐标
// 只在机器人请求时更新新数据
LD X21 // 数据请求信号
MOV D2990 D2000
MOV D2991 D2001
MOV D2992 D2002
这套方案实施后,连续测试2000次抓取零误差。关键点在于:数据更新必须由机器人主动请求,而非PLC周期发送。
7. 程序优化技巧
7.1 扫描周期压缩方法
项目初期程序扫描周期达到35ms,通过以下优化降到8ms:
- 将连续执行的MOV指令改为块传输(FMOV)
- 优化前:100个MOV指令约3.5ms
- 优化后:1个FMOV指令约0.2ms
- 用ALT指令替代自锁回路
- 传统自锁:约0.1ms/次
- ALT指令:约0.02ms/次
- 禁用未使用的软元件监控功能
7.2 内存占用优化
FX5u的32K步程序容量很快用尽,通过以下方法节省了40%空间:
- 重复使用的功能块改为子程序调用
- 将频繁修改的参数集中到文件寄存器(D10000+)
- 使用SFR指令回收不再使用的软元件
特别提醒:在GX Works3中启用"程序压缩"功能后,某些边缘case会出现指令执行异常。建议只在最终发布前使用该功能。
