Plc 在一定时间内将值从a更改为B

Plc 在一定时间内将值从a更改为B,plc,codesys,structured-text,Plc,Codesys,Structured Text,我希望某个值在值a到值B之间变化需要一定的时间。它是这样工作的,但我受到一个字节(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 :=

我希望某个值在值a到值B之间变化需要一定的时间。它是这样工作的,但我受到一个字节(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) 
TX=内部计时器(毫秒)
//fbScale将值从一个缩放到另一个。
fbScale[1](nIn:=nIn,nInLow:=nLow,nInHi:=nHi,nOutLow:=0,nOutHi:=255,nOut=>);
如果fbScale[1].nOut>Out\u INT和InitU以及bEn,则
TR:=T#60S;
如果(Out_INT 255),则
如果tx-tlnOut)

如果您希望在一段时间内逐渐转换一个值,那么您可以这样做:

    low_int: INT := 500;
    high_int: INT := 15000;
    duration: TIME := T#5S; // 5 seconds
    timer: TON;
    value: INT;
    scale: REAL;
此外,您可以添加一个转换易用性(例如本例中的易用性和易用性),如下所示:


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

您受字节限制是什么意思?使用单词。我应该说,如果你想要更好的帮助,请编辑我们的问题,更好地描述你的任务。你真正需要的东西很模糊。代码示例并没有帮助。有很多问题,比如“TR”在哪里被使用。我会从Util使用BLINK。@SergeyRomanov,如果目标是转换为阶跃函数,那么是的,但如果它是随着时间的推移逐渐变化的,那么据我所知,BLINK不会起作用,我把它理解为“在值a到值B之间变化”,而不是“从值a到值B变化”。我理解这个问题,他马上就改了。谢谢@Guiorgy!很抱歉解释得不好,但你的思路是对的。你说得对,我想逐渐改变。但是我可以说低int是0,高int是100,持续时间是10秒。所以0-100需要10秒。但我也希望值从0-5取5s,从5-7取2,5s,以此类推on@cha28,您要求的是一种控制值如何随时间变化的方法,这就是我在第二个示例(EaseInOutQuad)中所做的,但我仅使用了一条简单的缓和巴齐尔曲线(参见示例)。我使用的方法只是使值开始变慢,然后加速,然后再减速。如果您想对其进行更多的控制,则需要定义一个自定义函数,该函数接受并输出一个介于[0,1]之间的数字。在我看来,使用线性或多项式插值是最简单的
    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);