4. IO与运动协同:IO触发运动启动/停止、IO控制运动参数切换、IO状态反馈与运动状态联动
各位工程师,欢迎来到第四章。这一章我们聊点真正实战的东西——IO和运动怎么“打配合”。
说实话,很多刚入行的朋友容易把IO和运动当成两件事。IO归IO,运动归运动,各管各的。但在实际产线上,这两者根本分不开。你想想看,一个气缸到位了,电机才能启动;一个传感器检测到工件了,夹爪才能闭合。这就是IO与运动的协同。
我个人习惯把这种协同关系分成三个层次:触发、切换、反馈。咱们一个一个来拆解。
4.1 IO触发运动启动/停止
这是最基础、也是最常用的场景。说白了,就是用IO信号当“开关”,告诉运动系统什么时候干活、什么时候停下。
我在项目中遇到过这样一个案例:一条包装线,需要根据光电传感器的信号启动输送带。传感器检测到产品到位,输送带启动;产品离开,输送带停止。听起来简单吧?但坑就藏在细节里。
核心逻辑:
- 上升沿触发启动:IO信号从0变1的瞬间,触发运动指令
- 下降沿触发停止:IO信号从1变0的瞬间,触发停止指令
- 电平保持触发:IO信号持续为1时运动,为0时停止
这里有个关键点——边沿触发和电平触发的选择。我见过有人用错了触发方式,结果设备乱跳。举个例子:
// 边沿触发(推荐用于启动/停止)
IF IO_Sensor_RisingEdge THEN
MC_Power( Axis := 1, Enable := TRUE );
END_IF
IF IO_Sensor_FallingEdge THEN
MC_Power( Axis := 1, Enable := FALSE );
END_IF
// 电平触发(用于持续控制)
IF IO_Sensor_Level THEN
MC_MoveVelocity( Axis := 1, Velocity := 100 );
ELSE
MC_Stop( Axis := 1 );
END_IF
我的经验:启动用上升沿,停止用下降沿。这样最干净,不会因为信号抖动导致误触发。如果你用PLC做,记得在程序里加一个去抖计时器,10ms左右就够了。
4.2 IO控制运动参数切换
这一层就有点意思了。不是简单的启停,而是用IO信号来切换运动参数——速度、位置、加速度,甚至整个运动曲线。
举个例子:一台点胶机,需要根据产品型号切换点胶速度。型号A用高速,型号B用低速。怎么实现?用IO组合。
| IO1 | IO2 | 速度档位 | 应用场景 |
|---|---|---|---|
| 0 | 0 | 低速 (50 mm/s) | 精密点胶 |
| 0 | 1 | 中速 (100 mm/s) | 标准点胶 |
| 1 | 0 | 高速 (200 mm/s) | 快速点胶 |
| 1 | 1 | 超高速 (300 mm/s) | 试产模式 |
你看,两个IO信号就能组合出4种速度档位。这在产线上非常实用。我曾经做过一个项目,用4个IO信号组合出16种运动参数配置,覆盖了整条产线的所有产品型号。
注意:参数切换时,一定要考虑运动轴的当前状态。如果轴正在运动中突然切换速度,可能会造成冲击。我建议在切换前先做一次减速,或者用MC_ChangeVelocity这类平滑过渡指令。
代码实现也很直接:
// IO组合读取
SpeedSelect := IO_Speed1 + IO_Speed2 * 2;
CASE SpeedSelect OF
0: TargetVel := 50;
1: TargetVel := 100;
2: TargetVel := 200;
3: TargetVel := 300;
END_CASE
// 应用速度
MC_MoveVelocity( Axis := 1, Velocity := TargetVel );
4.3 IO状态反馈与运动状态联动
这一层是协同控制的“闭环”。运动系统在执行任务,IO系统在反馈状态,两者互相联动,形成一个完整的控制回路。
我把它总结成三个典型场景:
- 运动到位反馈:轴运动到目标位置后,输出一个IO信号,告诉PLC“我到位了”
- 运动故障反馈:轴出现报警或故障时,输出IO信号,触发急停或报警灯
- 运动状态联动:根据运动状态(运行中、停止中、回零中)控制IO输出
实战案例:一台六轴机器人抓取工件。机器人运动到抓取位置后,输出“到位信号”给PLC,PLC再控制夹爪气缸闭合。夹爪闭合后,传感器反馈“夹紧信号”,机器人才能开始抬升运动。这就是典型的IO与运动状态联动。
代码实现上,我习惯用状态机来管理:
// 运动状态反馈
IF MC_ReadStatus( Axis := 1 ).InPosition THEN
IO_InPosition := TRUE;
ELSE
IO_InPosition := FALSE;
END_IF
// 故障反馈
IF MC_ReadStatus( Axis := 1 ).Error THEN
IO_Error := TRUE;
MC_Stop( Axis := 1 );
END_IF
// 状态联动
CASE MotionState OF
0: // 空闲
IO_Busy := FALSE;
IF IO_StartSignal THEN
MotionState := 1;
END_IF
1: // 运动中
IO_Busy := TRUE;
MC_MoveAbsolute( Axis := 1, Position := TargetPos );
IF MC_ReadStatus( Axis := 1 ).InPosition THEN
MotionState := 2;
END_IF
2: // 到位
IO_InPosition := TRUE;
// 等待外部IO确认
IF IO_Confirm THEN
IO_InPosition := FALSE;
MotionState := 0;
END_IF
END_CASE
避坑指南:我曾经在一个项目中,因为没处理好IO反馈的时序,导致机器人抓取动作和夹爪动作冲突。后来加了一个50ms的延时,问题就解决了。记住,IO信号和运动指令之间,永远要留一点“缓冲时间”。
4.4 知识体系总览
为了让大家更直观地理解这三层关系,我画了一张结构图。你可以把它当作本章的“地图”。
4.5 实战要点总结
好了,这一章的内容就这些。最后我给大家列几个实战中一定要记住的点:
- 去抖处理:所有IO信号进PLC前,先做10-20ms的去抖滤波
- 边沿优先:启动/停止用边沿触发,参数切换用电平组合
- 状态机管理:复杂的协同控制,一定要用状态机,别用散乱的IF-ELSE
- 时序留余量:IO反馈和运动指令之间,加50-100ms的缓冲时间
- 调试工具:用示波器或PLC的Trace功能,同时观察IO信号和运动状态
最后提醒一句:IO与运动协同,最怕的就是“想当然”。你以为信号到了,实际上没到;你以为运动停了,实际上还在滑行。所以,一定要做联机测试,用实际信号验证每一个逻辑分支。