Mi prueba consistirá en crear un proyecto para SoftLogix en el que definiré un par de tags, OPC_BIT y OPC_DINT, que me servirán para probar la comunicación. En el SoftLogix no voy a hacer nada más, simplemente le transferiré el proyecto, lo pondre en modo Run y monitorizaré el contenido de los tags. Luego generaré un enlace OPC con el RSLinx y desde un programa en Visual Basic leeré y escribiré en los tags del PLC.
Para establecer una comunicación OPC necesitaré un servidor OPC, y Rockwell nos lo proporciona integrado con el RSLinx, pero ojo, deberemos asegurarnos de que no sea la versión lite. Recomiendo echar un vistazo a este documento Cómo obtener resultados con RSLinx Classic (pdf) donde se especifica para qué sirve cada versión de RSLinx.
En el ordenador donde tengo instalado Visual Basic he instalado RSLinx Classic. Con mi SoftLogix funcionando compruebo que lo detecta.
Para obtener acceso al PLC a través de OPC deberemos configurar un Topic, que es la definición de la ruta de acceso al controlador. Para ello vamos al menú de RSLinx y pulsamos sobre DDE/OPC → Topic Configuration... y aparecerá una ventana donde seleccionaremos nuestro controlador y le asignaremos un Topic, en mi caso PRUEBA_OPC.
Aceptamos y ya podemos cerrar el RSLinx. Para comprobar que nuestro servidor OPC funciona, Rockwell suministra la herramienta OPC Test Client (se instala conjuntamente con el RSLinx). La ejecutamos y vamos al menú Server → Connect...
Selecciono RSLinx OPC Server.
Ahora tenemos que añadir un grupo, vamos al menú Group → Add Group...
Le asignamos un nombre cualquiera y aceptamos.
Ya solo falta añadir Items (que serán nuestros tags), vamos al menú Item → Add Item...
En la ventana que aparece, en la parte inferior izquierda navegamos por el árbol del servidor OPC, seleccionamos dentro de nuestro Topic la opción online y a la derecha deberán mostrarse los tags de nuestro proyecto Logix5000. Selecciono el tag que me interese y pulso el botón Add Item.
Y ya podemos ver el contenido de nuestro tag. Si modificamos su valor desde el RSLogix5000 veremos en el OPC Test Client como varía.
Ya hemos comprobado que tenemos acceso por OPC a nuestro controlador. Ahora lo que voy a hacer es la misma operación pero desde un programa en Visual Basic.
Crearemos un proyecto en Visual Basic y, para tener acceso a las funciones de comunicación OPC, deberemos agregar, en mi caso, la referencia OPC DA Automation Wrapper 2.02 (OPCDAAuto.DLL) que estará disponible en mi ordenador al tener instalado el RSLinx. Esta referencia difiere según sea la versión de RSLinx de que dispongamos; según leo en el foro de control.com deberemos agregar RsLinxOPCAuto.DLL o incluso RsiOPCAuto.DLL si disponemos de versiones antiguas.
Comprobamos que en Espacios de nombres importados esté marcado RsiOPCAuto.
Con esto ya podemos empezar a programar. Voy a adaptar el código de la clase que programé en la entrada sobre OPC y WinAC:
Imports OPCAutomation
Public Class OPC_NdA 'OPC Notas de Automatización
'Objectos para establecer la comunicación OPC
Private WithEvents ServidorOPC As OPCServer
Private WithEvents GrupoOPC As OPCGroup
Private WithEvents GruposOPC As OPCGroups
Private ItemOPC() As OPCItem
Public Conectado As Boolean 'Para saber si la conexión está activada
'Si hay algún error se indica en estas variables
Public Mensaje As String
Public Detalle_Error As String
'Constructor
Public Sub New()
'Al crear el objeto, no estamos conectados
Conectado = False
End Sub
'Función para activar la conexión OPC
Public Function Conectar() As Boolean
'Si ya estoy conectado aviso y salgo.
If Conectado Then
Mensaje = "Error conexión OPC."
Detalle_Error = "Se ha intentado crear una conexión OPC cuando ya hay una creada."
Conectar = False
Exit Function
End If
Try
Mensaje = "Conectando con el servidor OPC..."
ServidorOPC = New OPCServer
ServidorOPC.Connect("RSLinx OPC Server")
Mensaje = "Añadiendo grupo al servidor OPC..."
GruposOPC = ServidorOPC.OPCGroups
GrupoOPC = GruposOPC.Add("Grupo1")
GrupoOPC.IsActive = True
GrupoOPC.UpdateRate = 1000
GrupoOPC.IsSubscribed = True
Mensaje = "Añadiendo Items al grupo..."
ReDim ItemOPC(100) 'Dimensionar según las necesidades
'Introducir un ítem por cada variable del PLC en la que queramos leer o escribir
'A cada ítem le asignamos un número, que debemos recordar para referirnos a él en el programa
ItemOPC(0) = GrupoOPC.OPCItems.AddItem("[PRUEBA_OPC]OPC_DINT", 0)
ItemOPC(1) = GrupoOPC.OPCItems.AddItem("[PRUEBA_OPC]OPC_BIT", 1)
Catch ex As Exception
Detalle_Error = "Error: " & ex.ToString
Conectado = False
Conectar = False
Exit Function
End Try
Mensaje = "Conexión OPC realizada correctamente."
Detalle_Error = ""
Conectado = True
Conectar = True
End Function
'Función para deshacer la conexión OPC
Public Function Desconectar() As Boolean
Try
Mensaje = "Desconectando..."
ItemOPC = Nothing
If Not IsNothing(ServidorOPC) Then
ServidorOPC.OPCGroups.RemoveAll()
ServidorOPC.Disconnect()
ServidorOPC = Nothing
End If
GrupoOPC = Nothing
GruposOPC = Nothing
Catch ex As Exception
Detalle_Error = "Error: " & ex.ToString
Desconectar = False
Exit Function
End Try
Mensaje = "Desconexión realizada correctamente."
Detalle_Error = ""
Conectado = False
Desconectar = True
End Function
'Función para escribir en un ítem que representa una variable entera
'Se le pasa el índice del ítem y el valor que vamos a escribir
'Si todo va bien devuelve True
Public Function EscribirItemInt(ByVal Indice As Integer, ByVal Entero As Integer) As Boolean
Dim Dims() As Integer = New Integer() {1}
Dim Bounds() As Integer = New Integer() {1}
Dim Serverhandles As Array = Array.CreateInstance(GetType(Integer), Dims, Bounds)
Dim Errores As Array = Array.CreateInstance(GetType(Integer), Dims, Bounds)
Dim Valores As Array = Array.CreateInstance(GetType(Object), Dims, Bounds)
If Not Conectado Then
Mensaje = "Error conexión OPC."
Detalle_Error = "No hay establecida una conexión OPC."
EscribirItemInt = False
Exit Function
End If
Try
Serverhandles.SetValue(ItemOPC(Indice).ServerHandle, 1)
Errores.SetValue(0, 1)
Valores.SetValue(Entero, 1)
GrupoOPC.SyncWrite(1, Serverhandles, Valores, Errores)
Catch ex As Exception
Detalle_Error = ex.ToString
Mensaje = "¡Error al escribir Item! [Int, Índice " & Indice & "]"
EscribirItemInt = False
Exit Function
End Try
Mensaje = ""
Detalle_Error = ""
EscribirItemInt = True
End Function
'Función para escribir en un ítem que representa una variable booleana
'Se le pasa el índice del ítem y el valor que vamos a escribir
'Si todo va bien devuelve True
Public Function EscribirItemBool(ByVal indice As Integer, ByVal Bit As Boolean) As Boolean
Dim Dims() As Integer = New Integer() {1}
Dim Bounds() As Integer = New Integer() {1}
Dim Serverhandles As Array = Array.CreateInstance(GetType(Integer), Dims, Bounds)
Dim Errores As Array = Array.CreateInstance(GetType(Integer), Dims, Bounds)
Dim Valores As Array = Array.CreateInstance(GetType(Object), Dims, Bounds)
If Not Conectado Then
Mensaje = "Error conexión OPC."
Detalle_Error = "No hay establecida una conexión OPC."
EscribirItemBool = False
Exit Function
End If
Try
Serverhandles.SetValue(ItemOPC(indice).ServerHandle, 1)
Errores.SetValue(0, 1)
Valores.SetValue(Bit, 1)
GrupoOPC.SyncWrite(1, Serverhandles, Valores, Errores)
Catch ex As Exception
Detalle_Error = ex.ToString
Mensaje = "¡Error al escribir Item! [Bool, Índice " & indice & "]"
EscribirItemBool = False
Exit Function
End Try
Mensaje = ""
Detalle_Error = ""
EscribirItemBool = True
End Function
'Función para leer un ítem que representa una variable entera
'Se le pasa el índice del ítem que vamos a leer
'Si todo va bien devuelve el valor de la variable
Public Function LeerItemInt(ByVal Indice) As Integer
Dim Valor As Object = Nothing
Dim Calidad As Object = Nothing
Dim TimeStamp As Object = Nothing
If Not Conectado Then
Mensaje = "Error conexión OPC."
Detalle_Error = "No hay establecida una conexión OPC."
LeerItemInt = 0
Exit Function
End If
Try
ItemOPC(Indice).Read(OPCDataSource.OPCDevice, Valor, Calidad, TimeStamp)
LeerItemInt = CInt(Valor.ToString)
Catch ex As Exception
Detalle_Error = ex.ToString
Mensaje = "¡Error al leer Item! [Int, Índice " & Indice & "]"
LeerItemInt = 0
Exit Function
End Try
Mensaje = ""
Detalle_Error = ""
End Function
'Función para leer un ítem que representa una variable booleana
'Se le pasa el índice del ítem que vamos a leer
'Si todo va bien devuelve el valor de la variable
Public Function LeerItemBool(ByRef Indice) As Boolean
Dim Valor As Object = Nothing
Dim Calidad As Object = Nothing
Dim TimeStamp As Object = Nothing
If Not Conectado Then
Mensaje = "Error conexión OPC."
Detalle_Error = "No hay establecida una conexión OPC."
LeerItemBool = 0
Exit Function
End If
Try
ItemOPC(Indice).Read(OPCDataSource.OPCDevice, Valor, Calidad, TimeStamp)
If StrComp(Valor.ToString, "True") = 0 Or Valor = 1 Then
LeerItemBool = True
Else
LeerItemBool = False
End If
Catch ex As Exception
Detalle_Error = ex.ToString
Mensaje = "¡Error al leer Item! [Bool, Índice " & Indice & "]"
LeerItemBool = False
Exit Function
End Try
Mensaje = ""
Detalle_Error = ""
End Function
End Class
Con respecto al código que hice para Siemens simplemente he cambiado en la función Conectar el servidor OPC a RSLinx OPC Server y he adaptado la lista de items.
Para introducir los items deberemos especificar el nombre del Topic que hayamos configurado en el RSLinx entre corchetes seguido del nombre del tag, por ejemplo:
ItemOPC(0) = GrupoOPC.OPCItems.AddItem("[PRUEBA_OPC]OPC_DINT", 0)
Las funciones para leer y escribir booleanos y enteros son las mismas que las programadas en el OPC de Siemens.
Ya solo nos queda crear una interfaz sencilla para probar la conexión:
Pulsando el botón Conectar se establecerá la conexión OPC y si todo va correctamente podremos escribir y leer valores en el tag OPC_DINT y cambiar el estado del booleano OPC_BIT.
El código de este sencillo programa lo tienes en este proyecto de Visual Basic.
Y hasta aquí esta toma de contacto con la tecnología OPC en Rockwell. No es un ejemplo elaborado, pero espero que pueda servir de punto de partida para aplicaciones más complejas.
Como siempre, agradeceré cualquier comentario.




























