Implementación con Beckhoff TwinCAT 3

Puede utilizar el software TwinCAT 3 de Beckhoff para probar la conectividad con el servidor OPC UA de RoboDK.

Añadir servidor TwinCAT3

Puede empezar creando el cliente OPC UA seleccionando E/S>Dispositivos>Añadir nuevo elemento.

OPC UA - Imagen 48

Seleccione Dispositivo OPC UA virtual de OPC >OK.

OPC UA - Imagen 49

Se inserta OPC UA Virtual.

OPC UA - Imagen 50

Necesitamos añadir un cliente OPC UA para acceder al servidor OPC UA de RoboDK.

Seleccione Dispositivo 1 >Clic derecho >Añadir nuevo elemento.

OPC UA - Imagen 51

Seleccione "Cliente OPC UA (Módulo)" y Aceptar.

OPC UA - Imagen 52

Se inserta el Cliente OPC UA.

OPC UA - Imagen 53

Configurar el servidor

Abra el cliente OPC UA >Vaya a la pestaña Configuración>haga clic en "Seleccionar punto final" para configurar el punto final del servidor OPC UA al que desea acceder.

OPC UA - Imagen 54

Introduzca la URL del servidor OPC UA de RoboDK y Actualícelo.

OPC UA - Imagen 55

Add RoboDK Server Method

Pulse "Añadir nodos" para examinar el nodo que se encuentra dentro del servidor OPC UA.

OPC UA - Imagen 56

Si se establece la conexión entre TwinCAT y el servidor OPC UA, puede examinar los detalles del servidor OPC UA.

OPC UA - Imagen 57

Seleccione todos los Métodos y Ok.

OPC UA - Imagen 58

Los métodos se insertan en su Configuración.

OPC UA - Imagen 59

Generar automáticamente el método RoboDK

Configure el prefijo de su nombre en este campo.

OPC UA - Imagen 60

Pulse "Crear Código Plc" para crear el Código PLC desde TwinCAT.

OPC UA - Imagen 61

Se crea una carpeta OpcUaClient en su proyecto y todos los métodos de RoboDK se crean en formato de bloque de función IEC61131-3.

OPC UA - Imagen 62

Ejemplo de programa PLC

Esta sección muestra un programa de ejemplo de un PLC TwinCAT de Beckhoff que se comunica con el servidor OPC UA de RoboDK.

PROGRAMA PRINCIPAL

VAR

   bConectado      :BOOL;

   StationPointer  :DINT;

   iPaso           :INT;

   bStart          :BOOL;;

   i               :INT;

   TON             :TON

   bReset          :BOOL;

   bEscribir       :BOOL;

   TON2            :TON

   bShow           :BOOL:=TRUE;

   bVis            :BOOL:=Verdadero;

FIN_VAR

 

VAR

   Nombre_robot          :CADENA(80):='ABB_RB1';

   ID_artículo           :ULINT;

   arrJoints       :ARRAY[0..11]DE LREAL;

   strJoints       :CADENA(80):='';

   arrJointsFromStr:ARRAY[1..11]OF LREAL;

   sSeparador      :CADENA(1) := ',';

   arrJointsComando:ARRAY[1..11]OF LREAL;

   strJointsComando:STRING(80);

FIN_VAR

 

VAR CONSTANTE

   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;

FIN_VAR

 

 

VAR

      aSplit :ARRAY[1..11] OF STRING(80);

      bResultadoSplit :BOOL;

        depurar         :BOOL;

     URL              :STRING:='http://192.168.3.42:8091';

FIN_VAR

bConectado:=OPCUA_VirtualClient_RoboDK_Station.bConectado;

 

