0

在 CodeSys 中是否可以动态地获取常量的值?

例如:

VAR CONSTANT
    MYCONST_1 : INT := 1;
    MYCONST_2 : INT := 2;
    MYCONST_3 : INT := 3;
    MYCONST_4 : INT := 4;
END_VAR

toCheck := 3; // INT
result := 0; // INT

FOR i := 1 TO 4 DO
    IF toCheck = i THEN
        result := GET_CONSTANT_VALUE_BYNAME(CONCAT('MYCONST_', INT_TO_STR(i)))
    END_IF
END_FOR
4

2 回答 2

2

您使用此代码的目标是什么?在循环结束时,如果 toCheck 等于 3,则结果 var 将始终为 4。

那么为什么不直接写 4 呢?

IF toCheck = 3 THEN
    result := MYCONST_4; 
END_IF

如果您想要一个取决于循环索引值的常量值,为什么不使用 const 整数数组?

VAR CONSTANT
    iConstValues : ARRAY[1..4] OF INT := [20,21,22,23];
END_VAR

FOR i := 1 to (eMAX_AXES_NUM-1) DO

    //Let's check an array of references to axes
    if NOT aAxes[i].isOperational()
    THEN
        //If one axis in the group is not operational return a result value
        result := iConstValues[i] ;
        RETURN
    END_IF
    
END_FOR

通常虽然你会有这样的东西:

TYPE E_Actuator :
(
    eNO_ACTUATOR := 0,
    eAXIS, //has value 1
    eVALVE //has value 2
);
END_TYPE

TYPE E_Status :
(
    eNO_RESULT := 0,
    eOPERATIONAL,
    eERROR
);
END_TYPE

TYPE E_AxisType :
(
    eX_AXIS := 1,
    eY_AXIS,
    eZ_AXIS,
    eA_AXIS,
    eB_AXIS,
    eMAX_AXES_NUM
);
END_TYPE

FUNCTION_BLOCK CheckActuators 
VAR_INPUT
    eActuator : E_Actuator;
END_VAR
VAR_OUTPUT
    eStatus : E_Status;
    eFaultyAxis : E_AxisType;
END_VAR

CASE eActuator OF

    //Check for type Axis
    eAXIS:
        //Check status here and return a value
        (*
        FOR i := 1 to (eMAX_AXES_NUM - 1) DO
            //CheckActuators has an array with references to all axes in the project for example..
            if NOT aAxes[i].isOperational()
            THEN
                //If one axis in the group is not operational return error status
                eStatus := eERROR;
                eFaultyAxis := i;

                RETURN
            END_IF
        END_FOR
        *)
        
    //Check for type Valve
    eVALVE:
            
END_CASE
于 2020-06-23T11:15:02.467 回答
2

首先你的例子很奇怪。ConfitionIF将在每个周期中起作用,尚不清楚条件如何取决于周期。我想你的意思是。

IF toCheck = i THEN

无论如何,在 codesys 中你不能在 PHP 变量中做类似的事情

$a = "hello";
$$a = "world";
echo $helo // output world

或者像这样

$b = 2;
$a1 = 1;
$a2 = 2;
echo ${"a" . $b}; // Output 2

这些都不适用于ST。你使用了不同的方法。如果你在你的问题中告诉你要解决的最终任务,我会建议你最好的,但现在我只会给你一个大概的想法。Codesys 2.3 的所有示例。在 3.5 中,语法略有不同。

  1. 数组

VAR 
    aSteps: ARRAY[1..4] OF INT := 1, 2, 3, 4;
END_VAR

toCheck := 3; // INT
result := 0; // INT

FOR i := 1 TO 4 DO
    IF toCheck = i THEN
        result := aSteps[i];
    END_IF
END_FOR

但更简单的是,正如您已经知道 index withtoCheck并且您不需要将其转换为变量名,您可以简单地。

VAR 
    aSteps: ARRAY[1..4] OF INT := 1, 2, 3, 4;
END_VAR

toCheck := 3; // INT
result := aSteps[toCheck];
  1. 枚举

首先你定义一个类型。

TYPE enSteps : (
    stepIdle, stepStart, stepEnd := 5
);
END_TYPE

现在stepIdle := 0stepStart := 1并且stepEnd := 5

VAR
    result: enSteps;
END_VAR

toCheck := 1;
result := toCheck;

IF result = stepStart THEN
   // DO something
END_IF

或者你可以使用CASE

CASE result OF
stepIdle: // do something
stepStart: // do something
stepEnd:
    result := stepIdle;
END_CASE

评论

如果你能描述你想要达到的目标,我会给你一个更好的建议。

于 2020-06-24T05:20:28.487 回答