WinLC RTX es un controlador en tiempo real basado en el entorno PC, se comunica de forma remota con STEP 7 y SIMATIC Computing a través
ResponderSuprimirde redes PROFIBUS, MPI o Ethernet.
WinLC RTX es compatible con las herramientas de automatización de la gama de productos SIMATIC, p.ej. con el software de programación STEP 7 y WinCC de SIEMENS.
¿PODRIAS HACER UN EJEMPLO DE WinLC RTX + STEP 7 + WinCC de SIEMENS con Ethernet?
GRACIAS, JG.
Hola JG. Supongo que ya has visto en el blog las entradas sobre WinAC.
ResponderSuprimirNo creo que dedique ninguna entrada a WinCC, ya que es un software que nunca he visto y no lo tengo disponible.
Lo que sí tengo es un runtime de WinCC Flexible, que tengo pensado intalar en una máquina virtual y en un futuro lo usaré para alguna entrada del blog.
Un saludo y gracias por el interés.
un runtime de WinCC Flexible ???
ResponderSuprimirGR, puedes detallar mas el concepto?
GRACIAS, JG.
Hola JG.
ResponderSuprimirEl WinCC Flexible Runtime es un software que, instalado en un ordenador normal, te permite usarlo como un panel Simatic, programable con WinCC Flexible.
Más información aquí: https://www.automation.siemens.com/mcms/human-machine-interface/en/visualization-software/wincc-flexible/wincc-flexible-runtime/Pages/Default.aspx
Un saludo.