跳到主要内容

CNC 数据采集与监控 — 车间 MES 数采中枢

行业: 机加工车间 / 精密模具 / 汽车零部件 工位规模: 中型车间 32 台 CNC 集中数采 + 实时监控 + MES 上报 数据规模: 32 台 × 20 点位 × 500 ms ≈ 1 280 点/秒 核心范围: 多协议采集 / 时序数据库 / OEE 实时 / MES 对接 / 刀具寿命 / 云端看板


1. 设备简介

本工站作为车间级的数采中枢, 一台工控机同时接入 32 台不同品牌的 CNC, 按协议循环采集关键工艺指标, 本地落地时序数据库, 并向 MES / Grafana / DarraCloud 分发。

工站参数:

  • 设备数: 32 台 CNC (发那科 31i × 12, 三菱 M80 × 8, 海德汉 TNC640 × 4, 广数 GSK × 8)
  • 采集点: 主轴 RPM / 负载 / 进给率 / 刀号 / 程序号 / 状态 / 累计件数等 20 点
  • 高频周期: 500 ms (RPM / 负载)
  • 低频周期: 2 s (程序号 / 刀号)
  • 存储: 本地 SQLite + 时序分区压缩, 保留 180 天
  • 分发: OPC UA Server / HTTP API / MQTT / DarraCloud

设计目标:

  1. 32 台全部稳定在线, 单台断线不影响其他
  2. OEE 指标刷新 ≤ 5 s
  3. 刀具寿命 80 % / 100 % 两级告警
  4. 拔网线可断网离线缓存, 恢复后补传 MES

2. 项目模块组成

本案例偏向纯软件 + 弱电, 机械子系统只是既有 CNC, 电气子系统只涉及机柜/交换机/UPS, 软件子系统是主体。

三层责任:

产出关键点
既有 CNCIP 地址清单 / 协议开通CNC 侧开启以太网口与协议服务
电气机柜 / 交换机 / 网线工业级屏蔽超五类, 全车间网段隔离
软件协议库 / 数据库 / 看板纯软件实现, 无需数采网关

3. 机械装配架构

本案例不涉及 机器人 / 伺服 / 传送带, 仅为机柜与网络装配, 物理拓扑如下:

布线规范:

  • 全车间超五类屏蔽网线, 走桥架, 避开变频器动力线 ≥ 30 cm
  • 交换机 4 × 10G 上联预留, 32 端口分给 CNC
  • UPS 3 kVA 支撑工控机 + 交换机 30 分钟
  • 4G 路由作出站备份, 宽带断线时自动切换

4. 程序架构

Darra 的 OB 调度非常适合数采: 每个协议一个独立 OB, 互不阻塞, 某台 CNC 断线仅影响对应协议 OB 的一个 slot。

调度表:

OB周期功能
OB10500 msFOCAS 采集 (Fanuc 12 台)
OB11500 msOPC UA Client (海德汉 4 台)
OB12500 msModbus TCP (广数 8 台)
OB202 sMTConnect HTTP (三菱 8 台)
OB212 s低频点 (程序号 / 刀号)
OB11 sOEE 计算
OB3010 s批量落库
OB3110 sMES 推送
OB3230 s云端同步

5. 硬件选型 BOM

序号类别品牌 / 型号规格数量单价 (¥)小计 (¥)
1工控机研华 UNO-2484Gi7-12700 / 32G / 2TB NVMe112 00012 000
2工业交换机华为 S5720-52X-PWR-LI48 口千兆 + 4 × 10G18 5008 500
3KVM 切换器普联2 路1380380
4UPS山特 C3KS3 kVA 在线式14 8004 800
524″ 值班大屏AOC显示总览看板21 2002 400
64G 路由器华三 MSR810双 SIM, 备用出站12 2002 200
7工业超五类屏蔽网线全车间布线12 5002 500
8机柜 + PDU定制22U 带散热风扇13 2003 200

硬件合计: ¥35 980

国产化率 ≈ 95% (工控机/交换机/UPS/4G/机柜均国产)

无需数采网关、无需额外协议转换器, 原 CNC 以太网口直接接入交换机即可。


6. IO 模块配置

6.1 选择 IO 模块 (逻辑从站)

本案例不使用物理 DI/DO, "IO" 指向软件侧逻辑从站 (每台 CNC 视为一个通讯从站)。IDE 采用"通讯从站向导"而非 EtherCAT 从站。

[+] 通讯网络 (车间 TCP)
├─ [+] Fanuc 分组 (FOCAS)
│ ├─ CNC-01 ~ CNC-12 192.168.10.11 ~ .22
├─ [+] 三菱 分组 (MTConnect)
│ ├─ CNC-13 ~ CNC-20 192.168.10.23 ~ .30
├─ [+] 海德汉 分组 (OPC UA)
│ ├─ CNC-21 ~ CNC-24 192.168.10.31 ~ .34
└─ [+] 广数 分组 (Modbus TCP)
└─ CNC-25 ~ CNC-32 192.168.10.35 ~ .42

配置流程 (IDE 通讯从站向导):

  1. 新建通讯项目添加分组 → 选择协议 (FOCAS / MTConnect / OPC UA / Modbus TCP)
  2. 分组内 添加设备 → 填写 IP / 端口 / 超时 / 重连策略
  3. 导入 采集点模板 (IDE 自带各协议常用点 CSV, 可导入)
  4. 变量映射: 每台设备实例化一个 UDT_CncData, 名称形如 cnc01 / cnc02 / ... / cnc32
  5. 协议级别独立 OB 运行, 单台断线不阻塞其他

6.2 IO 地址分配表

本案例以 UDT 变量替代物理地址, 每台 CNC 有一个实例:

变量名协议CNC 厂商点位说明
cnc01.rSpindleRPMFOCAS 9033CNC_RDACTF实际主轴转速
cnc01.rSpindleLoadFOCAS 9068CNC_RDSVLOAD伺服负载
cnc01.rFeedRateFOCAS 9022CNC_RDSPEED进给速度
cnc01.nToolNoFOCAS 9045CNC_RDTOFSR刀具号
cnc01.sProgNameFOCAS 9003CNC_RDPRGNUMNC 程序号
cnc01.eMachStateFOCAS 9100CNC_STATINFO运行状态
cnc01.nAlarmCodeFOCAS 9071CNC_RDALMSTAT报警号
cnc01.nPartsTotalFOCAS 9017CNC_RDPARAM累计件数
cnc13.rSpindleRPMMTConnect//Rotary[@name='S']/VelocityXML XPath
cnc21.rSpindleRPMOPC UAns=2;s=Axes.S.ActualVelNodeId
cnc25.rSpindleRPMModbus40001保持寄存器
cnc25.nAlarmCodeModbus40100报警区

6.3 IO 用途分工

数采场景没有物理机器人和安全组, 按数据流向分层:

阵营归属含义
采集组所有 cnc01~32 高低频点由各协议 OB 读取
计算组OEE / 刀具寿命 / AI 异常OB1_OEE 处理
分发组MES / Grafana / DarraCloud 接口OB31/32 向外推送

6.4 数据绑定到机器人

本案例无机器人, 该章节对应为"数据绑定到 MES/OPC UA Server":

逻辑名绑定目标协议
UaServer.Cnc01.Spindle.RPMcnc01.rSpindleRPMOPC UA Node
UaServer.Cnc01.Tool.Nocnc01.nToolNoOPC UA Node
Grafana.metric.spindle_rpm{id=01}cnc01.rSpindleRPMHTTP JSON
Mes.Equipment[01].OEEcnc01.rOEEHTTP POST
MQTT topic shop/cnc01/statecnc01.eMachStateMQTT Publish

IDE OPC UA Server 向导 勾选要发布的变量即可, 无需编码。


7. 核心数据结构

// -------- 单台 CNC 采集数据 --------
TYPE UDT_CncData :
STRUCT
sDevId : STRING[16]; // CNC-01 ~ CNC-32
eBrand : E_CncBrand;
sIp : STRING[16];
eProto : E_CncProtocol;

// 高频 500ms
rSpindleRPM : REAL;
rSpindleLoad : REAL;
rFeedRate : REAL;
rFeedOverride : REAL;

// 低频 2s
nToolNo : INT;
rToolUsedMin : REAL;
rToolLifeMin : REAL;
sProgName : STRING[32];
eMachState : E_MachState;

// 累计
nPartsTotal : DINT;
nPartsGood : DINT;
nAlarmCode : DWORD;
sAlarmText : STRING[80];

// OEE 实时
tRunTimeDay : TIME;
tPlanTimeDay : TIME := T#16h;
rAvailability : REAL;
rPerformance : REAL;
rQuality : REAL;
rOEE : REAL;

// 通讯诊断
bOnline : BOOL;
nErrorCnt : DINT;
tLastOk : DT;
END_STRUCT
END_TYPE

TYPE E_CncBrand : (Fanuc, Mitsubishi, Heidenhain, Gsk); END_TYPE
TYPE E_CncProtocol : (FOCAS, MTConnect, OPCUA, ModbusTcp); END_TYPE
TYPE E_MachState : (Stop := 0, Run := 1, Pause := 2, Alarm := 3); END_TYPE

// -------- 车间总览 --------
TYPE UDT_ShopSummary :
STRUCT
nOnline : INT; // 在线台数
nRunning : INT; // 运行中
nAlarm : INT; // 报警中
rShopOEE : REAL; // 全车间 OEE
nPartsDayTotal : DINT; // 全车间当日产量
END_STRUCT
END_TYPE

