Twincat 3:为数组位命名
Twincat 3: Giving names to array bits
整个PLC方面的初学者,欢迎指正。
我正在整理我的项目,目前的情况是:
我从 modbus 接收到 16 字节数组。这些充当按钮、灯、传送带,你在 Factory IO 中拥有什么。
GAB_FactoryIO_Inputs AT %I* : ARRAY [0..15] OF BYTE;
GAB_FactoryIO_Outputs AT %Q* : ARRAY [0..15] OF BYTE;
因此,我没有使用位“IO.GAB_FactoryIO_Inputs[0].0”来引用“开始按钮”,而是进行了一个笨拙的转换 POU 和 GVL 来遍历每一位并给它们一个新名称。所以目前它看起来像这样的 200 行:
IO.iSensor10_Capa := IO.GAB_FactoryIO_Inputs[7].3;
IO.iSensor9_Capa := IO.GAB_FactoryIO_Inputs[7].4;
IO.iPositioner_Limit := IO.GAB_FactoryIO_Inputs[7].5;
IO.iPositioner_Clamped := IO.GAB_FactoryIO_Inputs[7].6;
IO.iPick2_Detected := IO.GAB_FactoryIO_Inputs[7].7;
IO.iPick2_MovX := IO.GAB_FactoryIO_Inputs[8].0;
IO.iPick2_MovZ := IO.GAB_FactoryIO_Inputs[8].1;
IO.iPick2_Rot := IO.GAB_FactoryIO_Inputs[8].2;
IO.iPick2_GripRot := IO.GAB_FactoryIO_Inputs[8].3;
还有这个
iPositioner_Limit : BOOL;
iPositioner_Clamped : BOOL;
iPick2_Detected : BOOL;
iPick2_MovX : BOOL;
iPick2_MovZ : BOOL;
iPick2_Rot : BOOL;
iPick2_GripRot : BOOL;
一切正常,但我不禁觉得它很业余,笨拙,而且速度很慢。
我读过有关结构、枚举和别名的内容,并且认为将结构轻松地安排在“柜子”中将是我的救星,就像这样:
stCNC.Button1
stCNC.Button3
stCNC.Sensor1
隐藏在结构内部的是 stCNC Sensor1 = IO.GAB_FactoryIO_Inputs[9].4;
之间的转换
但由于某种原因根本不起作用。
我很可能从完全错误的角度出发,但不知道接下来要寻找什么。
EDIT 目前正在进行中。好像我掌握了基础知识。
@kolyur 有足够简单的例子可以遵循,所以我从那里开始,并朝着 @Steve 和 @YAVA 的例子前进:
//sending inputs to GVL FactoryIO_Inputs AT %I* : ARRAY [0..15] OF BYTE;
fbMBReadInputs(pDestAddr := ADR(IO.FactoryIO_Inputs),
//in GVL IO
FactoryIO_Inputs AT %I* : U_UNION2;
//inside S_LIGHTS:
TYPE S_LIGHTS :
STRUCT
LIGHT0 : BIT;
LIGHT1 : BIT;
LIGHT2 : BIT;
LIGHT3 : BIT;
LIGHT4 : BIT;
LIGHT5 : BIT;
LIGHT6 : BIT;
LIGHT7 : BIT;
END_STRUCT
END_TYPE
//inside U_UNION1
TYPE U_UNION1 :
UNION
nArray : ARRAY[0..15] OF BYTE;
sName : S_NAME;
//Then instantiating in POU
VAR
sLights : S_LIGHTS;
---
sLights.LIGHT1 := TRUE;
你可以试试用UNION。
它基本上是一个“覆盖”变量,您可以将其置于另一个变量之上。
TYPE Test :
UNION
nARRAY : ARRAY[0..15] OF BYTE;
sHumanReadable : sStruct;
END_UNION
END_TYPE
如果您使用 BIT 数据类型,结构可能会有所帮助。 BIT 寻址单个位(不像 BOOL 需要整个字节),但它们只能在结构中使用。
TYPE Test
STRUCT
button1 : BIT;
button2 : BIT;
button3 : BIT;
button4 : BIT;
sensor1 : BIT;
sensor2 : BIT;
sensor3 : BIT;
sensor4 : BIT;
END_STRUCT
END_TYPE
这个结构占用一个字节,您可以将它们组成一个数组,而不是字节数组,以便在您的 Modbus 例程中使用。
不是先 link 将每个 IO 放入全局变量列表,然后 link 将它们放入函数块,而是可以 link 将符号直接放入函数实例块。
例如,您制作以下功能块并将硬件输入放在 VAR
部分,或者您可以将它们放在 VAR_INPUT
中。您还可以按照其他人的建议将输入收集到结构中,并在功能块中使用此结构。
FUNCTION_BLOCK Picker
VAR
MoveX AT %I : BOOL;
MoveY AT %I : BOOL;
Rotate AT %I : BOOL;
GripRotate AT %I : BOOL;
END_VAR
然后在你的程序中创建一个选择器的实例
PROGRAM MAIN
VAR
picker1 : Picker;
END_VAR
然后从你的系统配置中你可以link每个终端直接输入到VAR
里面picker1
.
整个PLC方面的初学者,欢迎指正。
我正在整理我的项目,目前的情况是: 我从 modbus 接收到 16 字节数组。这些充当按钮、灯、传送带,你在 Factory IO 中拥有什么。
GAB_FactoryIO_Inputs AT %I* : ARRAY [0..15] OF BYTE;
GAB_FactoryIO_Outputs AT %Q* : ARRAY [0..15] OF BYTE;
因此,我没有使用位“IO.GAB_FactoryIO_Inputs[0].0”来引用“开始按钮”,而是进行了一个笨拙的转换 POU 和 GVL 来遍历每一位并给它们一个新名称。所以目前它看起来像这样的 200 行:
IO.iSensor10_Capa := IO.GAB_FactoryIO_Inputs[7].3;
IO.iSensor9_Capa := IO.GAB_FactoryIO_Inputs[7].4;
IO.iPositioner_Limit := IO.GAB_FactoryIO_Inputs[7].5;
IO.iPositioner_Clamped := IO.GAB_FactoryIO_Inputs[7].6;
IO.iPick2_Detected := IO.GAB_FactoryIO_Inputs[7].7;
IO.iPick2_MovX := IO.GAB_FactoryIO_Inputs[8].0;
IO.iPick2_MovZ := IO.GAB_FactoryIO_Inputs[8].1;
IO.iPick2_Rot := IO.GAB_FactoryIO_Inputs[8].2;
IO.iPick2_GripRot := IO.GAB_FactoryIO_Inputs[8].3;
还有这个
iPositioner_Limit : BOOL;
iPositioner_Clamped : BOOL;
iPick2_Detected : BOOL;
iPick2_MovX : BOOL;
iPick2_MovZ : BOOL;
iPick2_Rot : BOOL;
iPick2_GripRot : BOOL;
一切正常,但我不禁觉得它很业余,笨拙,而且速度很慢。
我读过有关结构、枚举和别名的内容,并且认为将结构轻松地安排在“柜子”中将是我的救星,就像这样:
stCNC.Button1
stCNC.Button3
stCNC.Sensor1
隐藏在结构内部的是 stCNC Sensor1 = IO.GAB_FactoryIO_Inputs[9].4;
之间的转换但由于某种原因根本不起作用。 我很可能从完全错误的角度出发,但不知道接下来要寻找什么。
EDIT 目前正在进行中。好像我掌握了基础知识。 @kolyur 有足够简单的例子可以遵循,所以我从那里开始,并朝着 @Steve 和 @YAVA 的例子前进:
//sending inputs to GVL FactoryIO_Inputs AT %I* : ARRAY [0..15] OF BYTE;
fbMBReadInputs(pDestAddr := ADR(IO.FactoryIO_Inputs),
//in GVL IO
FactoryIO_Inputs AT %I* : U_UNION2;
//inside S_LIGHTS:
TYPE S_LIGHTS :
STRUCT
LIGHT0 : BIT;
LIGHT1 : BIT;
LIGHT2 : BIT;
LIGHT3 : BIT;
LIGHT4 : BIT;
LIGHT5 : BIT;
LIGHT6 : BIT;
LIGHT7 : BIT;
END_STRUCT
END_TYPE
//inside U_UNION1
TYPE U_UNION1 :
UNION
nArray : ARRAY[0..15] OF BYTE;
sName : S_NAME;
//Then instantiating in POU
VAR
sLights : S_LIGHTS;
---
sLights.LIGHT1 := TRUE;
你可以试试用UNION。 它基本上是一个“覆盖”变量,您可以将其置于另一个变量之上。
TYPE Test :
UNION
nARRAY : ARRAY[0..15] OF BYTE;
sHumanReadable : sStruct;
END_UNION
END_TYPE
如果您使用 BIT 数据类型,结构可能会有所帮助。 BIT 寻址单个位(不像 BOOL 需要整个字节),但它们只能在结构中使用。
TYPE Test
STRUCT
button1 : BIT;
button2 : BIT;
button3 : BIT;
button4 : BIT;
sensor1 : BIT;
sensor2 : BIT;
sensor3 : BIT;
sensor4 : BIT;
END_STRUCT
END_TYPE
这个结构占用一个字节,您可以将它们组成一个数组,而不是字节数组,以便在您的 Modbus 例程中使用。
不是先 link 将每个 IO 放入全局变量列表,然后 link 将它们放入函数块,而是可以 link 将符号直接放入函数实例块。
例如,您制作以下功能块并将硬件输入放在 VAR
部分,或者您可以将它们放在 VAR_INPUT
中。您还可以按照其他人的建议将输入收集到结构中,并在功能块中使用此结构。
FUNCTION_BLOCK Picker
VAR
MoveX AT %I : BOOL;
MoveY AT %I : BOOL;
Rotate AT %I : BOOL;
GripRotate AT %I : BOOL;
END_VAR
然后在你的程序中创建一个选择器的实例
PROGRAM MAIN
VAR
picker1 : Picker;
END_VAR
然后从你的系统配置中你可以link每个终端直接输入到VAR
里面picker1
.