『7x24小时有问必答』
上个季度,我接手一个旧项目:3台MELSEC iQ-R系列PLC,控制一套老式输送线,IO点200+。第一天上电,震动传感器狂报警——地址重复、注释错乱、数组写到一半断号,返工3天。老板问:"这点活还要多久?"我说:"重写,但换个写法。"
改造完,任务跑一遍从120秒降至30秒,地址长度从200行缩到50行。核心就一招:数组寻址。今天我把踩过的坑和手撕代码全拆开给你看。

为什么老旧PLC代码难读到想砸键盘?

你以为老旧代码只是注释少?真相是:80%的IO地址硬编码在梯形图里,改一个传感器映射,要翻5个FB块改30个点。"复用"这个词,在老项目里就是笑话。

学知识1:地址冲突是魔鬼

现场有一组传感器,型号E2E-X10D1-N,6个。原程序这样写:
// 旧方案:手动编号
VAR
bSensor1 AT %I0.0 : BOOL;
bSensor2 AT %I0.1 : BOOL;
bSensor3 AT %I0.2 : BOOL;
// ... 一直写到第6个
END_VAR
改造时发现:传感器2和传感器5的地址被占用(因为中间插了一个HMI按钮)。排查用了4小时。你以为地址连续,实际上中间有隐形的"断号"

学知识2:数组寻址一劳永逸

用数组+自动编号,彻底告别手动冲突:
// 新方案:数组 + 结构体
TYPE SensorGroup :
STRUCT
bSensors : ARRAY[1..6] OF BOOL;  // 6个传感器
iAnalog   : ARRAY[1..6] OF INT;  // 模拟量通道
END_STRUCT
END_TYPE
VAR
gstSensorGroup AT %I10.0 : SensorGroup;  // 基地址
END_VAR
这样传感器1-6自动占用连续地址段(%I10.0~%I10.5),中间不会插入其他设备。数组让你从手动标注变成自动偏移——这是第一个"原来是这样"。

你以为线性改就够?实际上得用SIL3安全结构化

老项目最怕改安全逻辑——比如急停回路。原程序是逻辑散落在3个POU里,维护者不敢动。

设计一个安全FB,复用率提升8倍

我用三菱MELSEC安全FB库(SFB)重构急停逻辑:
// 安全急停FB
FUNCTION_BLOCK FB_SafetyStop
VAR_INPUT
bEstop1 : BOOL;  // 硬件急停开关1
bEstop2 : BOOL;  // 硬件急停开关2
bEnable : BOOL;  // 程序使能
END_VAR
VAR_OUTPUT
bRunEnable : BOOL;  // 运行许可
END_VAR
// FB逻辑(SIL3双通道冗余)
bRunEnable := (bEstop1 AND bEstop2 AND bEnable);
IF NOT bEstop1 THEN
// 错误代码:E101 急停1触发
stError := TRUE;
bRunEnable := FALSE;
END_IF
重点
:这个FB在3台PLC中复用了8个位置,每台只需改一次基地址。改造前:急停逻辑分散,排查需30分钟。改造后:一个块,5分钟定位。
复用率从1提升到8倍

案例实战:如何用单数组完成200个传感器映射

这是最硬核的部分。现场有200个传感器,旧代码用200个独立BOOL变量,程序体积5000步。

用数组缩减代码量

// 单数组:索引=传感器号,值=映射地址
VAR
aiSensorMap : ARRAY[1..200] OF INT;  // 物理地址索引表
bSensorData : ARRAY[1..200] OF BOOL; // 数据处理结果
END_VAR
初始初始化写一次:
// 初始化映射表
FOR I := 1 TO 100 DO
aiSensorMap[I] := I + 1000;  // 传感器1:映射到1001地址
END_FOR
读取时统一处理:
// 统一读取
FOR I := 1 TO 200 DO
// 实际上用SysReadWord读取物理地址aiSensorMap[I]
bSensorData[I] := (SysReadWord(aiSensorMap[I]) > 0);
END_FOR
改造前:改一个传感器地址需改3-5处代码。
改造后:改aiSensorMap[I]的一个值。代码量从5000步降至600步

性能对比表

维度旧方案(分散变量)新方案(数组)
代码长度(行)5000600
调试时间(小时)81
错误率(次/月)30
维护人员要求高级工程师初级即可改
第二个'原来是这样':数组不只是语法糖,它是模块化改造的基石。

善后细节:从烧录到调试

改完程序别急着跑。踩过的坑:

学知识3:断电后保持状态

数组初始化在系统上电时执行,导致数据丢失。用三菱的RETAIN关键字:
VAR RETAIN
aiSensorMap : ARRAY[1..200] OF INT;  // 断电保持
END_VAR

学知识4:用系统监视功能

MELSEC iQ-R的GX Works3里,有一个系统监视窗口,能实时看数组状态。你以为数组调试难,实际上用监视表比逐个点方便10倍

一个真故障案例

调试时发现传感器2一直ON,查半天发现:旧物理地址%I10.0被HMI强行占用。用数组后,基地址改为%I20.0正常。这个坑告诉我:物理地址空间预留是要点

改造清单:3步走

第一步:清理物理地址

用GX Works3的工程功能,查IO映射表
把冗余地址全部删除,释放空间
定义基地址(如%I10.0、%Q10.0),预留连续段

第二步:设计数据结构

优先用ARRAY + 结构体
每个传感器/执行器编一个索引号
初始化映射表,存物理地址或模拟量通道

第三步:重构FB

安全逻辑单独FB,复用
数组访问用循环,不写重复代码
加RETAIN解决断电丢失
你有一个可操作的检查清单:
   
1.[ ] 所有IO地址是否在数组/结构体里,而不是硬编码   2.[ ] 是否预留了20%地址段给未来扩展   3.[ ] 程序能否通过改一个数组值适配不同IO数   4.[ ] 是否用系统监视功能验证过数据流   
最后问自己:你的老项目里,还有多少硬编码地址等着你手动改? 去翻GX Works3工程文件,找一个IO点多的程序,试试用数组重写一部分。改造完告诉我效率提升多少。
(本文基于MELSEQ iQ-R R08CPU + GX Works3 V2.4编写)
推荐阅读
8个层次搞懂三菱机械手编程,最后一个是终极境界
发布于 2026-06-27
三菱机械手轨迹规划与编程:从直线到复杂曲线
发布于 2026-06-21
6步搞定三菱iQ-R FB封装+3套实战代码,PLC编程效率直接翻倍
发布于 2026-06-18
KEYWORDS
PLC, GX Works, MELSEC, 三菱, 梯形图
如果你觉得这篇文章有帮助,请点个在看,分享给更多需要的人!
关注我,获取更多实用干货~
有问题欢迎评论区留言交流!

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

上一主题上一主题         下一主题下一主题
QQ手机版小黑屋粤ICP备17165530号

关于我们·投诉举报· 用户帮助· 联系我们 · 本站服务 · 版权声明· 隐私政策 · 投搞指南

法律保护:PLC技术网,plcjs.com,plcjs.net等字样
Copyright 2010-2030. All rights reserved. 


微信公众号二维码 抖音二维码 百家号二维码 今日头条二维码哔哩哔哩二维码