You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

如何在Node-RED中高效读取西门子PLC的结构化数据(区域与加热器)

高效读取西门子PLC数组/Struct到Node-RED的方案

核心思路

node-red-contrib-s7支持一次性读取连续的PLC数据块字节,你只需要确认数组的起始地址和总字节长度,读取后用Node-RED函数节点将原始Buffer解析为结构化JSON即可,无需为每个变量单独创建节点。

步骤1:确认PLC中数组的内存布局

首先在TIA Portal中打开对应的DB块,查看zones数组的起始地址和每个区域struct的总字节数

  • 比如zones数组起始于DB1.DBB0,每个区域struct占12字节,数组有5个元素,那么总读取长度就是5*12=60字节。
  • 注意西门子PLC的struct会自动做字节对齐,务必以TIA Portal中显示的实际字节偏移为准(比如布尔类型会占1字节,实数占4字节,不足对齐字节的会填充空白)。

步骤2:配置node-red-contrib-s7读取节点

  1. 添加一个s7 in节点,配置好PLC的连接参数(IP、机架号、槽号等)。
  2. 在节点的"Address"字段填写数组的起始地址和长度:
    • 格式示例:DB1,DBB0,60(表示读取DB1从字节0开始的60个字节)。
    • 如果是按字读取,也可以用DB1,DBW0,30(30个字=60字节)。

步骤3:用函数节点解析Buffer为结构化JSON

s7 in节点的输出连接到一个function节点,编写解析代码,根据你PLC中struct的结构提取数据。以下是示例代码(需根据实际struct结构调整):

// 读取到的原始字节数据存在msg.payload中
const rawBuffer = msg.payload;
const zones = [];

// 配置参数:根据你的PLC struct调整
const zoneByteSize = 12; // 单个区域struct的总字节数
const heaterCountPerZone = 2; // 每个区域的加热器数量
const tempByteLength = 4; // 温度(实数)占4字节
const statusByteOffset = 4; // 加热器状态在区域内的字节偏移

// 循环解析每个区域
for (let zoneIdx = 0; zoneIdx < rawBuffer.length / zoneByteSize; zoneIdx++) {
  const zoneBaseOffset = zoneIdx * zoneByteSize;
  const currentZone = { heaters: [] };

  // 循环解析区域内的每个加热器
  for (let heaterIdx = 0; heaterIdx < heaterCountPerZone; heaterIdx++) {
    const heaterBaseOffset = zoneBaseOffset + heaterIdx * (tempByteLength + 2); // 考虑对齐填充

    currentZone.heaters.push({
      // 读取实数温度(注意字节序:西门子默认是大端,用readFloatBE;如果不对试readFloatLE)
      temperature: rawBuffer.readFloatBE(heaterBaseOffset),
      // 读取布尔状态(取字节的第0位)
      status: (rawBuffer.readUInt8(heaterBaseOffset + tempByteLength) & 0x01) === 1
    });
  }

  zones.push(currentZone);
}

// 将结构化数据作为新的payload输出
msg.payload = zones;
return msg;

最佳实践

  1. 复用解析逻辑:将解析函数封装为可复用的子流,后续新增区域或加热器时,只需修改函数中的配置参数和解析逻辑,无需重新搭建节点。
  2. 动态适配数组长度:如果数组长度可能变化,可以在PLC的DB中单独存储数组的当前元素数量,先读取这个数值,再根据数值计算需要读取的总字节数,实现动态读取。
  3. 调试验证:先用s7 in节点读取单个区域的字节,在调试面板查看Buffer内容,验证解析代码的正确性,再扩展到整个数组。
  4. 性能优化:一次性读取连续的字节块比多次读取单个变量效率高很多,尤其适合大量数据的场景。

内容的提问来源于stack exchange,提问作者Gortex

火山引擎 最新活动