6 轴机器人取放 — CNC 上下料工站
行业: 精密零件加工 / 3C 装配 / 注塑取件 工位规模: 中型单机工站 (1 台 6 轴机器人 + 1 台 CNC + 1 条来料传送带 + 1 个成品托盘) 产能: 8 秒/件, 日产 ~10 000 件 (20 小时有效运行) 核心范围: 电气选型 / 机械装配 / IO 配置 / 机器人示教 / SCL 程序 / HMI 面板
1. 设备简介
该工站是典型的 CNC 加工中心自动上下料场景, 由 1 台 6 轴工业机器人替代人工, 完成从来料皮带取毛坯、放入 CNC 夹具、等待加工、取出成品、放入成品托盘的完整循环。
工站特点:
- 毛坯: 圆柱钢件 Φ50×80mm, 重 800g, 来料皮带末端单列到位
- 加工: 车铣复合中心, 单件加工约 3.8 秒 (含换刀)
- 机器人: 6 kg 负载 / 900 mm 臂展, 完成取料 → 上料 → 等待 → 取成品 → 码放
- 夹爪: 气动双作用平行夹爪 + 双磁簧到位传感
- 产能: 总节拍 8 s/件 (机器人 5 s + CNC 3 s 并行)
- 安全: 围栏 + 安全门锁 + 急停 + 安全继电器硬回路
设计目标:
- 节拍稳定在 8 秒/件, 允许波动 ±0.3 s
- 换型时间 < 10 分钟 (3 种毛坯尺寸配方)
- 72 小时连续烧机无异常停机
- 支持手机远程查看节拍/产量/报警
2. 项目模块组成
一套完整的工站涉及机械 + 电气 + 软件三大子系统, 三者并行设计、互相约束。
三层协作关系:
| 层 | 产出物 | 责任人 | 交付顺序 |
|---|---|---|---|
| 机械 | 装配图 / 气路图 / 夹爪选型 | 机械工程师 | 第 1~2 周 |
| 电气 | 原理图 / 柜体布置 / BOM | 电气工程师 | 第 2~3 周 (与机械并行) |
| 软件 | IDE 工程 / IO 映射 / 程序 / 面板 | 控制工程师 | 第 3~6 周 |
3. 机械装配架构
机械布局围绕机器人为中心, 皮带、CNC、托盘呈"半环"布置, 缩短机器人平均搬运路径。
机器人工作半径验证:
| 目标点 | 距底座 | 可达性 |
|---|---|---|
| 皮带末端取料点 P1 | 620 mm | OK (< 900 mm) |
| CNC 夹具上料点 P2 | 820 mm | OK (极限姿态) |
| CNC 出料点 P3 | 820 mm | OK |
| 托盘 8 个放料点 | 550 ~ 780 mm | OK |
气动回路: 阀岛 5 位 2 通 × 2 联, 分别控制夹爪开/合, 回气装消声器, 气源压力 0.5 MPa 稳压。
4. 程序架构 (OB / FB 调用)
Darra IDE 采用类 IEC 61131-3 的 OB + FB 组织, 运行时分为快速中断(1 ms)和主循环(2 ms)两级调度。
调度表:
| OB | 周期 | 优先级 | 功能 |
|---|---|---|---|
| OB30 | 1 ms (EtherCAT 同步) | 最高 | 伺服闭环、急停硬回路、传感器边沿 |
| OB1 | 2 ms | 高 | 状态机、步序调度、工艺对象调用 |
| OB2 | 100 ms | 中 | HMI 通讯、变量刷新 |
| OB3 | 1 s | 低 | 云端推送、日志归档 |
5. 硬件选型 BOM
选型原则: 国产优先, 接口统一 EtherCAT, 单点故障不影响安全。
| 序号 | 类别 | 品牌 / 型号 | 规格 | 数量 | 单价 (¥) | 小计 (¥) |
|---|---|---|---|---|---|---|
| 1 | 工控机 | 研华 UNO-2484G | i5-12500 / 16G / 256G SSD | 1 | 6 800 | 6 800 |
| 2 | 伺服驱动 | 汇川 SV660N-S4R0 | 400W CiA402 EtherCAT | 4 | 1 800 | 7 200 |
| 3 | 伺服驱动 | 汇川 SV660N-S7R6 | 750W CiA402 EtherCAT | 2 | 2 400 | 4 800 |
| 4 | 伺服电机 | 汇川 ISMH1-40B30CB | 400W 带抱闸 | 4 | 1 500 | 6 000 |
| 5 | 伺服电机 | 汇川 ISMH1-75B30CB | 750W 带抱闸 | 2 | 2 100 | 4 200 |
| 6 | IO 从站 | 汇川 AM600-1608ETN | 8DI / 8DO EtherCAT | 1 | 1 250 | 1 250 |
| 7 | IO 从站 | 汇川 AM600-0016ETP | 16DO EtherCAT | 1 | 980 | 980 |
| 8 | 机器人本体 | 埃斯顿 ER6-900 | 6 kg / 900 mm / 6 轴 | 1 | 42 000 | 42 000 |
| 9 | 气动夹爪 | SMC MHZ2-20D | 平行双作用 + 磁簧 | 1 | 1 400 | 1 400 |
| 10 | 电磁阀岛 | SMC VQC1100 | 5 位 2 通 | 1 | 1 600 | 1 600 |
| 11 | 接近开关 | 图尔克 | M8 PNP 3 线 | 6 | 120 | 720 |
| 12 | 安全继电器 | 施耐德 XPSAC5121 | 急停 + 安全门 | 1 | 1 800 | 1 800 |
| 13 | 触摸屏 | 威纶通 MT8103iE | 10.1″ | 1 | 2 200 | 2 200 |
| 14 | 皮带本体 | 定制 | 2m 平皮带 + 变频 | 1 | 8 500 | 8 500 |
| 15 | 电控柜 | 定制 | 800×600×250 含风扇 | 1 | 3 500 | 3 500 |
| 16 | 电缆 / 拖链 | — | 动力 + 编码器 + 信号 | 1 | 3 000 | 3 000 |
硬件合计: ¥95 950
品牌分布 (国产化率 > 85%):
- 国产: 汇川 (伺服/IO), 埃斯顿 (机器人), 研华 (工控机), 威纶通 (HMI)
- 进口: SMC (气动), 图尔克 (传感器), 施耐德 (安全继电器)
6. IO 模块配置
6.1 选择 IO 模块
Darra IDE 打开 IO 设备向导, 在 EtherCAT 从站树下依次添加设备:
[+] 网络 0 (EtherCAT Master eth0)
├─ [+] Slave_1 汇川 SV660N-400W (J1 关节)
├─ [+] Slave_2 汇川 SV660N-750W (J2 关节)
├─ [+] Slave_3 汇川 SV660N-750W (J3 关节)
├─ [+] Slave_4 汇川 SV660N-400W (J4 关节)
├─ [+] Slave_5 汇川 SV660N-400W (J5 关节)
├─ [+] Slave_6 汇川 SV660N-400W (J6 关节)
├─ [+] Slave_7 汇川 AM600-1608ETN (主 IO 模块 8DI/8DO)
└─ [+] Slave_8 汇川 AM600-0016ETP (阀岛驱动 16DO)
操作流程:
- 在 IDE 菜单栏点击 IO 设备 → 添加 EtherCAT 从站
- 扫描总线自动识别, 或从 ESI 库手动选型 (推荐扫描法, 一次全部识别)
- 对每个从站右键 → PDO 映射, 选择 CiA402 Profile (伺服) 或 Digital IO (IO)
- 分配 Instance 名 (如
axJ1/axJ2/io_main/io_valve), 此名称将直接用于 SCL 程序 - 设置同步周期 1 ms, DC 主参考 = Slave_1
6.2 IO 地址分配表
DI (数字输入) — AM600-1608ETN:
| 变量名 | 地址 | 物理位置 | 说明 |
|---|---|---|---|
| SEN_PartReady | %IX0.0 | 皮带末端 | 毛坯到位光电开关 |
| SEN_GripClosed | %IX0.1 | 夹爪本体 | 夹爪闭合磁簧 |
| SEN_GripOpen | %IX0.2 | 夹爪本体 | 夹爪张开磁簧 |
| SEN_CNCReady | %IX0.3 | CNC 出料口 | CNC 加工完成信号 |
| SEN_CNCDoor | %IX0.4 | CNC 安全门 | 安全门状态 |
| SEN_TrayOK | %IX0.5 | 成品托盘 | 当前放料点空闲 |
| SB_Start | %IX0.6 | 控制柜 | 启动按钮 |
| SB_Stop | %IX0.7 | 控制柜 | 停止按钮 |
| SB_EStop | %IX1.0 | 急停回路 | 急停 (常闭) |
| SW_ModeAuto | %IX1.1 | 模式选择 | 自动 / 手动 |
| SB_Reset | %IX1.2 | 控制柜 | 故障复位 |
DO (数字输出) — AM600-1608ETN + AM600-0016ETP:
| 变量名 | 地址 | 物理位置 | 说明 |
|---|---|---|---|
| SOL_GripClose | %QX0.0 | 阀岛 Y1 | 夹爪闭合电磁阀 |
| SOL_GripOpen | %QX0.1 | 阀岛 Y2 | 夹爪张开电磁阀 |
| MTR_Conveyor | %QX0.2 | 皮带变频 | 皮带使能 |
| SOL_CNCStart | %QX0.3 | CNC 输入 | CNC 启动脉冲 |
| HL_Run | %QX0.4 | 三色灯 | 绿灯 (运行) |
| HL_Alarm | %QX0.5 | 三色灯 | 红灯 (报警) + 蜂鸣 |
| HL_Standby | %QX0.6 | 三色灯 | 黄灯 (待机) |
| HL_ModeAuto | %QX0.7 | 模式指示 | — |
6.3 IO 用途分工
IO 按功能角色划分三个"阵营", 避免交叉影响:
| 阵营 | 作用 | 所属 IO |
|---|---|---|
| 机器人组 | 参与动作触发 / 抓取反馈 | SEN_PartReady, SEN_Grip*, SEN_CNCReady, SOL_Grip*, SOL_CNCStart |
| 主控组 | 上下料工站的启停 / 物流控制 | SB_Start, SB_Stop, SW_ModeAuto, SB_Reset, MTR_Conveyor, HL_* |
| 安全组 | 独立急停回路 (软件 + 硬件双层) | SB_EStop, SEN_CNCDoor, SAFE_LC (光幕) |
安全组信号同时接入安全继电器 (硬回路) 和 PLC (软回路), 硬回路断开伺服 STO 强制停止, 软回路触发状态机 Fault 状态。
6.4 数据绑定到机器人
Darra 工艺对象允许将特定 IO 直接绑定到机器人组, 机器人路径执行中可作为触发/反馈条件, 无需在 SCL 里手动检查。
IDE 机器人向导中右键 AXIS_GROUP_6DOF → 绑定 IO:
| 逻辑名 | 绑定 IO | 含义 | 用途 |
|---|---|---|---|
R.PartPresent | SEN_PartReady | 工件到位 | MC_WaitInput 条件 |
R.GripperClosed | SEN_GripClosed | 夹紧到位 | 抓取后确认 |
R.GripperOpen | SEN_GripOpen | 松开到位 | 放料后确认 |
R.CloseGripper | SOL_GripClose | 抓取动作 | MC_SetOutput |
R.OpenGripper | SOL_GripOpen | 松开动作 | MC_SetOutput |
R.ExtAlarm | SB_EStop (取反) | 外部安全 | MC_GroupStop 硬触发 |
绑定后, 机器人脚本可直接写 Gripper.Close(), 底层自动映射到对应阀岛输出 + 读取到位反馈, 程序从 200 多行状态机简化到 50 行。
7. 核心数据结构
// -------- 工件信息 --------
TYPE UDT_Part :
STRUCT
sBatch : STRING[32]; // 批次号
sSerial : STRING[16]; // 序列号
nRecipe : INT; // 配方号 (1=A/2=B/3=C)
rWeight : REAL; // 重量 g
tStartTime : DT; // 毛坯上料时刻
tCNCStart : DT; // CNC 加工开始
tCNCEnd : DT; // CNC 加工结束
tPlaceEnd : DT; // 成品放置完成
bQualified : BOOL; // 是否合格
nCycleMs : DINT; // 总耗时 ms
END_STRUCT
END_TYPE
// -------- 工站状态 --------
TYPE UDT_StationStatus :
STRUCT
eState : E_StationState; // Idle/Running/Paused/Fault/Maint
nCycleCount : DINT; // 已完成件数 (班)
nCycleCountDay : DINT; // 当日累计
nAlarmCode : DWORD; // 当前报警位图
rOEE : REAL; // 综合设备效率 %
rAvgCycleMs : REAL; // 平均节拍 ms
tStartShift : DT; // 班次开始时间
END_STRUCT
END_TYPE
// -------- 报警记录 --------
TYPE UDT_Alarm :
STRUCT
tStamp : DT;
nCode : INT;
sMessage : STRING[80];
eLevel : E_AlarmLevel; // Info/Warn/Fault
bAcked : BOOL;
END_STRUCT
END_TYPE
// -------- 机器人位姿 --------
TYPE UDT_Pose :
STRUCT
rX, rY, rZ, rA, rB, rC : REAL; // XYZ (mm) + RPY (deg)
END_STRUCT
END_TYPE
TYPE E_StationState :
(Idle := 0, Running := 1, Paused := 2, Fault := 3, Maint := 4);
END_TYPE
TYPE E_AlarmLevel : (Info := 0, Warn := 1, Fault := 2); END_TYPE
// -------- 全局 DB --------
VAR_GLOBAL
gPart : UDT_Part;
gStation : UDT_StationStatus;
gAlarms : ARRAY[0..31] OF UDT_Alarm;
// 机器人示教点 (现场示教填入)
gPickApp : UDT_Pose; // 取料接近点 (Z+50)
gPick : UDT_Pose; // 取料点
gCncApp : UDT_Pose; // CNC 上料接近点
gCncPlace : UDT_Pose; // CNC 放置点
gWait : UDT_Pose; // 等待位 (安全避开 CNC)
gTrayApp : UDT_Pose; // 托盘接近点
gTrayPlace : UDT_Pose; // 托盘放置点 (8 个)
END_VAR
8. 核心程序代码
8.1 OB30 — 1 ms 快速中断
PROGRAM OB30_FastTask
VAR_EXTERNAL
axG1 : AXIS_REF_GROUP; // 6 轴机器人组工艺对象
io_main : IO_AM600_1608;
io_valve : IO_AM600_0016;
END_VAR
VAR
bPartEdge : BOOL;
END_VAR
// 1. 工艺对象内部同步 6 轴位置/速度/力矩 (自动完成)
// 2. 边沿捕获: 来料到位上升沿, 精确到 1 ms
bPartEdge := R_EDGE(io_main.I[0].0);
// 3. 急停硬联锁 — 绕过状态机直达安全停止
IF NOT io_main.I[1].0 THEN
MC_GroupStop(Group := axG1, Deceleration := 8000);
io_main.Q[0].5 := TRUE; // 红灯点亮
END_IF;
END_PROGRAM
8.2 OB1 — 主循环状态机 (取放循环核心)
PROGRAM OB1_Main
VAR
sm : E_StationState := Idle;
nStep : INT := 0;
mcMove : MC_MoveL;
mcMoveJ : MC_MoveJ;
tonGrip : TON;
tonStable : TON;
rSpeed : REAL := 60.0; // HMI 可调 (%)
END_VAR
// ===== 安全 =====
IF NOT io_main.I[1].0 THEN sm := Fault; END_IF;
// ===== 启停 =====
IF io_main.I[0].6 AND sm = Idle THEN sm := Running; END_IF;
IF io_main.I[0].7 THEN sm := Idle; END_IF;
CASE sm OF
Idle:
io_main.Q[0].4 := FALSE; // 绿灯灭
nStep := 0;
Running:
io_main.Q[0].4 := TRUE;
CASE nStep OF
0: // 等待来料
io_main.Q[0].2 := TRUE; // 皮带运行
IF io_main.I[0].0 THEN
io_main.Q[0].2 := FALSE;
gPart.tStartTime := DT_NOW();
nStep := 10;
END_IF;
10: // 接近取料点
mcMoveJ(Group := axG1, Target := gPickApp, Velocity := rSpeed,
Execute := TRUE);
IF mcMoveJ.Done THEN nStep := 20; END_IF;
20: // 精细下降到取料点
mcMove(Group := axG1, Target := gPick, Velocity := 20.0,
Execute := TRUE);
IF mcMove.Done THEN
tonStable(IN := TRUE, PT := T#150ms);
IF tonStable.Q THEN nStep := 30; END_IF;
END_IF;
30: // 夹爪闭合
io_valve.Q[0].0 := TRUE;
io_valve.Q[0].1 := FALSE;
tonGrip(IN := TRUE, PT := T#400ms);
IF tonGrip.Q AND io_main.I[0].1 THEN nStep := 40; END_IF;
40: // 抬升 → 前往 CNC 接近点
mcMove(Group := axG1, Target := gPickApp, Velocity := 40.0,
Execute := TRUE);
IF mcMove.Done THEN nStep := 50; END_IF;
50: // 等 CNC 门开, 进入 CNC 上料
IF io_main.I[0].4 THEN // 安全门允许
mcMoveJ(Group := axG1, Target := gCncApp, Velocity := rSpeed,
Execute := TRUE);
IF mcMoveJ.Done THEN nStep := 60; END_IF;
END_IF;
60: // 精确放入 CNC 夹具
mcMove(Group := axG1, Target := gCncPlace, Velocity := 15.0,
Execute := TRUE);
IF mcMove.Done THEN nStep := 70; END_IF;
70: // 张开夹爪, 撤出
io_valve.Q[0].0 := FALSE;
io_valve.Q[0].1 := TRUE;
tonGrip(IN := TRUE, PT := T#300ms);
IF tonGrip.Q AND io_main.I[0].2 THEN
mcMove(Group := axG1, Target := gCncApp, Velocity := 30.0,
Execute := TRUE);
IF mcMove.Done THEN nStep := 80; END_IF;
END_IF;
80: // 触发 CNC 启动, 机器人到等待位
io_main.Q[0].3 := TRUE;
gPart.tCNCStart := DT_NOW();
mcMoveJ(Group := axG1, Target := gWait, Velocity := rSpeed,
Execute := TRUE);
IF mcMoveJ.Done THEN nStep := 90; END_IF;
90: // 等加工完成
io_main.Q[0].3 := FALSE;
IF io_main.I[0].3 THEN
gPart.tCNCEnd := DT_NOW();
nStep := 100;
END_IF;
100..130: // 对称的取成品 → 码放托盘流程 (略)
// ...
200: // 周期结束, 统计
gStation.nCycleCount := gStation.nCycleCount + 1;
gPart.nCycleMs := DT_DIFF_MS(DT_NOW(), gPart.tStartTime);
gStation.rAvgCycleMs := (gStation.rAvgCycleMs * 0.9)
+ (gPart.nCycleMs * 0.1);
nStep := 0;
END_CASE;
Fault:
io_main.Q[0].4 := FALSE;
io_main.Q[0].5 := TRUE;
IF io_main.I[1].2 AND io_main.I[1].0 THEN
sm := Idle;
io_main.Q[0].5 := FALSE;
END_IF;
END_CASE;
END_PROGRAM
8.3 FB_Alarm — 报警管理
FUNCTION_BLOCK FB_Alarm
VAR_INPUT
nCode : INT;
sMsg : STRING[80];
eLevel : E_AlarmLevel;
bTrigger : BOOL;
END_VAR
VAR_OUTPUT
bActive : BOOL;
END_VAR
VAR
rtrig : R_TRIG;
END_VAR
rtrig(CLK := bTrigger);
IF rtrig.Q THEN
// 写入环形数组
FOR i := 31 TO 1 BY -1 DO
gAlarms[i] := gAlarms[i-1];
END_FOR;
gAlarms[0].tStamp := DT_NOW();
gAlarms[0].nCode := nCode;
gAlarms[0].sMessage := sMsg;
gAlarms[0].eLevel := eLevel;
gAlarms[0].bAcked := FALSE;
bActive := TRUE;
END_IF;
END_FUNCTION_BLOCK
9. 运行与调试
9.1 上电步骤
- 主电源合闸, 工控机开机进入 Darra Panel (运行时)
- 工控机自检 EtherCAT 总线: 8 个从站 全部 OP 状态
- 扭动安全钥匙 → 解除急停 → 伺服使能 (抱闸自动释放)
- 按 复位 按钮 → 状态机进入 Idle
- 选择 自动模式 → 按 启动 → 机器人自动回原点 → 进入 Running
9.2 示教流程
首次上电或换型时需要示教 6 个关键点:
| 点名 | 示教方法 | 注意 |
|---|---|---|
| gPickApp | 皮带末端正上方 +50 mm | 用手轮轴空下降 |
| gPick | 抓取实际点 | 夹爪爪尖接触毛坯上端 |
| gCncApp | CNC 门内 200 mm 安全位 | 确保不碰撞门 |
| gCncPlace | CNC 夹具定位块 | 干涉检测后示教 |
| gWait | 不阻挡 CNC 加工的安全位 | Z 高 +200 mm |
| gTrayPlace | 托盘第一格 (其余 7 格由偏移计算) | — |
9.3 常见问题排查
| 现象 | 可能原因 | 处理 |
|---|---|---|
| 机器人到位后等待, 不抓取 | 夹爪磁簧信号误判 | 检查 %IX0.1 到位延时 |
| CNC 启动信号无响应 | CNC 输入接线 / 极性 | 对 CNC 侧用万用表 |
| 节拍波动大 | 网卡非独占 / CPU 睡眠 | 关闭 C-State, 绑核 |
| 偶发 EtherCAT 掉线 | 线缆质量 / 接地 | 更换屏蔽电缆 |
10. Darra 功能对照表
| 工站需求 | 实现方式 | IDE 配置位置 |
|---|---|---|
| 6 轴正逆解 | 工艺对象 AXIS_REF_GROUP | 机器人向导 |
| 1 ms 伺服周期 | EtherCAT DC 同步 | 主站属性 |
| 路径插补 | MC_MoveL / MC_MoveJ | 程序调用 |
| 平滑加减速 | Jerk-Limited Profile | 工艺对象参数 |
| 配方切换 | UDT_Recipe 全局 DB | 数据结构编辑器 |
| OEE 统计 | FB_Statistics | 程序模块 |
| HMI 面板 | Darra Panel 拖拽设计器 | 面板工程 |
| 云端看板 | DarraCloud 一键对接 | 项目属性 |
| 报警归档 | 内置 SQLite 环形写入 | 无需额外开发 |
11. 项目总结
本工站以机器人为中心进行机电软一体化设计, 1 台工控机 + 1 套 Darra PLC 软件完成原本需要 PLC、机器人控制器、HMI、远程网关 4 套设备才能覆盖的功能。
关键成果:
- 节拍稳定 8.0 ± 0.2 s, 72 h 烧机无掉线
- 硬件国产化率 > 85%, BOM 约 ¥9.6w, 交付周期 6 周
- IO 绑定机器人工艺对象后, 取放循环代码从 200 余行缩减到 50 行
- HMI 面板、云端看板、报警归档零额外开发
可复用模板: 本案例 UDT 结构 / 报警 FB / OB30 快速中断 / 机器人 IO 绑定方式, 均可直接迁移到其他 6 轴单机工站 (CNC/注塑/压铸上下料、3C 螺丝锁付等)。