1. 项目背景与核心价值
三轴码垛仿真确实是工业控制领域最具代表性的入门项目之一。我从业十年间带过的所有工控新人,第一个实战项目几乎都是这个。为什么它如此经典?因为一个完整的码垛系统几乎涵盖了工控领域所有基础要素:运动控制、逻辑编程、传感器应用、人机交互,以及最关键的——如何将抽象的控制逻辑转化为物理设备的精确动作。
这次我们采用Factory IO搭建立体仓库场景,配合西门子TIA Portal V16(博图)编写PLC程序。Factory IO作为目前最接近真实产线的3D仿真平台,其物理引擎可以模拟真实设备间的碰撞、延时等特性,而TIA Portal则是工业现场使用率最高的编程环境之一。这种组合既能避免新手直接操作真实设备的风险,又能获得近乎真实的调试体验。
2. 场景搭建与硬件配置
2.1 Factory IO场景构建
打开Factory IO后选择"Empty Scene",我们先从传送带开始搭建:
- 在"Conveyors"分类下选择"Belt Conveyor (400mm)",这是标准宽度传送带
- 添加光电传感器"Photoeye"作为货物到达检测
- 插入"Palletizer"模块作为码垛机主体,调整其X/Y/Z轴行程分别为800/600/400mm
- 最后放置"Rack"货架模块,设置4行4列的存储位
关键技巧:按住Ctrl键拖动模块可快速复制,Shift+方向键实现微调定位。建议将传送带与货架的间距设为码垛机最大伸展距离的80%,留出安全余量。
2.2 博图V16硬件组态
在TIA Portal中新建项目,设备选择S7-1200 CPU 1214C DC/DC/DC(最常用的入门级PLC):
- 在"设备视图"中添加工艺对象"TO_PositioningAxis"×3,分别对应X/Y/Z轴
- 配置每个轴的硬件接口:
- X轴:PTO脉冲输出Q0.0,方向信号Q0.1
- Y轴:PTO脉冲输出Q0.2,方向信号Q0.3
- Z轴:PTO脉冲输出Q0.4,方向信号Q0.5
- 设置轴参数(以X轴为例):
javascript复制{ "Mechanics": "Lead screw", // 丝杠传动 "Lead": 5, // 导程5mm/转 "MaxVelocity": 500, // 最大速度500mm/s "Acceleration": 1000, // 加速度1000mm/s² }
3. PLC程序开发详解
3.1 主控制逻辑框架
在OB1主循环中建立状态机控制结构:
pascal复制CASE #CurrentState OF
0: // 待机状态
IF #StartButton THEN
#CurrentState := 10;
END_IF;
10: // 传送带运行
"Conveyor_Run"(Speed := 50);
IF "Photoeye_In".Q THEN
"Conveyor_Stop"();
#CurrentState := 20;
END_IF;
20: // 抓取货物
"Palletizer_Gripper"(Open := FALSE);
#Timer_Delay(IN := TRUE, PT := T#1S);
IF #Timer_Delay.Q THEN
#CurrentState := 30;
END_IF;
// 更多状态省略...
END_CASE;
3.2 运动控制功能块
创建FB500"Axis_MoveAbsolute"功能块实现点位运动:
pascal复制// 输入参数
VAR_INPUT
Axis: INT; // 轴号
Position: REAL; // 目标位置(mm)
Velocity: REAL := 300; // 默认速度
END_VAR
// 临时变量
VAR_TEMP
cmdPos: MC_MoveAbsolute;
END_VAR
// 功能实现
cmdPos(
Axis := "AxisDB"[Axis].TO_Reference,
Position := Position,
Velocity := Velocity,
Execute := TRUE);
3.3 货位管理算法
采用二维数组管理库存状态,在DB1中定义:
pascal复制TYPE Stock_Info :
STRUCT
IsOccupied : BOOL; // 货位占用状态
PalletID : INT; // 托盘编号
Timestamp : DATE_AND_TIME; // 入库时间
END_STRUCT
END_TYPE
VAR
RackStatus : ARRAY[1..4,1..4] OF Stock_Info; // 4x4货架
CurrentPos : ARRAY[1..3] OF REAL; // XYZ当前位置
END_VAR
4. 联调技巧与问题排查
4.1 Factory IO信号映射
在Factory IO的I/O配置中建立信号关联:
| 信号名称 | PLC地址 | 类型 | 说明 |
|---|---|---|---|
| Conveyor_Run | Q0.6 | 输出 | 传送带启动 |
| Photoeye_In | I0.0 | 输入 | 进料光电传感器 |
| Gripper_Open | Q0.7 | 输出 | 夹具打开 |
常见坑:Factory IO的输入信号需要设置为"Normally Open"(常开)模式,否则PLC接收到的信号逻辑会相反。
4.2 运动控制调试要点
-
轴抖动问题:
- 检查PTO脉冲频率是否超过PLC输出能力(S7-1200最高100kHz)
- 适当降低加速度参数,建议从500mm/s²开始逐步上调
-
定位偏差:
mathematica复制实际位移 = 脉冲数 × 导程 / 每转脉冲数检查伺服驱动器的电子齿轮比设置是否与PLC配置一致
-
极限位保护:
务必在程序开始添加硬限位检测逻辑:pascal复制IF NOT "LimitSwitch_X_Min" THEN "Axis_X".MC_Stop(Execute := TRUE); END_IF;
5. 进阶优化方向
5.1 路径规划算法
基础的三轴联动采用顺序运动:
code复制X轴定位 → Y轴定位 → Z轴下降 → 抓取 → Z轴上升
优化为复合运动可节省30%周期时间:
python复制def optimize_path(current, target):
# 计算各轴移动距离
dx = abs(target[0] - current[0])
dy = abs(target[1] - current[1])
dz = abs(target[2] - current[2])
# 根据轴速度比例计算同步时间
t_x = dx / v_x
t_y = dy / v_y
t_z = dz / v_z
# 调整各轴速度使运动时间一致
new_vx = dx / max(t_x, t_y, t_z)
new_vy = dy / max(t_x, t_y, t_z)
new_vz = dz / max(t_x, t_y, t_z)
return (new_vx, new_vy, new_vz)
5.2 异常处理机制
完善的状态监控应包括:
- 超时检测:每个动作步骤添加看门狗计时器
- 冲突检测:货位状态双重验证(光电传感器+软件状态)
- 急停恢复:记录断点位置,支持从中断点继续运行
在OB35循环中断组织块中实现:
pascal复制// 超时监控
IF #CurrentState <> #LastState THEN
#StateTimer(IN := FALSE);
#StateTimer(IN := TRUE, PT := T#30S);
ELSE
IF #StateTimer.Q THEN
"Emergency_Stop"();
#AlarmCode := 16#8001;
END_IF;
END_IF;
#LastState := #CurrentState;
这个项目最让我感慨的是,看似简单的码垛动作背后竟有如此多的细节需要考虑。第一次调试时我忽略了加速度参数,结果机械臂急启急停导致传送带上的货物全部倾倒。后来养成了个好习惯:所有运动控制参数都先用30%的额定值试运行,确认无碰撞风险后再逐步上调。