使用IOTGW-AIC100实现工业Modbus设备数据采集与MES对接

应用场景

制造业数字化转型中,设备数据采集是关键环节。传统方案依赖 PLC 数据直接上传或人工抄表,存在改造成本高、数据孤岛等问题。本文介绍如何使用 IOTGW-AIC100 物联网网关,零改造 采集工厂现有 Modbus 设备数据,并上报到 MES 系统。

典型工业场景

行业设备类型采集参数
注塑注塑机温度、压力、周期时间、产量计数
冲压冲床冲压次数、模具开合、故障状态
包装包装机运行速度、包装数量、废品率
焊接焊机电流、电压、焊点计数
空压空压机压力、流量、功率、运行时间

系统架构

┌────────────────────────────────────────────────────────────┐
│                        MES系统                              │
│   ┌──────────┐  ┌──────────┐  ┌──────────┐               │
│   │ 实时看板  │  │ 报表分析  │  │ 设备台账  │               │
│   └────┬─────┘  └────┬─────┘  └────┬─────┘               │
│        │              │              │                      │
│   ┌────┴──────────────┴──────────────┴─────┐               │
│   │              HTTP / MQTT API              │               │
│   └────┬───────────────────────────────────┘               │
└────────┼───────────────────────────────────────────────────┘
         │ HTTP POST / MQTT
┌────────┼───────────────────────────────────────────────────┐
│ 边缘层 │  IOTGW-AIC100                                     │
│        │  ┌──────────────────────────────────────┐        │
│        │  │       NodeRed 数据流                  │        │
│        │  │  采集→清洗→聚合→上报                 │        │
│        │  └──────────────────────────────────────┘        │
│        │           │                                       │
│        │    ┌──────┴───────┐                            │
│        │    │ 本地存储缓存  │ ← 断网时数据不丢失          │
│        │    └──────────────┘                            │
│        └────────────┬─────────────────────┘               │
└─────────────────────┼───────────────────────────────────────┘
                      │ RS485 / RS232 (Modbus-RTU)
┌─────────────────────┼───────────────────────────────────────┐
│ 设备层 │   ┌─────────┼─────────┐                           │
│        │   ▼         ▼         ▼                           │
│   ┌────┴───┐  ┌────┴───┐  ┌────┴───┐                       │
│   │ 注塑机  │  │ 冲床   │  │ 电表   │                       │
│   │ PLC    │  │ PLC   │  │ Modbus │                       │
│   └─────────┘  └─────────┘  └─────────┘                       │
└─────────────────────────────────────────────────────────────┘

硬件准备

设备型号数量说明
物联网网关IOTGW-AIC1001台边缘计算核心
RS485转接线3.81mm端子若干设备连接
网线Cat5e1条连接交换机
电源DC 12V 2A1个网关供电

Modbus设备连接

接线方式

Modbus-RTU 采用总线拓扑接线:

                    ┌─────────────┐
                    │  IOTGW-AIC  │
    RS485-A ◄───────┤ A           │
    RS485-B ◄───────┤ B           │
                    │ GND         │◄── 屏蔽层接地
                    └──────┬──────┘

              ┌────────────┼────────────┐
              │            │            │
           设备1         设备2         设备3

终端电阻

在总线两端(网关和最远设备)并联120Ω终端电阻。

线缆选型

  • 距离 < 100m:使用普通双绞线
  • 距离 100-500m:使用带屏蔽双绞线
  • 距离 > 500m:增加RS485中继器

NodeRed数据采集配置

步骤1:读取Modbus寄存器

拖入「modbus read」节点:

注塑机PLC(假设使用Modbus TCP):

名称:注塑机数据
类型:Modbus-IP
主机:192.168.1.101:502
单元ID:1
功能码:Read Holding Registers (3)
地址:0
数量:20
轮询间隔:5秒

电表(Modbus RTU通过RS485):

名称:电表数据
类型:Serial RS485
串口:/dev/ttyUSB0
波特率:9600
数据位:8
停止位:1
校验:无
单元ID:2
功能码:Read Holding Registers (3)
地址:0
数量:10
轮询间隔:60秒

步骤2:数据解析

拖入「function」节点解析注塑机数据:

// 解析注塑机关键参数
var regs = msg.payload;

return {
    device_id: "injection_01",
    timestamp: new Date().toISOString(),
    parameters: {
        mold_temp_1: regs[0] / 10,      // 模具温度1 (0.1°C)
        mold_temp_2: regs[1] / 10,      // 模具温度2
        melt_temp: regs[2] / 10,        // 熔胶温度
        injection_pressure: regs[3],    // 注射压力
        cycle_time: regs[4],           // 周期时间 (0.1s)
        shot_count: regs[5],           // 射出次数
        status: regs[6] === 1 ? "running" : "stopped",
        alarm: regs[7]                 // 报警代码
    }
};

