编程思路:8台水泵优先排序 点击:302 | 回复:3



࿐ཉི༗࿆乐为༗࿆ཉི࿐

    
  • 精华:0帖
  • 求助:3帖
  • 帖子:6帖 | 21回
  • 年度积分:107
  • 历史总积分:299
  • 注册:2020年9月09日
发表于:2024-10-17 16:52:02
楼主
求助帖60分-未结帖

-------------------------------------------------------------------、

初学SCL,请教下各位工友,想实现以下功能该如何写

8台电机,6用2备,

1,自动模式下的启停排序

①,根据压力值Bar(real)判断 处于对应区间开启对应台数

②,运行时间满足停机时间则切换轮休电机

③,启动时按休眠时间长的优先启动

④,停止按运行时间长的停止

下图是①压力Bar假设对应的启动台数

---------------------------------------------------------------------------

注:只是争对编程算法如何实现,并不讨论其实际应用场景。





楼主最近还看过

victor329

  • [版主]
  • 精华:1帖
  • 求助:26帖
  • 帖子:361帖 | 2513回
  • 年度积分:13381
  • 历史总积分:102187
  • 注册:2008年5月16日
发表于:2024-10-19 21:03:46
1楼

这个画个流程图,思路自然就有了,按照状态做顺控,想清楚所有的情况就行!

回复本条

    

冲出枪林弹雨

  • 精华:0帖
  • 求助:0帖
  • 帖子:9帖 | 70回
  • 年度积分:0
  • 历史总积分:918
  • 注册:2015年9月04日
发表于:2024-10-21 22:34:28
2楼

大概意思吧,还有些异常报警处理没写,你自己看着弄下

// 初始化定时器  

IF NOT StartTime.IN THEN  

    StartTime(IN := TRUE, PT := T#0S);  

END_IF  

  

IF NOT ShutdownTime.IN THEN  

    ShutdownTime(IN := AutoMode AND (PressureBar <= PressureLow OR PressureBar >= PressureHigh), PT := StandbyTime);  

END_IF  

  

// 初始化休眠时间定时器  

FOR i := 1 TO 4 DO  

    IF NOT SleepTime[i].IN THEN  

        SleepTime[i](IN := TRUE, PT := SleepIntervals[i]);  

    END_IF  

END_FOR  

  

// 根据压力值判断电机台数  

IF AutoMode THEN  

    MotorCount := 0;  

      

    IF PressureBar < PressureLow THEN  

        MotorCount := 1;  

    ELSIF PressureBar < PressureMedium THEN  

        MotorCount := 2;  

    ELSIF PressureBar < PressureHigh THEN  

        MotorCount := 3;  

    ELSE  

        MotorCount := 4;  

    END_IF  

      

    // 初始化电机启用状态  

    FOR i := 1 TO 4 DO  

        MotorEnabled[i] := FALSE;  

    END_FOR  

      

    // 根据休眠时间长的优先启动  

    FOR i := 1 TO MotorCount DO  

        MaxSleepTimeIndex := 1;  

        FOR j := 1 TO 4 DO  

            IF NOT MotorEnabled[j] AND (SleepTime[j].ET > SleepTime[MaxSleepTimeIndex].ET) THEN  

                MaxSleepTimeIndex := j;  

            END_IF  

        END_FOR  

        MotorEnabled[MaxSleepTimeIndex] := TRUE;  

    END_FOR  

      

    // 更新电机状态  

    FOR i := 1 TO 4 DO  

        IF MotorEnabled[i] THEN  

            IF NOT MotorState[i] THEN  

                MotorState[i] := TRUE;  

                RunTime[i](IN := TRUE, PT := T#MAX); // 开始计时  

            END_IF  

        ELSE  

            IF MotorState[i] THEN  

                MotorState[i] := FALSE;  

                RunTime[i](IN := FALSE); // 停止计时  

            END_IF  

        END_IF  

        MotorCommand[i] := MotorState[i];  

    END_FOR  

      

    // 切换轮休电机  

    IF ShutdownTime.Q THEN  

        MaxRunTimeIndex := 1;  

        FOR i := 1 TO 4 DO  

            IF MotorEnabled[i] AND (RunTime[i].ET > RunTime[MaxRunTimeIndex].ET) THEN  

                MaxRunTimeIndex := i;  

            END_IF  

        END_FOR  

        MotorEnabled[MaxRunTimeIndex] := FALSE;  

        MotorState[MaxRunTimeIndex] := FALSE;  

        RunTime[MaxRunTimeIndex](IN := FALSE);  

        ShutdownTime(IN := FALSE); // 重置停机定时器  

    END_IF  

ELSE  

    // 手动模式下,所有电机停止  

    FOR i := 1 TO 4 DO  

        MotorCommand[i] := FALSE;  

        MotorState[i] := FALSE;  

        RunTime[i](IN := FALSE);  

    END_FOR  

END_IF  


回复本条

    

monzer

  • [版主]
  • 精华:11帖
  • 求助:2帖
  • 帖子:49帖 | 127回
  • 年度积分:1147
  • 历史总积分:13004
  • 注册:2020年3月27日
发表于:2024-10-23 11:09:00
3楼

大佬的这个问题看似很难其实一点也不简单。琢磨了好几天了,才想到以下的办法:

首先定义一些数据结构:1,有一个启动队列,由#bar决定出队列的次数。2,有一个停机状态表/队列。3,有一组计时器与停机状态表进行绑定。4,有一个运行状态表/队列。5,有一组定时器与运行状态进行绑定。

然后是对应的实现:设备上电时,8台设备全部进入停机状态表,与此同时激活计时器。初次启动时拷贝所有计时器的值到一张临时表中,随之对临时计时器表进行排序,然后根据#bar的值从停机状态表中出#bar数量的设备到启动队列,由启动队列按照#bar数量完成设备的启动。并且在每个出启动队列的设备,给它分配一个时间片,这个时间片由定时器完成。另外要新开一个线程去监视定时器到没到期。这个新开的线程可由触发器或者异步中断来完成。当定时器到期时,与之对应 的设备进入停机状态表。


回复本条

    

热门招聘
相关主题

官方公众号

智造工程师