0

我希望值在值 A 到值 B 之间变化需要一定的时间。它以这种方式工作,但我受到 BYTE (255) 的限制,如果我想使用更大的数字,这会使比例变差。我不知道怎么做。

因此,我需要帮助来解决这个问题。

提前致谢!

TX = Internal timer in MS

// fbScale scales a value from one to another.
fbScale[1](nIn := nIn, nInLow := nLow, nInHi := nHi, nOutLow := 0, nOutHi := 255, nOut =>);

IF fbScale[1].nOut > Out_INT AND InitU AND bEn THEN
    TR := T#60S;
    IF (Out_INT <> 255) THEN
        IF tx - tl < TR THEN
            Out_INT := MIN(TO_BYTE(SHL(TO_DWORD(tx - tl), 8) / TO_DWORD(TR)), (BYTE#255 - Start));
            Out_INT := Start + Out_INT;
        ELSE
            Out_INT := 255;
        END_IF  
    END_IF
    
    bBusy := TRUE;
    InitD := FALSE;

ELSIF fbScale[1].nOut < Out_INT AND InitD AND bEn THEN
    TR := SEL(ChangeLowHi, DWtoSec(nRTD),  T#0S);
        IF (Out_INT <> 0) THEN
            IF tx - tl < TR THEN
                Out_INT := MIN(TO_BYTE(SHL(TIME_TO_DWORD(tx - tl), 8) / TO_DWORD(TR)), Start);
                Out_INT := Start - Out_INT;
            ELSE
                Out_INT := 0;
            END_IF;
        END_IF
        
        bBusy := TRUE;
        InitU := FALSE;     
    
ELSE
    tl := tx;
    InitU := TRUE;
    InitD := TRUE;
    Start := Out_INT;
    
END_IF

fbScale[2](nIn := Out_INT, nInLow := 0, nInHi := 255, nOutLow := nLow, nOutHi := nHi, nOut => nOut) 
4

1 回答 1

1

如果您想要在一段时间内逐渐转换一个值,那么您可以执行以下操作:

    low_int: INT := 500;
    high_int: INT := 15000;
    duration: TIME := T#5S; // 5 seconds
    timer: TON;
    value: INT;
    scale: REAL;
    timer(IN := TRUE, PT := duration);

    IF (timer.Q) THEN
        value := high_int;
    ELSE
        scale := TIME_TO_REAL(timer.ET) / TIME_TO_REAL(duration);
        value := REAL_TO_INT(low_int + (high_int - low_int) * scale);
    END_IF

此外,您可以像这样添加过渡缓动(例如本例中的缓入和缓出):

    METHOD EaseInOutQuad : REAL
    VAR_INPUT
        scale: REAL;
    END_VAR
    IF (scale < 0.5) THEN
        EaseInOutQuad := 2 * scale * scale;
    ELSE
        EaseInOutQuad := -1 + (4 - 2 * scale) * scale;
    END_IF
    scale := TIME_TO_REAL(timer.ET) / TIME_TO_REAL(duration);
    scale := EaseInOutQuad(scale);
    value := REAL_TO_INT(low_int + (high_int - low_int) * scale);

如果您想进一步控制值如何随时间变化,则必须定义一个自定义函数。是一个 codesys 项目,其中我使用线性插值的示例,但如果您希望它更平滑,可以使用多项式插值。

于 2020-12-04T19:44:40.650 回答