连接变量
Concatenate variable
我需要将一个字符串、一个整数和一个字符串连接成一个变量——在本例中是一个输入。
输入命名如下:
DI_Section1_Valve AT %I*: BOOL;
DI_Section2_Valve AT %I*: BOOL;
DI_Section3_Valve AT %I*: BOOL;
现在,我想遍历这些(这只是一个简短的例子):
For i:= 1 TO 3 DO
Var[i] := NOT CONCAT(CONCAT('DI_Section', INT_TO_STRING(i)), '_Valve')
END_FOR
但是通过连接字符串,我最终会得到一个字符串,例如。 'DI_Section1_Valve',而不是布尔变量,例如。 DI_Section1_Valve.
如何以变量而不是字符串结束?
任何帮助表示赞赏,在此先感谢。
/Thoft99
您不能使用字符串访问变量。您可以做的是手动创建一个指向您要索引的值的指针数组,例如:
DI_Section1_Valve AT %I*: BOOL;
DI_Section2_Valve AT %I*: BOOL;
DI_Section3_Valve AT %I*: BOOL;
DI_Section_Valves: ARRAY [1..3] OF POINTER TO BOOL
:= [ADR(DI_Section1_Valve), ADR(DI_Section2_Valve), ADR(DI_Section3_Valve)];
FOR i:= 1 TO 3 DO
out[i] := DI_Section_Valves[i]^;
END_FOR
编辑:或者,您可以创建一个执行此操作的函数:
METHOD Get_DI_Selection_Valve : BOOL
VAR_INPUT
i: INT;
END_VAR
CASE i OF
1: Get_DI_Selection_Valve := DI_Section1_Valve;
2: Get_DI_Selection_Valve := DI_Section2_Valve;
3: Get_DI_Selection_Valve := DI_Section3_Valve;
END_CASE
FOR i:= 1 TO 3 DO
out[i] := Get_DI_Selection_Valve(i);
END_FOR
想法是一样的
这种技术叫做可变变量。不幸的是,这在 ST 中不可用。有几种解决方法。据我了解,Twincat 3 基于 Codesys 3.5。这意味着 UNION 可用。还有一个技巧,对 BOOL
的引用没有按预期工作,一个引用占用一个字节。所以你不能按顺序排列它们,所以你需要知道输入模块的BYTE
地址。
TYPE DI_Bits : STRUCT
DI_Section1_Valve : BIT; (* Bit 1 *)
DI_Section2_Valve : BIT; (* Bit 2 *)
DI_Section3_Valve : BIT; (* Bit 3 *)
DI_Section4_Valve : BIT; (* Bit 4 *)
DI_Section5_Valve : BIT; (* Bit 5 *)
DI_Section6_Valve : BIT; (* Bit 6 *)
DI_Section7_Valve : BIT; (* Bit 7 *)
DI_Section8_Valve : BIT; (* Bit 8 *)
END_STRUCT
END_TYPE
TYPE DI_Sections : UNION
ByName : DI_Bits;
ByID : ARRAY[1..8] OF BOOL; (* Comment *)
ByMask: BYTE;
END_UNION
END_TYPE
PROGRAM PLC_PRG
VAR
DIS AT %IB0.0: DI_Sections; (* Our union *)
xOut : BOOL;
END_VAR
xOut := DIS.ByID[1];
xOut := DIS.ByName.DI_Section1_Valve;
DIS.ByID[5] := TRUE;
// Now DIS.ByName.DI_Section5_Valve also EQ TRUE
END_PROGRAM
我需要将一个字符串、一个整数和一个字符串连接成一个变量——在本例中是一个输入。
输入命名如下:
DI_Section1_Valve AT %I*: BOOL;
DI_Section2_Valve AT %I*: BOOL;
DI_Section3_Valve AT %I*: BOOL;
现在,我想遍历这些(这只是一个简短的例子):
For i:= 1 TO 3 DO
Var[i] := NOT CONCAT(CONCAT('DI_Section', INT_TO_STRING(i)), '_Valve')
END_FOR
但是通过连接字符串,我最终会得到一个字符串,例如。 'DI_Section1_Valve',而不是布尔变量,例如。 DI_Section1_Valve.
如何以变量而不是字符串结束? 任何帮助表示赞赏,在此先感谢。 /Thoft99
您不能使用字符串访问变量。您可以做的是手动创建一个指向您要索引的值的指针数组,例如:
DI_Section1_Valve AT %I*: BOOL;
DI_Section2_Valve AT %I*: BOOL;
DI_Section3_Valve AT %I*: BOOL;
DI_Section_Valves: ARRAY [1..3] OF POINTER TO BOOL
:= [ADR(DI_Section1_Valve), ADR(DI_Section2_Valve), ADR(DI_Section3_Valve)];
FOR i:= 1 TO 3 DO
out[i] := DI_Section_Valves[i]^;
END_FOR
编辑:或者,您可以创建一个执行此操作的函数:
METHOD Get_DI_Selection_Valve : BOOL
VAR_INPUT
i: INT;
END_VAR
CASE i OF
1: Get_DI_Selection_Valve := DI_Section1_Valve;
2: Get_DI_Selection_Valve := DI_Section2_Valve;
3: Get_DI_Selection_Valve := DI_Section3_Valve;
END_CASE
FOR i:= 1 TO 3 DO
out[i] := Get_DI_Selection_Valve(i);
END_FOR
想法是一样的
这种技术叫做可变变量。不幸的是,这在 ST 中不可用。有几种解决方法。据我了解,Twincat 3 基于 Codesys 3.5。这意味着 UNION 可用。还有一个技巧,对 BOOL
的引用没有按预期工作,一个引用占用一个字节。所以你不能按顺序排列它们,所以你需要知道输入模块的BYTE
地址。
TYPE DI_Bits : STRUCT
DI_Section1_Valve : BIT; (* Bit 1 *)
DI_Section2_Valve : BIT; (* Bit 2 *)
DI_Section3_Valve : BIT; (* Bit 3 *)
DI_Section4_Valve : BIT; (* Bit 4 *)
DI_Section5_Valve : BIT; (* Bit 5 *)
DI_Section6_Valve : BIT; (* Bit 6 *)
DI_Section7_Valve : BIT; (* Bit 7 *)
DI_Section8_Valve : BIT; (* Bit 8 *)
END_STRUCT
END_TYPE
TYPE DI_Sections : UNION
ByName : DI_Bits;
ByID : ARRAY[1..8] OF BOOL; (* Comment *)
ByMask: BYTE;
END_UNION
END_TYPE
PROGRAM PLC_PRG
VAR
DIS AT %IB0.0: DI_Sections; (* Our union *)
xOut : BOOL;
END_VAR
xOut := DIS.ByID[1];
xOut := DIS.ByName.DI_Section1_Valve;
DIS.ByID[5] := TRUE;
// Now DIS.ByName.DI_Section5_Valve also EQ TRUE
END_PROGRAM