|
上个季度,我接手一个旧项目: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)重构急停逻辑: // 安全急停FBFUNCTION_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步。 性能对比表 | 维度 | 旧方案(分散变量) | 新方案(数组) | | 代码长度(行) | 5000 | 600 | | 调试时间(小时) | 8 | 1 | | 错误率(次/月) | 3 | 0 | | 维护人员要求 | 高级工程师 | 初级即可改 | 第二个'原来是这样':数组不只是语法糖,它是模块化改造的基石。善后细节:从烧录到调试 改完程序别急着跑。踩过的坑: 学知识3:断电后保持状态 数组初始化在系统上电时执行,导致数据丢失。用三菱的RETAIN关键字: VAR RETAINaiSensorMap : 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, 三菱, 梯形图 如果你觉得这篇文章有帮助,请点个在看,分享给更多需要的人! 关注我,获取更多实用干货~ 有问题欢迎评论区留言交流! 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |