在本例中,您将学习如何启用OPC UA插件并将RoboDK转换为OPC UA服务器。我们将使用UaExpert软件和Beckhoff TwinCAT3 TF6100浏览一些设置。
OPC UA插件允许您配置一些设置,例如服务器端口。您还可以选择激活服务器、停用服务器或自动启动RoboDK。
启用OPC UA外接程序后,选择OPC ua -OPC ua设置配置您的OPC UA设置。
左侧显示OPC UA设置界面,如下图所示。
如果你看到一个消息,如“RoboDK的OPC UA服务器运行在端口4840”,这意味着在RoboDK的OPC UA服务器启动。
您可以与任何有一个或多个机器人的RoboDK站测试OPC UA连接。
您可以使用UaExpert软件测试与RoboDK OPC UA服务器的连通性。
您可以从统一自动2022世界杯国家队名单化网站下载免费版UaExpert软件:https://www.unified-automation.com/2022世界杯国家队名单downloads/opc-ua-clients.html.
启动UaExpert,点击“+”按钮添加RoboDK OPC UA服务器。
展开自定义发现并选择<双击添加服务器。>选项添加RoboDK OPC UA服务器。
输入上一步中配置的OPC UA服务器的URL“OPC .tcp://127.0.0.1:48440”。
连接安全选项为“无”的OPC UA服务器。
完成服务器配置。
现在您可以从UaExpert连接到RoboDK OPC UA服务器。
当连接建立时,您可以看到Nodes和Methods。
RoboDK OPC UA服务器内部有一些节点可以让您交换有关站点的一些基本信息。
RoboDK节点是提供RoboDK软件实际版本的节点。
本操作中使用的版本为RoboDK 64 Bit v5.5.3.23031。
仿真速度是显示实际仿真速度的节点,允许用户覆盖当前的仿真速度。
节点值参考仿真速度滑动条。
当前仿真可以从该节点读取,并且可以覆盖仿真速度。
站节点是一个节点,它允许用户在RoboDK中获得站的当前名称。
正如您在下面看到的,站点节点引用了您在RoboDK中的“站点名称”。
站点参数和站点值是一对设置节点,允许用户获取或设置站点内的任何参数。RoboDK OPC UA服务器将持续监控“StationParameter”的实际值,并从站值节点返回该“StationParameter”的值。
您可以通过右键单击您的RoboDK站>站参数来查看您的站参数。
在Constant parameters字段中,您可以看到默认的站点参数及其值。
站点参数引用“参数”字段,站点值引用“值”字段。
我们可以通过点击“添加”按钮来创建我们自己的参数。
添加了一个新的Station参数。
输入您的参数名称和参数值,然后按Apply保存它。
您也可以获得自己的站点参数。
节点时间是一个节点,可以让您获得RoboDK站的当前时间。
返回一个DataTime格式的值。
这个节点是不断更新的。
RoboDK OPC UA服务器还提供了一些方法,允许用户动态访问RoboDK站的数据。
我们可以右键单击Method>Call来执行该方法。
getItem是一个允许用户获取Item指针的方法。
对于inputargarguments,设备名称是必需的,你可以想象设备名称是你的工作站名称,机器人名称等。itemid是outpuarguments它返回那个设备的指针。
在这个例子中,我收到了我的ABB机器人的项目ID(指针),命名为“ABB_RB1”。
如果项目名称无效或在您的站点中不存在,则返回0。
getJonits是一个方法,它允许用户根据Item ID从站点获取机器人的关节值。
Item ID是Item的指针值,您可以从getItem()方法中获取它。
我们将以“ABB_RB1”项目名称获取项目ID,并返回一个UInt64值。
在传递Item ID的方法中返回关节值,该方法是在前面的方法中获得的。
getJointsStr是一个允许用户基于字符串值获取关节值的方法。
我们可以在这个方法中传递Robot name (String)。
在My Station中,ABB_RB1是我的机器人的名字。
我们只需在Robot name参数中传递“ABB_RB1”,然后调用该方法-返回字符串格式的关节值。
setJointsStr是一个方法,它允许用户基于字符串值设置机器人的关节值。
在Robot name中,传递的是ABB_RB1,我们可以在joint参数中传递一个带有关节值的字符串。
例如:-0.000000,0.000000,-0.000000,-0.000000,-0.0,-0.000000
现在我们可以通过I/O b> Devices b>插入OPC UA客户端。
在“OPC >OK”中选择“虚拟OPC UA设备”。
插入OPC UA Virtual。
我们需要添加OPC UA Client来访问RoboDK OPC UA Server。
选择设备1 >右键单击>添加新项。
选择“OPC UA客户端(模块)”,单击“确定”。
插入OPC UA客户端。
打开OPC UA客户端>转到设置选项卡>,单击“选择端点”,配置您想要访问的OPC UA服务器端点。
输入RoboDK OPC UA服务器URL,单击“更新”。
单击“Add Nodes”,浏览OPC UA服务器内部的节点。
如果TwinCAT与OPC UA服务器连接成功,则可以浏览OPC UA服务器的详细信息。
选择所有的方法和确定。
方法插入到配置中。
在此字段中配置您的名称前缀。
按“创建Plc代码”从TwinCAT创建Plc代码。
在您的项目中创建一个OpcUaClient文件夹,并且所有RoboDK Method都以IEC61131-3功能块格式创建。
本节展示了Beckhoff TwinCAT PLC与RoboDK OPC UA服务器通信的示例程序。
项目主要
VAR
bConnected: BOOL;
StationPointer:力;
iStep: INT;
bStart: BOOL;;
我:INT;
吨:吨;
bReset: BOOL;
bWrite: BOOL;
TON2:吨;
bShow: BOOL: = TRUE;
英属维尔京群岛:BOOL: = True;
END_VAR
VAR
Robot_name: STRING(80): =“ABB_RB1”;
Item_ID: ULINT;
arrJoints: ARRAY [0 . .LREAL 11);
strJoints:字符串(80):= ";
arrJointsFromStr: ARRAY [1 . .LREAL 11);
sSeparator:STRING(1):= ',';
arrJointsCommand: ARRAY [1 . .LREAL 11);
strJointsCommand:字符串(80);
END_VAR
VAR常数
cStepWaitCmd: INT: = 0;
cStepInit: INT: = 5;
cStepGetItem: INT: = 10;
cStepGetItemReset: INT: = 20;
cStepGetItemError: INT: = 990;
cStepGetJoints: INT: = 30;
cStepGetJointsReset: INT: = 40;
cStepGetJointsError: INT: = 991;
cStepGetJointsStr: INT: = 50;
cStepGetJointsStrReset: INT: = 60;
cStepGetJointsStrError: INT: = 992;
cStepSetJointStrDelay: INT: = 69;
cStepSetJointsStr: INT: = 70;
cStepSetJointsStrReset: INT: = 80;
cStepSetJointsStrError: INT: = 993;
cStepEnd: INT: = 300;
cStepWaitReset: INT: = 999;
END_VAR
VAR
aSplit: ARRAY [1 . .[11] of string (80);
bResultSplit: BOOL;
调试: BOOL;
URL:字符串:= ' http://192.168.3.42:8091 ';
END_VAR
bConnected: = OPCUA_VirtualClient_RoboDK_Station.bConnected;
案例1 .步骤1
cStepWaitCmd:
如果启动,那么
iStep: = cStepInit;
bStart: = FALSE;
END_IF
cStepInit:
StationPointer: = 0;
对于i:=1到11
arrJoints[我]:= 0.0;
arrJointsFromStr[我]:= 0.0;
aSplit[我]:= ";
END_FOR
如果不是,OPCUA_VirtualClient_RoboDK_Station.getItem.bBusy
而不是opcua_virtualclient_robodk_station . getitem . error
而不是OPCUA_VirtualClient_RoboDK_Station.getJoints.bBusy
而不是opcua_virtualclient_robodk_station . getjoints . error
而不是OPCUA_VirtualClient_RoboDK_Station.getJointsStr.bBusy
而不是opcua_virtualclient_robodk_station . getjointsstr . error
而不是OPCUA_VirtualClient_RoboDK_Station.setJoints.bBusy
而不是opcua_virtualclient_robodk_station . setjoints . error
而不是OPCUA_VirtualClient_RoboDK_Station.setJointsStr.bBusy
而不是opcua_virtualclient_robodk_station . setjointsstr . error
然后
iStep: = cStepGetItem;
END_IF
iStep: = cStepGetItem;
cStepGetItem:
如果OPCUA_VirtualClient_RoboDK_Station.getItem。bDone然后
iStep: = cStepGetItemReset;
Item_ID: = OPCUA_VirtualClient_RoboDK_Station.getItem.Item_ID;
ELSIF OPCUA_VirtualClient_RoboDK_Station.getItem。bError然后
iStep: = cStepGetItemError;
END_IF
cStepGetItemReset:
如果不是,opcua_virtualclient_robodk_station . getitem . error
而不是OPCUA_VirtualClient_RoboDK_Station.getItem.bBusy
然后
iStep: = cStepGetJoints;
END_IF
cStepGetJoints:
如果OPCUA_VirtualClient_RoboDK_Station.getJoints.bDone
而不是OPCUA_VirtualClient_RoboDK_Station.getJoints.bBusy
然后
iStep: = cStepGetJointsReset;
ELSIF OPCUA_VirtualClient_RoboDK_Station.getJoints。bError然后
iStep: = 991;
END_IF
cStepGetJointsReset:
如果不是,opcua_virtualclient_robodk_station . getitem . error
而不是OPCUA_VirtualClient_RoboDK_Station.getItem.bBusy
然后
iStep: = cStepGetJointsStr;
END_IF;
cStepGetJointsStr:
如果OPCUA_VirtualClient_RoboDK_Station.getJointsStr.bDone
而不是OPCUA_VirtualClient_RoboDK_Station.getJointsStr.bBusy
然后
iStep: = cStepGetJointsStrReset;
ELSIF OPCUA_VirtualClient_RoboDK_Station.getJointsStr。bError然后
iStep: = cStepGetJointsStrError;
END_IF
cStepGetJointsStrReset:
如果不是,opcua_virtualclient_robodk_station . getjointsstr . error
而不是OPCUA_VirtualClient_RoboDK_Station.getJointsStr.bBusy
然后
iStep: = cStepSetJointStrDelay;
END_IF;
cStepSetJointStrDelay:
strJointsCommand: = ";strJointsCommand: = CONCAT (LREAL_TO_STRING (arrJointsCommand [1]), strJointsCommand);
strJointsCommand: = CONCAT (strJointsCommand ', ');
strJointsCommand: = CONCAT (strJointsCommand LREAL_TO_STRING (arrJointsCommand [2]));
strJointsCommand: = CONCAT (strJointsCommand ', ');
strJointsCommand: = CONCAT (strJointsCommand LREAL_TO_STRING (arrJointsCommand [3]));
strJointsCommand: = CONCAT (strJointsCommand ', ');
strJointsCommand: = CONCAT (strJointsCommand LREAL_TO_STRING (arrJointsCommand [4]));
strJointsCommand: = CONCAT (strJointsCommand ', ');
strJointsCommand: = CONCAT (strJointsCommand LREAL_TO_STRING (arrJointsCommand [5]));
strJointsCommand: = CONCAT (strJointsCommand ', ');
strJointsCommand: = CONCAT (strJointsCommand LREAL_TO_STRING (arrJointsCommand [6]));
TON2 (: = TRUE, PT: = T # 0.2秒);
如果TON2。问那么
TON2 (: = FALSE);
iStep: = cStepSetJointsStr;
END_IF
cStepSetJointsStr:
如果(
OPCUA_VirtualClient_RoboDK_Station.setJointsStr.bDone
而不是
OPCUA_VirtualClient_RoboDK_Station.setJointsStr.bBusy
)
还是不写
然后
iStep: = cStepSetJointsStrReset;
ELSIF OPCUA_VirtualClient_RoboDK_Station.setJointsStr.bError
然后
iStep: = cStepSetJointsStrError;
END_IF
cStepSetJointsStrReset:
bWrite: = FALSE;
OPCUA_VirtualClient_RoboDK_Station.setJointsStr.bExecute: = FALSE;
如果不是,opcua_virtualclient_robodk_station . setjointsstr . error
而不是OPCUA_VirtualClient_RoboDK_Station.setJointsStr.bBusy
然后
iStep: = cStepEnd;
END_IF;
cStepEnd:
吨(:= TRUE, PT: = T # 0.1秒);
如果吨。问那么
吨(:= FALSE);
如果没有调试,则
iStep: = 10;
其他的
iStep: = cStepSetJointStrDelay;
END_IF;
END_IF
cStepGetItemError:
Item_ID: = 0;
iStep: = cStepWaitReset;
cStepGetJointsError:
对于i:=0到11
arrJoints[我]:= -99999.99;
END_FOR
iStep: = cStepWaitReset;
cStepGetJointsStrError:
strJoints: = ";
iStep: = cStepWaitReset;
cStepWaitReset:
如果布雷塞,那么
iStep: = cStepInit;
bReset: = FALSE;
END_IF;
END_CASE
aSplit[1]:= strjoint;
对于i:=1到7
bResultSplit:= FindAndSplit(
pSeparator:= ADR(sSeparator)
,pSrcString:= ADR(aSplit[i])
pLeftString: = ADR (aSplit[我])
,nLeftSize:= SIZEOF(aSplit[i])
pRightString: = ADR (aSplit (i + 1))
,nRightSize:= SIZEOF(aSplit[1 +1])
,bSearchFromRight:= FALSE);
如果不是bResultSplit,那么
退出;
END_IF
END_FOR
对于i:=1到6
arrJointsFromStr[我]:= STRING_TO_LREAL (aSplit[我]);
END_FOR;
//
OPCUA_VirtualClient_RoboDK_Station.getItem (
bExecute: = iStep = cStepGetItem
Item_Name: = Robot_name
);
OPCUA_VirtualClient_RoboDK_Station.getJoints (
bExecute: = iStep = cStepGetJoints
Item_ID: = Item_ID关节= > arrJoints
);
OPCUA_VirtualClient_RoboDK_Station.getJointsStr (
bExecute: = iStep = cStepGetJointsStr
Robot_name: = Robot_name关节= > strJoints
);
如果写的话
OPCUA_VirtualClient_RoboDK_Station.setJointsStr (
bExecute: = TRUE
Robot_name: = Robot_name关节:= strJointsCommand);
END_IF;