从Allen-Bradley转CODESYS:PLC代码组织与OOP实践问询
CODESYS OOP编程适配指南(从AB梯形逻辑过渡)
1. 替代AB子程序/AOI的CODESYS方案
AB里的子程序对应CODESYS的独立PRG,AOI对应FB(功能块),完全不用把所有逻辑塞主PRG里:
- 用独立PRG做子程序:给PRG定义输入输出变量,调用时直接传参,彻底替代全局变量传值的方式。
- 优先用FB做封装:把输送机、堵塞传感器、急停这些设备做成带私有内部变量的FB,只暴露必要的输入输出和方法。比如
FB_Conveyor里封装自身的运行状态、速度控制逻辑,FB_JamSensor封装堵塞检测逻辑,内部变量设为PRIVATE,避免外部随意修改。
2. 大量设备的实例化策略(比如100台输送机)
主PRG可以作为顶层入口,但不用手写100次实例化代码:
- 数组批量实例化:
PROGRAM PRG_Main VAR arrConveyors: ARRAY[1..100] OF FB_Conveyor; i: INT; END_VAR FOR i := 1 TO 100 DO // 初始化每个输送机的唯一参数 arrConveyors[i].nConveyorID := i; arrConveyors[i].fMaxSpeed := 50.0; // 执行循环逻辑 arrConveyors[i].Cyclic(); END_FOR - 分区PRG管理:把设备按区域划分,比如
PRG_Zone1负责1-20号输送机,PRG_Zone2负责21-40号,主PRG只需要调用这些分区PRG,避免主PRG过于臃肿。 - 工厂模式FB:写一个
FB_DeviceFactory,负责批量创建、初始化所有设备实例,主PRG只调用工厂的初始化方法,然后通过工厂返回的实例数组管理设备。
3. 避免全局变量的FB间通信(解决跨PRG实例引用问题)
接口是解耦通信的核心,针对跨PRG实例引用的问题,有两种可靠方案:
方案1:接口+参数传递
定义统一接口让相关FB实现,再通过参数把实例引用传给需要的FB:
// 定义报警源接口 INTERFACE I_AlarmProvider PROPERTY bAlarmActive: BOOL READ_ONLY; METHOD ResetAlarm: BOOL; END_INTERFACE // 堵塞传感器FB实现接口 FUNCTION_BLOCK FB_JamSensor IMPLEMENTS I_AlarmProvider VAR PRIVATE bDetectedJam: BOOL; END_VAR bDetectedJam := NOT DI_SensorInput; PROPERTY bAlarmActive: BOOL READ_ONLY bAlarmActive := bDetectedJam; END_PROPERTY METHOD ResetAlarm: BOOL bDetectedJam := FALSE; ResetAlarm := TRUE; END_METHOD
然后在主PRG里实例化传感器和输送机,把传感器引用传给输送机:
PROGRAM PRG_Main VAR jamSensor1: FB_JamSensor; conveyor1: FB_Conveyor; END_VAR // 把传感器实例作为接口类型传给输送机 conveyor1.arrAlarmProviders[1] := jamSensor1; conveyor1.Cyclic(); jamSensor1.Cyclic();
方案2:事件驱动通信
用CODESYS的EVENT机制实现主动通知,彻底避免主动引用:
// 堵塞传感器FB定义事件 FUNCTION_BLOCK FB_JamSensor VAR_EVENT OnJamDetected: EVENT; END_VAR // 检测到堵塞时触发事件 IF NOT DI_SensorInput AND NOT bPrevSensorState THEN RAISE OnJamDetected; END_IF bPrevSensorState := NOT DI_SensorInput;
然后输送机FB订阅这个事件:
FUNCTION_BLOCK FB_Conveyor VAR // 订阅传感器的堵塞事件 <Attribute(EventSubscriber)> METHOD OnJamReceived: BOOL // 收到堵塞事件后停止输送机 DO_ConveyorOutput := FALSE; OnJamReceived := TRUE; END_METHOD END_VAR
在主PRG里关联事件和订阅方法:
PROGRAM PRG_Main VAR jamSensor1: FB_JamSensor; conveyor1: FB_Conveyor; END_VAR // 关联事件与订阅方法 jamSensor1.OnJamDetected += conveyor1.OnJamReceived; jamSensor1.Cyclic(); conveyor1.Cyclic();
4. 过渡阶段的实操资源
- 官方文档:直接看CODESYS帮助中心的**「Object-Oriented Programming」章节**,里面有FB、接口、继承的完整语法和示例。
- 官方示例项目:在CODESYS的「示例」菜单里搜索「Object-Oriented Programming」,里面有现成的多设备OOP架构案例,可以直接拆解学习。
- 官方直播:找CODESYS官方发布的「传统PLC编程转OOP」主题直播回放,里面有从梯形逻辑到OOP的实操过渡演示。
内容的提问来源于stack exchange,提问作者lcabal27
相关产品推荐
相关产品推荐