VAR_GLOBAL
cnc : ARRAY[1..32] OF UDT_CncData;
shop : UDT_ShopSummary;
END_VAR

8. 核心程序代码

8.1 OB10 — FOCAS 采集 (Fanuc 12 台)

PROGRAM OB10_Fanuc
VAR
i : INT;
hLib : DWORD;
rc : DINT;
END_VAR

FOR i := 1 TO 12 DO
IF cnc[i].eProto <> FOCAS THEN CONTINUE; END_IF;

rc := FOCAS_Connect(cnc[i].sIp, 8193, ADR(hLib));
IF rc <> 0 THEN
cnc[i].bOnline := FALSE;
cnc[i].nErrorCnt := cnc[i].nErrorCnt + 1;
CONTINUE;
END_IF;

// 500 ms 高频点
FOCAS_ReadSpindle(hLib, ADR(cnc[i].rSpindleRPM));
FOCAS_ReadServoLoad(hLib, 0, ADR(cnc[i].rSpindleLoad));
FOCAS_ReadFeed(hLib, ADR(cnc[i].rFeedRate));
FOCAS_ReadFeedOvr(hLib, ADR(cnc[i].rFeedOverride));
FOCAS_ReadStatus(hLib, ADR(cnc[i].eMachState));
FOCAS_ReadAlarm(hLib, ADR(cnc[i].nAlarmCode), ADR(cnc[i].sAlarmText));

cnc[i].bOnline := TRUE;
cnc[i].tLastOk := DT_NOW();
FOCAS_Close(hLib);
END_FOR;

END_PROGRAM

8.2 OB1 — OEE 计算

PROGRAM OB1_OEE
VAR
i : INT;
END_VAR

shop.nOnline := 0;
shop.nRunning := 0;
shop.nAlarm := 0;
shop.rShopOEE := 0.0;
shop.nPartsDayTotal := 0;

FOR i := 1 TO 32 DO
IF NOT cnc[i].bOnline THEN CONTINUE; END_IF;
shop.nOnline := shop.nOnline + 1;

// 可用率 = 运行时间 / 计划时间
IF cnc[i].tPlanTimeDay > T#0s THEN
cnc[i].rAvailability := TIME_TO_REAL(cnc[i].tRunTimeDay)
/ TIME_TO_REAL(cnc[i].tPlanTimeDay);
END_IF;

// 性能率 = 实际件数 / 理论件数 (由 MES 反馈理论节拍)
IF cnc[i].nPartsTotal > 0 THEN
cnc[i].rPerformance := MIN(1.0, cnc[i].nPartsGood * 1.0
/ MAX(1, cnc[i].nPartsTotal));
END_IF;

// 合格率 = 合格 / 总数
IF cnc[i].nPartsTotal > 0 THEN
cnc[i].rQuality := cnc[i].nPartsGood * 1.0 / cnc[i].nPartsTotal;
END_IF;

cnc[i].rOEE := cnc[i].rAvailability
* cnc[i].rPerformance
* cnc[i].rQuality;

// 刀具寿命告警
IF cnc[i].rToolUsedMin / cnc[i].rToolLifeMin >= 1.0 THEN
FB_RaiseAlarm(i, 801, 'Tool life EXPIRED, force change', Fault);
ELSIF cnc[i].rToolUsedMin / cnc[i].rToolLifeMin >= 0.8 THEN
FB_RaiseAlarm(i, 800, 'Tool life 80%, prepare change', Warn);
END_IF;

// 状态统计
IF cnc[i].eMachState = Run THEN shop.nRunning := shop.nRunning + 1; END_IF;
IF cnc[i].eMachState = Alarm THEN shop.nAlarm := shop.nAlarm + 1; END_IF;
shop.rShopOEE := shop.rShopOEE + cnc[i].rOEE;
shop.nPartsDayTotal := shop.nPartsDayTotal + cnc[i].nPartsTotal;
END_FOR;

IF shop.nOnline > 0 THEN
shop.rShopOEE := shop.rShopOEE / shop.nOnline;
END_IF;

END_PROGRAM

8.3 OB30 — 批量落库 (10 s)

PROGRAM OB30_DB
VAR
i : INT;
stmt : SQLITE_Stmt;
END_VAR

stmt.Prepare(
'INSERT INTO cnc_timeseries(dev,ts,rpm,load,feed,state,parts) ' ||
'VALUES(?,?,?,?,?,?,?)');