CASO iStep DE

  

 

   cStepWaitCmd:

        IF bStart THEN

              iPaso:=cPasoInicio;

              bInicio:=FALSE;

        FIN_IF

  

   cStepInit:

 

        PunteroEstación:=0;

        FOR i :=1 TO 11 DO

              arrJoints[i]:=0,0;

              arrJointsFromStr[i]:=0.0;

              aSplit[i]:='';

        FIN_FOR

        IF NOT OPCUA_VirtualClient_RoboDK_Station.getItem.bBusy

              AND NOT 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

              ENTONCES

              iPaso:=cPasoGetItem;

        FIN_IF

        iPaso:=cPasoGetItem;

  

   cStepGetItem:

 

        IF OPCUA_VirtualClient_RoboDK_Station.getItem.bDone THEN

              iPaso:=cPasoGetItemReset;

        Item_ID:=OPCUA_VirtualClient_RoboDK_Station.getItem.Item_ID;

        ELSIF OPCUA_VirtualClient_RoboDK_Station.getItem.bError THEN

              iStep:=cStepGetItemError;

        FIN_IF

       

   cStepGetItemReset:

 

        IF NOT OPCUA_VirtualClient_RoboDK_Station.getItem.bError

              AND NOT OPCUA_VirtualClient_RoboDK_Station.getItem.bBusy

              ENTONCES

              iPaso:=cPasoGetJoints;

        FIN_IF

   cStepGetJoints:

 

        IF OPCUA_VirtualClient_RoboDK_Station.getJoints.bDone

              AND NOT OPCUA_VirtualClient_RoboDK_Station.getJoints.bBusy

              ENTONCES

              iStep:=cStepGetJointsReset;

        ELSIF OPCUA_VirtualClient_RoboDK_Station.getJoints.bError THEN

              iPaso:=991;

        FIN_IF

       

   cStepGetJointsReset:

 

        IF NOT OPCUA_VirtualClient_RoboDK_Station.getItem.bError

              AND NOT OPCUA_VirtualClient_RoboDK_Station.getItem.bBusy

       

              ENTONCES

              iStep:=cStepGetJointsStr;

        FIN_IF;

       

   cStepGetJointsStr:

 

        IF OPCUA_VirtualClient_RoboDK_Station.getJointsStr.bDone

              AND NOT OPCUA_VirtualClient_RoboDK_Station.getJointsStr.bBusy

              ENTONCES

              iStep:=cStepGetJointsStrReset;

        ELSIF OPCUA_VirtualClient_RoboDK_Station.getJointsStr.bError THEN

              iStep:=cStepGetJointsStrError;

        FIN_IF         

 

   cStepGetJointsStrReset:

 

        IF NOT OPCUA_VirtualClient_RoboDK_Station.getJointsStr.bError

              AND NOT OPCUA_VirtualClient_RoboDK_Station.getJointsStr.bBusy

              ENTONCES

                   iPaso:=cPasoSetJointStrDelay;

        FIN_IF;

       

   cStepSetJointStrDelay:

        strJointsComando:=''; strJointsComando:=CONCAT(LREAL_TO_STRING(arrJointsComando[1]),strJointsComando);

      strJointsComando:=CONCAT(strJointsComando,',');

   strJointsComando:=CONCAT(strJointsComando,LREAL_TO_STRING(arrJointsComando[2]));

      strJointsComando:=CONCAT(strJointsComando,',');

   strJointsComando:=CONCAT(strJointsComando,LREAL_TO_STRING(arrJointsComando[3]));

      strJointsComando:=CONCAT(strJointsComando,',');

   strJointsComando:=CONCAT(strJointsComando,LREAL_TO_STRING(arrJointsComando[4]));

      strJointsComando:=CONCAT(strJointsComando,',');

   strJointsComando:=CONCAT(strJointsComando,LREAL_TO_STRING(arrJointsComando[5]));

      strJointsComando:=CONCAT(strJointsComando,',');

   strJointsComando:=CONCAT(strJointsComando,LREAL_TO_STRING(arrJointsComando[6]));

        TON2(IN:=VERDADERO,PT:=T#0,2S);

        IF TON2.Q THEN

              TON2(IN:=FALSO);

              iPaso:=cPasoSetJointsStr;

        FIN_IF

  

   cStepSetJointsStr:

 

       

        SI (

        OPCUA_VirtualClient_RoboDK_Station.setJointsStr.bDone

              Y NO   

        OPCUA_VirtualClient_RoboDK_Station.setJointsStr.bBusy

         )

              OR NOT bEscribir

              ENTONCES

              iPaso:=cPasoSetJointsStrReset;

        ELSIF OPCUA_VirtualClient_RoboDK_Station.setJointsStr.bError           

          ENTONCES

              iStep:=cStepSetJointsStrError;

        FIN_IF    

             

   cStepSetJointsStrReset:

        bEscribir:=FALSE;

         OPCUA_VirtualClient_RoboDK_Station.setJointsStr.bExecute:=FALSE;

        IF NOT OPCUA_VirtualClient_RoboDK_Station.setJointsStr.bError

              AND NOT OPCUA_VirtualClient_RoboDK_Station.setJointsStr.bBusy

              ENTONCES

              iPaso:=cFinPaso;

        FIN_IF;

       

   cStepEnd:

        TON(IN:=VERDADERO,PT:=T#0,1S);

        IF TON.Q THEN

              TON(IN:=FALSE);

              IF NOT debug THEN

                   iPaso:=10;

              ELSE

                   iPaso:=cPasoSetJointStrDelay;

              FIN_IF;

        FIN_IF

       

   cStepGetItemError:

        Item_ID:=0;

        iPaso:=cPasoEsperarReinicio;

  

   cStepGetJointsError:

        FOR i :=0 TO 11 DO

              arrJoints[i]:=-99999.99;

        FIN_FOR

        iPaso:=cPasoEsperarReinicio;

       

   cStepGetJointsStrError:

        strJoints:='';

        iPaso:=cPasoEsperarReinicio;

       

   cStepWaitReset:

        IF bReset THEN

              iPaso:=cPasoInicio;

              bReinicio:=FALSE;

        FIN_IF;   

FIN_CASE

 

aSplit[1] := strJoints;

 

FOR i:=1 TO 7 DO

    bResultadoSplit := BuscarYSplit(

   pSeparador := ADR(sSeparador)

   ,pSrcString := ADR(aSplit[i])

   ,pCadenaIzquierda:= ADR(aSplit[i])

   ,nTamañoIzquierda := TAMAÑO(aSplit[i])

   ,pCadenaDerecha:= ADR(aSplit[i+1])

   ,nTamañoDerecho := SIZEOF(aSplit[i+1])

   ,bBuscarDesdeDerecha := FALSE );

    IF NOT bResultadoSplit THEN

        SALIDA

    FIN_IF

FIN_FOR

 

PARA i :=1 A 6 HACER

   arrJointsFromStr[i]:=STRING_TO_LREAL(aSplit[i]);

FIN_FOR;

 

//

OPCUA_VirtualClient_RoboDK_Station.getItem(

bExecute:=iStep=cStepGetItem

,Nombre_del_artículo:=Nombre_del_robot

);

 

 

OPCUA_VirtualClient_RoboDK_Station.getJoints(

bEjecutar:=iPaso=cPasoGetJoints

,Item_ID:=Item_ID,Juntas=>arrJuntas

);

 

 

OPCUA_VirtualClient_RoboDK_Station.getJointsStr(

bExecute:=iStep=cStepGetJointsStr

,Nombre_robot:=Nombre_robot,Juntas=>strJuntas

);

 

IF bWrite THEN

OPCUA_VirtualClient_RoboDK_Station.setJointsStr(

   bEjecutar:=TRUE

,Nombre_robot:=Nombre_robot,Juntas:=strComandoJuntas);

FIN_IF;