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;