我在 Node-RED 里重造了三菱 PLC 采集节点:一个工业工程师对 mcprotocol 的 7 个不满

发布时间:2026/7/1 9:42:40

我在 Node-RED 里重造了三菱 PLC 采集节点:一个工业工程师对 mcprotocol 的 7 个不满 做工业边缘计算这两年Node-RED 里三菱 PLC 的采集方案基本只有一个选择——node-red-contrib-mcprotocol。用过的都知道它不是不能用是用起来太拧巴。我忍了一年列了 7 个忍无可忍的痛点最终决定自己造一个。现在它已经跑在 3 个现场项目里npm 上也发了稳定版。这篇文章不是广告是一个工程师的踩坑记录。一、痛点 1散点、跨类型、混寄存器只能一个一个配mcprotocol 一个节点可以读一段连续地址比如 D100 开始的 100 个 INT16这个没问题。但真实工控场景根本不是100 个连续 INT16这么理想。更多时候是这样的- D100温度INT16斜率 0.1- D200压力FLOAT32占两个寄存器- D500状态UINT16- X0开关 BOOL- M5运行状态 BOOL散点、跨地址、混寄存器类型。mcprotocol 遇到这些只能拆成好几个节点后面再挂一堆 function 拼 Buffer、算斜率。我的做法一个节点里放表格。需要采集的点位一行一行填同类型自动聚类合并——D 寄存器归一组发一条批量读指令X 归一组发另一条。十几个散点不是十几个 TCP 连接是两三个。表格里还支持批量生成起始 100数量 100点一下自动填充。中间个别特殊的比如 D150 是 FLOAT32单独改就行。二、痛点 2FLOAT32 要自己拼 BufferPLC 里 D200 存的是 FLOAT32占 D200 和 D201 两个寄存器。mcprotocol 读回来是两个 INT16你得在后面挂一个 function 节点var buf Buffer.alloc(4);buf.writeInt16LE(msg.payload[0], 0);buf.writeInt16LE(msg.payload[1], 2);msg.payload buf.readFloatLE(0);return msg;这还只是 FLOAT32。UINT16 读到负数要自己 65536INT32 要拼高低字斜率换算还要再挂一个 function。我的做法表格里下拉选数据类型——INT16 / UINT16 / INT32 / UINT32 / FLOAT32 / BOOL。节点自动解码你拿到手的 engValue 就是最终值。三、痛点 3斜率换算再挂一个 function温度存在 PLC 里是 2530实际是 253.0℃。mcprotocol 给你 2530你自己除 10。我的做法表格里填斜率 0.1偏移 0。输出直接是 engValue: 253.0。四、痛点 4出错只会说 timeoutPLC 返回 0xC052地址越界、0xC059批量超限、0xC051软元件不支持mcprotocol 统统给你转成一句 timeout。你盯着日志查了半天最后发现是表里填错了一个地址。更惨的是你根本不知道 PLC 到底拒绝的是哪个请求。这也是早期项目条件下无奈的选择——那时候能连上 PLC 就不错了。但今天工业现场对稳定性要求更高不能再忍了。我的做法内置 19 个 MC 错误码映射。出错时直接告诉你[PLC 0xC052] Address out of range (D100)[PLC 0xC059] Points out of range[PLC 0xC051] Device not supported五、痛点 5serialNo 是摆设4E 帧的 serialNo 字段设计来就是做请求-响应匹配的。mcprotocol 直接写死一个值不变PLC 响应回来根本不知道是哪个请求的。我的做法每发一帧 serialNo 自增 1响应回来校验。不匹配直接丢弃重试。六、痛点 6没有模拟模式出差路上、在家写流程、CI 自动化测试没有 PLC 怎么办mcprotocol 直接 Not connected。我的做法Node-RED settings.js 里加一行 mcSimulationMode: true不连 PLC 也能跑随机生成仿真数据。七、痛点 7依赖冲突mcprotocol 本身虽然零依赖但它和某些版本的 Node-RED 共存时会有连接池 bug。你查了半天最后发现是插件内部 connection pool 状态崩了。我的做法整个节点只用了 Node.js 自带的 net 和 Buffer。没有第三方依赖没有连接池黑盒TCP 连接我自己管。硬碰硬对比mcprotocol- 散点跨类型采集拖多个节点 挂 function- FLOAT32自己写 function 拼接- 原始值→工程值自己写 function 换算- 出错提示timeout- serialNo固定不变- 模拟测试不支持- 外部依赖有我的节点- 散点跨类型采集拖 1 个节点填表- FLOAT32表格选 FLOAT32自动解码- 原始值→工程值填斜率 0.1自动变换- 出错提示[PLC 0xC052] Address out of range- serialNo每帧自增 响应校验- 模拟测试一行配置- 外部依赖0不只是独立节点这个 MC 节点不是孤立存在的。它和 node-red-contrib-edgelink-pg 是一对mitsubishi-read → edgelink-pg-store → PostgreSQL/TimescaleDB↑ PLC 数据采集 ↑ 批量写入带缓冲、重试、断线保护MC 读节点输出的数据格式PG 写节点直接认识零配置入库。deviceId 自动做分表、regType 自动写 register_type 列、engValue 直接写 eng_value 列。PG 节点也不是普通的 SQL 执行器——它内置了批量缓冲100 条一次 INSERT、失败重试队列、PG 假死超时 kill、内存双上限防 OOM。这俩加起来就是一条完整的 PLC→数据库链路中间不需要写一行代码。一条完整的数据流长什么样左侧一个 mitsubishi-read 节点表格里填了 5 行点位D100 温度、D200 压力 FLOAT32、X0 开关……右边连一个 edgelink-pg-store配置了数据库连接127.0.0.1:5432Debug 面板直接输出{温度: { engValue: 253.0, regType: D, quality: 0 },压力: { engValue: 1.25, regType: D, quality: 0 },开关: { engValue: 1, regType: X, quality: 0 }}拖出来、填表、部署数据直接进数据库。不需要写 function不需要拼 Buffer。安装cd ~/.node-rednpm install node-red-contrib-mitsubishi或者直接在 Node-RED Palette Manager 里搜 mitsubishi 一键安装。GitHubhttps://github.com/Qq225083/node-red-contrib-mitsubishi局限诚实说当前版本只支持 3E 和 4E 帧- Q 系列、L 系列、iQ-R、iQ-FFX5U支持- FX3U 以太网模块FX3U-ENET支持- 纯串口的 FX3U需要 1E 帧不支持- A 系列需要 1E 帧不支持不带以太网模块的老 FX3U 暂时用不了。1E 帧已经在路上了。最后造这个节点的初衷很简单我是一个工业现场工程师我不想把时间花在写 function 节点、拼 Buffer、猜 timeout 上。我想拖一个节点、填表、部署然后去喝杯咖啡。现在可以了。如果你也在用 Node-RED 做工业采集欢迎试用有问题直接提 Issue。更新记录- 2026.06.30v1.0.3 发布修复 4E 帧序列号校验、TCP 响应完整性检查- 2026.06.27v1.0.0 发布初始版本

相关新闻