FOR i := 1 TO 32 DO
IF NOT cnc[i].bOnline THEN CONTINUE; END_IF;
stmt.Bind(1, cnc[i].sDevId);
stmt.Bind(2, DT_NOW());
stmt.Bind(3, cnc[i].rSpindleRPM);
stmt.Bind(4, cnc[i].rSpindleLoad);
stmt.Bind(5, cnc[i].rFeedRate);
stmt.Bind(6, cnc[i].eMachState);
stmt.Bind(7, cnc[i].nPartsTotal);
stmt.Execute();
stmt.Reset();
END_FOR;

stmt.Close();

END_PROGRAM

8.4 OB31 — MES 推送 (带离线缓存)

PROGRAM OB31_Mes
VAR
i : INT;
sJson : STRING[1024];
http : HTTP_Client;
bOk : BOOL;
END_VAR

FOR i := 1 TO 32 DO
IF NOT cnc[i].bOnline THEN CONTINUE; END_IF;

sJson := JSON_Build(cnc[i]); // 内置序列化
bOk := http.Post(
'https://mes.local/api/equip/state',
sJson,
timeout := T#3s);

IF NOT bOk THEN
// 离线缓存到本地 SQLite, 下个周期重试
DB_InsertPending(cnc[i].sDevId, sJson);
END_IF;
END_FOR;

// 补传离线积压
FB_ReplayPending(limit := 500);

END_PROGRAM

9. 运行与调试

9.1 上电步骤

  1. 合闸 UPS → 工控机 → 启动 Darra Panel
  2. 执行 通讯诊断: 32 台 CNC ping 全通
  3. 逐台验证协议握手 (IDE 通讯监视器)
  4. 观察 shop.nOnline 达到 32
  5. 查看 Grafana 看板, 主轴 RPM 折线持续刷新

9.2 协议调通顺序

建议分批调通, 避免一次全上排查困难:

批次协议台数备注
1Modbus TCP (广数)8最简单, 先通
2OPC UA (海德汉)4需导入 CNC Nodeset
3FOCAS (发那科)12需 CNC 侧开通 HSSB/Ethernet
4MTConnect (三菱)8需 CNC Agent 先启动

9.3 OPC UA Server 发布

IDE → OPC UA Server 向导 → 勾选要对外发布的变量:

Root
├── Shop
│ ├── OnlineCount (UInt16)
│ ├── RunningCount (UInt16)
│ └── ShopOEE (Double)
└── Machines
├── CNC-01
│ ├── SpindleRPM (Double)
│ ├── ToolNo (Int16)
│ └── OEE (Double)
├── CNC-02
│ └── ...

MES 使用任意 OPC UA Client 订阅即可。

9.4 告警规则

告警条件级别推送
通讯断线tLastOk 超 30 sWarn值班室大屏
CNC 报警nAlarmCode <> 0Fault微信 + 大屏
刀具 80%rToolUsed/rToolLife ≥ 0.8Warn班组长
刀具 100%≥ 1.0Fault强制停机
OEE < 40%持续 30 分钟Info工艺师邮件

9.5 常见问题

现象原因处理
FOCAS 断线频繁CNC HSSB 超时连接保活 10 s
MTConnect XPath 错CNC 版本差异导入对应 XSD
落库延时 > 1 sSQLite WAL 关了启用 WAL
Grafana 掉点HTTP 接口压力改 MQTT/InfluxDB

10. Darra 功能对照表

工站需求实现方式IDE 位置
多协议采集内置 FOCAS / MTConnect / OPC UA / Modbus / MQTT通讯向导
时序数据库内置 SQLite + WAL + 分区项目属性
OEE 计算FB_Availability/Performance/Quality程序模块
刀具寿命管理UDT 字段 + FB_RaiseAlarm程序模块
OPC UA Server勾选发布变量UA Server 向导
Grafana 对接HTTP 接口内置通讯向导
离线缓存DB_InsertPending + FB_ReplayPending库函数
云端看板DarraCloud 一键项目属性

11. 项目总结

数采中枢场景最能体现 Darra 作为"一体化软 PLC"的价值: 以 1 台工控机 + 1 套软件替代传统方案的 "32 个数采网关 + SCADA + 数据库 + OPC Server + MES 适配器", 硬件成本降低约一个数量级。

成果:

  • 32 台全在线, 单台断线仅影响对应 slot, 整体不挂
  • OEE 刷新 1 s, 数据库写入 800 条/秒
  • 180 天历史占用约 45 GB, 2 TB SSD 可容 8 年
  • 全部国产硬件, 机柜合计 ¥3.6 w
  • MES / Grafana / 云端三条分发路径并行, 任一中断不影响其他

可复用: UDT_CncData / UDT_ShopSummary / 多协议 OB 模板 / OEE 计算 FB / OPC UA Server 发布方式, 可直接迁移到注塑机、压铸机、冲压机、立式加工中心等任意设备数采场景, 替换协议库即可。