博图SCL灵活运用加减计数、函数指令案例-自动化分拣站(上)

博图SCL灵活运用加减计数指令案例:智能物料分拣站

1. 应用场景与解决方案
在自动化分拣站中,需要根据不同类型的物料箱动态调整产品装入数量:
- A类箱:10个产品
- B类箱:15个产品
- C类箱:8个产品

传统计数器只能处理固定目标值,我们通过SCL语言灵活运用CTU计数器,实现了:
- 动态目标值设置
- 运行时目标值调整
- 安全保护机制
- 状态实时同步

2. 系统流程图

 3. SCL程序实现
FUNCTION_BLOCK FB_SmartCounter
VAR
    // 输入输出定义
    ProductSensor: BOOL;  // 产品检测传感器
    Button_A, Button_B, Button_C: BOOL; // 箱子类型选择
    ResetButton, EStop: BOOL; // 复位和急停
    UpButton, DownButton: BOOL; // 目标值调整
    
    BoxFull: BOOL;  // 装箱完成信号
    CurrentCount: INT; // 当前计数值
    CurrentTarget: INT; // 当前目标值
    StatusMessage: STRING(80); // 状态信息
    
    // 内部变量
    PrevProductSensor, PrevUpButton, PrevDownButton: BOOL;
    Counter: CTU; // 加计数器实例
    Mode: INT := 0; // 0:未选, 1:A, 2:B, 3:C
    DefaultTargets: ARRAY[1..3] OF INT := [10, 15, 8]; // 默认目标值
    bInitialized: BOOL := FALSE;
END_VAR

#CurrentTarget_1 := #CurrentTarget;
#CurrentCount_1:= #CurrentCount;
#StatusMessage_1 := #StatusMessage;
#BoxFull_1:= #BoxFull;
//===== 初始化部分 =====//
IF NOT #bInitialized THEN
    
    "IEC_Counter_0_DB".CTUD(CU:=FALSE,
                            CD:=FALSE,
                            R:=TRUE,
                            PV:=0);
    #CurrentTarget := 0;
    #CurrentCount := 0;
    #BoxFull := FALSE;
    #StatusMessage := 0;
    #bInitialized := TRUE;
    RETURN;
END_IF;

//===== 急停/复位处理 =====//
IF #EStop OR #ResetButton THEN
  
    "IEC_Counter_0_DB".R := TRUE;
    #CurrentCount := 0;
    #BoxFull := FALSE;
    #Mode := 0;
    #StatusMessage := 9;
    RETURN;
END_IF;

//===== 模式选择 =====//
IF #Button_A AND NOT #PrevProductSensor THEN
    #Mode := 1;
    #CurrentTarget := #DefaultTargets[1];
    "IEC_Counter_0_DB".R := TRUE;
    #CurrentCount := 0;
    #BoxFull := FALSE;
    #StatusMessage := 1;
ELSIF #Button_B AND NOT #PrevProductSensor THEN
    #Mode := 2;
    #CurrentTarget := #DefaultTargets[2];
    "IEC_Counter_0_DB".R := TRUE;
    #StatusMessage := 2;
ELSIF #Button_C AND NOT #PrevProductSensor THEN
    #Mode := 3;
    #CurrentTarget := #DefaultTargets[3];
    "IEC_Counter_0_DB".R := TRUE;
    #StatusMessage := 3;
END_IF;
IF #CurrentCount_1<>0 THEN
    #PrevProductSensor := #CurrentCount_1 >= #CurrentTarget_1;

ELSE
    
    #PrevProductSensor :=FALSE;
    
END_IF;


//===== 状态保存 =====//
"R_TRIG_DB"(CLK:= #UpButton,
            Q=> #PrevUpButton);
"R_TRIG_DB_1"(CLK:= #DownButton,
              Q=>#PrevDownButton);

//===== 模式检测 =====//
IF #Mode = 0 THEN
    RETURN;
END_IF;

//===== 核心计数逻辑 =====//

#CurrentCount := "IEC_Counter_0_DB".CV;
    
"IEC_Counter_0_DB".CTUD(CU :=  #ProductSensor AND NOT #PrevProductSensor,
                            CD := FALSE,
                            R := FALSE,
                            PV :=  #CurrentTarget);
// 目标值检测
    IF "IEC_Counter_0_DB".QU THEN
    #BoxFull := TRUE;
    #StatusMessage := 4;
ELSE
    #BoxFull := FALSE;
END_IF;

//===== 动态目标值调整 =====//
// 增加目标值
IF #UpButton AND NOT #PrevUpButton THEN
    #CurrentTarget := LIMIT(MN := #DefaultTargets[#Mode], IN := #CurrentTarget , MX := #DefaultTargets[#Mode] + 5);
    "IEC_Counter_0_DB".PV := #CurrentTarget + 1;
    #StatusMessage := 5;
    #CurrentTarget := "IEC_Counter_0_DB".PV;
END_IF;

// 减少目标值
IF #DownButton AND NOT #PrevDownButton THEN
    #CurrentTarget := LIMIT(MN := #DefaultTargets[#Mode], IN := #CurrentTarget , MX := #DefaultTargets[#Mode] + 5);
    "IEC_Counter_0_DB".PV := #CurrentTarget - 1;
    #StatusMessage := 5;
END_IF;

//===== 安全保护机制 =====//
// 强制完成检测
IF #CurrentCount >= #CurrentTarget AND NOT #BoxFull THEN
    #BoxFull := TRUE;
    #StatusMessage := 7;
END_IF;

// 状态同步
IF #BoxFull AND #CurrentCount < #CurrentTarget THEN
    #BoxFull := FALSE;
    #StatusMessage := 8;
END_IF;

你可能感兴趣的:(博图编程基础知识及案例,自动化,运维,程序人生,算法)