步骤3:数据清洗与聚合

拖入「function」节点进行边缘计算:

// 计算OEE相关指标
var params = msg.parameters;

// 计算设备综合效率
var ideal_cycle_time = 15; // 秒
var actual_cycle_time = params.cycle_time / 10;
var cycle_efficiency = (ideal_cycle_time / actual_cycle_time) * 100;

// 计算可用率
var status_value = params.status === "running" ? 1 : 0;

return {
    device_id: msg.device_id,
    timestamp: msg.timestamp,
    metrics: {
        cycle_efficiency: Math.min(100, cycle_efficiency).toFixed(2),
        availability: status_value * 100,
        shot_count: params.shot_count,
        mold_temp_avg: ((params.mold_temp_1 + params.mold_temp_2) / 2).toFixed(1)
    }
};

步骤4:本地缓存(断网保护)

拖入「file」节点实现本地存储:

// 本地JSON文件存储
var fs = require('fs');
var filename = '/data/cache/' + msg.device_id + '_cache.json';

var data = {
    device_id: msg.device_id,
    last_update: msg.timestamp,
    buffer: []
};

try {
    var existing = fs.readFileSync(filename, 'utf8');
    data = JSON.parse(existing);
} catch(e) {}

// 添加当前数据到缓冲区
data.buffer.push(msg);

// 保留最近100条记录
if (data.buffer.length > 100) {
    data.buffer.shift();
}

fs.writeFileSync(filename, JSON.stringify(data, null, 2));
return msg;

步骤5:上报MES系统

HTTP POST方式

拖入「http request」节点:

方法:POST
URL:http://mes.company.com/api/v1/device/data
Headers:
  Content-Type: application/json
  Authorization: Bearer {{credentials.token}}

MQTT方式

拖入「mqtt out」节点:

服务器:mqtt.company.com:1883
主题:mes/devices/{{device_id}}/telemetry
QoS:1
保留:false

MES数据接收示例

网关上报的数据格式(HTTP JSON):

{
    "device_id": "injection_01",
    "timestamp": "2026-04-16T10:30:00.000Z",
    "metrics": {
        "cycle_efficiency": "92.5",
        "availability": "100",
        "shot_count": 15420,
        "mold_temp_avg": "225.5"
    },
    "raw_data": {
        "mold_temp_1": 225.0,
        "mold_temp_2": 226.0,
        "melt_temp": 250.0,
        "injection_pressure": 85,
        "cycle_time": 150,
        "status": "running"
    }
}

告警配置

设备异常告警

// 在function节点中添加告警判断
var params = msg.parameters;

var alarms = [];

if (params.mold_temp_1 > 260) {
    alarms.push({
        level: "critical",
        code: "TEMP_OVER_HIGH",
        message: "模具温度1过高",
        value: params.mold_temp_1
    });
}

if (params.alarm !== 0) {
    alarms.push({
        level: "warning",
        code: "DEVICE_ALARM",
        message: "设备报警",
        value: params.alarm
    });
}

if (alarms.length > 0) {
    return [{
        payload: { device_id: msg.device_id, alarms: alarms }
    }];
}

告警通知

拖入「email」或「钉钉Webhook」节点:

// 钉钉告警消息格式
var dingtalk = {
    msgtype: "text",
    text: {
        content: "【注塑机告警】\n设备:" + msg.payload.device_id + "\n告警:" + msg.payload.alarms[0].message
    }
};
return { payload: JSON.stringify(dingtalk) };

部署与验证

本地调试

  1. 部署NodeRed流程
  2. 观察Debug面板输出
  3. 用万用表测量RS485总线电压(正常约2-5V)

MES对接验证

调用MES API测试数据接收:

curl -X POST http://mes.company.com/api/v1/device/data \
  -H "Content-Type: application/json" \
  -d '{
    "device_id": "test_device",
    "timestamp": "2026-04-16T10:00:00Z",
    "metrics": { "test_value": 123 }
  }'

查看数据上报日志

ssh root@192.168.88.1
tail -f /var/log/node-red/messages.log

常见问题

问题原因解决方案
读取数据全为0寄存器地址偏移确认设备Modbus地址表
通信超时波特率/校验不匹配检查设备RS485参数
偶发丢数据总线干扰屏蔽接地,加终端电阻
MES接收失败Token过期配置自动刷新Token

总结

使用IOTGW-AIC100实现工业数据采集的优势:

  • 免PLC编程:直接读取Modbus寄存器,无需PLC配合
  • 边缘计算:本地数据聚合、清洗,减少云端压力
  • 断网保护:本地缓存,网络恢复后补传
  • 灵活上报:HTTP/MQTT多种协议对接MES
  • 远程运维:ZeroTier组网,浏览器远程配置