Neste exemplo, você aprenderá a ativar o Add-in OPC UA e a converter o RoboDK em um servidor OPC UA. Navegaremos por algumas configurações usando o software UaExpert e o Beckhoff TwinCAT3 TF6100.
O Add-in OPC UA permite que você defina algumas configurações, como a porta do servidor. Você também pode optar por ativar o servidor, desativá-lo ou iniciar automaticamente com o RoboDK.
Com o Add-in OPC UA ativado, selecione OPC UA – Configurações OPC UA para definir suas configurações de OPC UA.
A tela Configurações OPC UA é exibida no lado esquerdo, conforme mostrado na imagem a seguir.
Se você vir uma mensagem como "Servidor RoboDK's OPC UA em execução na porta 4840", isso significa que o servidor OPC UA no RoboDK foi iniciado.
Você pode testar a conectividade OPC UA com qualquer estação RoboDK que tenha um ou mais robôs.
Você pode usar o software UaExpert para testar a conectividade com o Servidor RoboDK OPC UA.
Você pode fazer o download da versão gratuita do software UaExpert no site da Unified Automation: https://www.unified-automation.com/downloads/OPC UA-clients.html.
Inicie o UaExpert e clique no botão "+" para adicionar o servidor OPC UA do RoboDK.
Expanda o Custom Discovery e selecione a opção <Double clicks to Add Server.> para adicionar o Servidor RoboDK OPC UA.
Digite o URL do servidor OPC UA, opc.tcp://127.0.0.1:48440, que você configurou na etapa anterior.
Conecte o servidor OPC UA com a segurança "None".
O servidor está configurado.
Agora você pode se conectar ao Servidor RoboDK OPC UA a partir do UaExpert.
Você pode ver os nós e os métodos quando a conexão for estabelecida.
Há alguns nós dentro do servidor OPC UA do RoboDK que permitem que você troque algumas informações básicas sobre a sua estação.
O nó do RoboDK é um nó que fornece a versão real do seu software RoboDK.
A versão RoboDK 64 Bit v5.5.3.23031 foi usada neste exemplo.
Velocidade de simulação é um nó que mostra a velocidade de simulação real e permite que o usuário substitua a velocidade de simulação atual.
O valor do nó tem como referência a barra deslizante da velocidade de simulação.
A simulação atual pode ser lida a partir desse nó e pode substituir a velocidade da simulação.
O Nó Estação é um nó que permite ao usuário obter o nome atual da estação no RoboDK.
Como você vê abaixo, o nó Station é referenciado ao seu "Nome da Estação" no RoboDK.
Parâmetro da Estação e Valor da Estação são um par de nós que permite ao usuário obter ou definir qualquer parâmetro dentro da estação. O servidor OPC UA do RoboDK monitorará continuamente o valor real de "Parâmetro da estação" e retornará o valor desse "Parâmetro da estação", a partir do nó Valor da Estação.
Você pode visualizar os parâmetros da sua estação clicando com o botão direito do mouse na estação RoboDK > Parâmetros da estação.
No campo Parâmetros constantes, você pode ver os parâmetros padrão da estação e seus valores.
O parâmetro da estação é referenciado no campo "Parâmetro" e o valor da estação é referenciado no campo " Valor".
E podemos criar nossos próprios parâmetros clicando no botão "Adicionar".
Um novo parâmetro Estação foi adicionado.
Digite o nome do parâmetro e o valor do parâmetro e, em seguida, pressione Aplicar para salvá-lo.
Você também pode obter seu próprio parâmetro de estação.
O nó Hora é um nó que permite a você obter a hora atual da Estação RoboDK.
É retornado um valor com o formato DataHora.
E esse nó é atualizado continuamente.
O Servidor RoboDK OPC UA também é fornecido com alguns métodos para permitir que o usuário acesse os dados da estação RoboDK dinamicamente.
Podemos simplesmente clicar com o botão direito do mouse no Método > Chamada para executar o método.
ObterItem é um método que permite que o usuário obtenha o ponteiro do seu Item.
Para os ArgumentosDeEntrada, o Nome do Dispositivo é necessário, você pode imaginar que o Nome do Dispositivo é o nome da estação, o nome do robô, etc. E Item ID é o ArgumentosDeSaida que retorna o ponteiro desse dispositivo.
Neste exemplo, recebi o ID do item (ponteiro) do meu robô ABB denominado "ABB_RB1".
0 é retornado se o Item Name for inválido ou não existir em sua estação.
ObterEixos é um método que permite ao usuário obter o valor do ângulo dos eixos do robô na estação, com base na ID do item.
O ID do item é o valor do ponteiro do seu item e você pode obtê-lo no método ObterItem().
Obteremos a ID do item com esse nome de item "ABB_RB1", e um valor UInt64 será retornado.
O valor dos ângulos dos eixos é retornado ao passar o ID do item no método que obtivemos anteriormente.
ObterStrEixos é um método que permite ao usuário obter o valor dos ângulos dos eixos com base em um valor String.
Podemos passar o nome do robô (String) nesse método.
Em My Station, ABB_RB1 é o nome do meu robô.
Podemos simplesmente passar "ABB_RB1" no parâmetro do nome do robô e chamar o método - O valor conjunto no formato String é retornado.
DefinirStrEixos é um método que permite ao usuário definir o valor dos ângulos dos eixos do Robô, com base em um valor String.
No nome do robô, ABB_RB1 é passado, e podemos simplesmente passar uma string com o valor do ângulo no parâmetro Joints.
Por exemplo:-0.000000,0.000000,-0.000000,-0.000000,-0.0,-0.000000
Você pode usar o software TwinCAT 3 da Beckhoff para testar a conectividade com o Servidor RoboDK OPC UA.
Você pode começar criando o cliente OPC UA selecionando I/O > Devices > Add New Item.
Selecione Virtual OPC UA Device from OPC > OK.
OPC UA Virtual é inserido.
Precisamos adicionar um cliente OPC UA para acessar o servidor OPC UA do RoboDK.
Selecione Device 1 > Clique com o botão direito do mouse > Add New Item.
Selecione "OPC UA Client(Module)" e Ok.
O cliente OPC UA é inserido.
Abra o OPC UA Client > Vá para a guia Settings (Configurações) > Clique em "Select Endpoint" (Selecionar ponto final) para configurar o ponto final do OPC UA Server que você gostaria de acessar.
Digite o URL do servidor OPC UA do RoboDK e atualize-o.
Pressione "Add Nodes" (Adicionar nós) para procurar o nó que está dentro do servidor OPC UA.
Se a conexão entre o TwinCAT e o servidor OPC UA for estabelecida, você poderá procurar os detalhes do servidor OPC UA.
Selecione todos os métodos e clique em Ok.
Os métodos são inseridos em sua configuração.
Configure o prefixo do nome nesse campo.
Pressione "Create Plc Code" para criar o código PLC a partir do TwinCAT.
Uma pasta OpcUaClient é criada em seu projeto e todos os métodos do RoboDK são criados no formato de bloco de função IEC61131-3.
Esta seção mostra um programa de amostra de um PLC TwinCAT da Beckhoff que se comunica com o servidor RoboDK OPC UA.
PROGRAM MAIN
VAR
bConnected :BOOL;
StationPointer :DINT;
iStep :INT;
bStart :BOOL;;
i :INT;
TON :TON;
bReset :BOOL;
bWrite :BOOL;
TON2 :TON;
bShow :BOOL:=TRUE;
bVis :BOOL:=True;
END_VAR
VAR
Robot Name :STRING(80):='ABB_RB1';
Item_ID :ULINT;
arrJoints :ARRAY[0..11]DE LREAL;
strJoints :STRING(80):='';
arrJointsFromStr:ARRAY[1..11]OF LREAL;
sSeparador :STRING(1) := ',';
arrJointsCommand:ARRAY[1..11]OF LREAL;
strJointsCommand:STRING(80);
END_VAR
VAR CONSTANT
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;
debug :BOOL;
URL :STRING:='http://192.168.3.42:8091';
END_VAR
bConnected:=OPCUA_VirtualClient_RoboDK_Station.bConnected;
CASE iStep OF
cStepWaitCmd:
IF bStart THEN
iStep:=cStepInit;
bStart:=FALSE;
END_IF
cStepInit:
StationPointer:=0;
FOR i :=1 TO 11 DO
arrJoints[i]:=0.0;
arrJointsFromStr[i]:=0.0;
aSplit[i]:='';
END_FOR
IF NOT OPCUA_VirtualClient_RoboDK_Station.getItem.bBusy
E NÃO OPCUA_VirtualClient_RoboDK_Station.getItem.bError
AND NOT OPCUA_VirtualClient_RoboDK_Station.getJoints.bBusy
AND NOT OPCUA_VirtualClient_RoboDK_Station.getJoints.bError
AND NOT OPCUA_VirtualClient_RoboDK_Station.getJointsStr.bBusy
AND NOT OPCUA_VirtualClient_RoboDK_Station.getJointsStr.bError
AND NOT OPCUA_VirtualClient_RoboDK_Station.setJoints.bBusy
AND NOT OPCUA_VirtualClient_RoboDK_Station.setJoints.bError
AND NOT OPCUA_VirtualClient_RoboDK_Station.setJointsStr.bBusy
AND NOT OPCUA_VirtualClient_RoboDK_Station.setJointsStr.bError
ENTÃO
iStep:=cStepGetItem;
END_IF
iStep:=cStepGetItem;
cStepGetItem:
IF OPCUA_VirtualClient_RoboDK_Station.getItem.bDone THEN
iStep:=cStepGetItemReset;
Item_ID:=OPCUA_VirtualClient_RoboDK_Station.getItem.Item_ID;
ELSIF OPCUA_VirtualClient_RoboDK_Station.getItem.bError THEN
iStep:=cStepGetItemError;
END_IF
cStepGetItemReset:
IF NOT OPCUA_VirtualClient_RoboDK_Station.getItem.bError
AND NOT OPCUA_VirtualClient_RoboDK_Station.getItem.bBusy
ENTÃO
iStep:=cStepGetJoints;
END_IF
cStepGetJoints:
IF OPCUA_VirtualClient_RoboDK_Station.getJoints.bDone
AND NOT OPCUA_VirtualClient_RoboDK_Station.getJoints.bBusy
ENTÃO
iStep:=cStepGetJointsReset;
ELSIF OPCUA_VirtualClient_RoboDK_Station.getJoints.bError THEN
iStep:=991;
END_IF
cStepGetJointsReset:
IF NOT OPCUA_VirtualClient_RoboDK_Station.getItem.bError
AND NOT OPCUA_VirtualClient_RoboDK_Station.getItem.bBusy
ENTÃO
iStep:=cStepGetJointsStr;
END_IF;
cStepGetJointsStr:
IF OPCUA_VirtualClient_RoboDK_Station.getJointsStr.bDone
AND NOT OPCUA_VirtualClient_RoboDK_Station.getJointsStr.bBusy
ENTÃO
iStep:=cStepGetJointsStrReset;
ELSIF OPCUA_VirtualClient_RoboDK_Station.getJointsStr.bError THEN
iStep:=cStepGetJointsStrError;
END_IF
cStepGetJointsStrReset:
IF NOT OPCUA_VirtualClient_RoboDK_Station.getJointsStr.bError
AND NOT OPCUA_VirtualClient_RoboDK_Station.getJointsStr.bBusy
ENTÃO
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(IN:=TRUE,PT:=T#0.2S);
IF TON2.Q THEN
TON2(IN:=FALSE);
iStep:=cStepSetJointsStr;
END_IF
cStepSetJointsStr:
IF (
OPCUA_VirtualClient_RoboDK_Station.setJointsStr.bDone
E NÃO
OPCUA_VirtualClient_RoboDK_Station.setJointsStr.bBusy
)
OR NOT bWrite
ENTÃO
iStep:=cStepSetJointsStrReset;
ELSIF OPCUA_VirtualClient_RoboDK_Station.setJointsStr.bError
ENTÃO
iStep:=cStepSetJointsStrError;
END_IF
cStepSetJointsStrReset:
bWrite:=FALSE;
OPCUA_VirtualClient_RoboDK_Station.setJointsStr.bExecute:=FALSE;
IF NOT OPCUA_VirtualClient_RoboDK_Station.setJointsStr.bError
AND NOT OPCUA_VirtualClient_RoboDK_Station.setJointsStr.bBusy
ENTÃO
iStep:=cStepEnd;
END_IF;
cStepEnd:
TON(IN:=TRUE,PT:=T#0.1S);
IF TON.Q THEN
TON(IN:=FALSE);
IF NOT debug THEN
iStep:=10;
ELSE
iStep:=cStepSetJointStrDelay;
END_IF;
END_IF
cStepGetItemError:
Item_ID:=0;
iStep:=cStepWaitReset;
cStepGetJointsError:
FOR i :=0 TO 11 DO
arrJoints[i]:=-99999.99;
END_FOR
iStep:=cStepWaitReset;
cStepGetJointsStrError:
strJoints:='';
iStep:=cStepWaitReset;
cStepWaitReset:
IF bReset THEN
iStep:=cStepInit;
bReset:=FALSE;
END_IF;
END_CASE
aSplit[1] := strJoints;
FOR i:=1 TO 7 DO
bResultSplit := FindAndSplit(
pSeparator := ADR(sSeparator)
pSrcString := ADR(aSplit[i])
pLeftString:= ADR(aSplit[i])
nLeftSize := SIZEOF(aSplit[i])
pRightString:= ADR(aSplit[i+1])
nRightSize := SIZEOF(aSplit[i+1])
bSearchFromRight := FALSE );
IF NOT bResultSplit THEN
SAÍDA;
END_IF
END_FOR
FOR i :=1 TO 6 DO
arrJointsFromStr[i]:=STRING_TO_LREAL(aSplit[i]);
END_FOR;
//
OPCUA_VirtualClient_RoboDK_Station.getItem(
bExecute:=iStep=cStepGetItem
Item_Name:=Nome_do_robô
);
OPCUA_VirtualClient_RoboDK_Station.getJoints(
bExecute:=iStep=cStepGetJoints
Item_ID:=Item_ID,Joints=>arrJoints
);
OPCUA_VirtualClient_RoboDK_Station.getJointsStr(
bExecute:=iStep=cStepGetJointsStr
,Robot_name:=Robot_name,Joints=>strJoints
);
IF bWrite THEN
OPCUA_VirtualClient_RoboDK_Station.setJointsStr(
bExecute:=TRUE
, Robot_name:=Robot_name,Joints:=strJointsCommand);
END_IF;