3 de octubre de 2011

Accediendo a un PLC Simatic a través de ethernet con Libnodave

En esta entrada usé la biblioteca libre Libnodave para acceder a un PLC S7-300 desde Visual Basic a través de un adaptador serie/MPI. Varios lectores me hicieron consultas sobre si era posible usarla para acceder a un PLC S7-300/400 a través de ethernet, pero al no tener disponible un controlador adecuado para hacer pruebas pues no tenía respuesta. Sin embargo, de la entrada anterior tengo preparada una máquina virtual con WinAC RTX y su puerto ethernet como puerto de comunicaciones, que creo que es un banco de pruebas ideal para hacer pruebas con Libnodave.

Lo primero que voy a hacer es un proyecto en Step7 con un único DB, por ejemplo el DB10, con un único dato de formato BYTE. Lo transferiero al WinAC y pongo el PLC software en modo Run. Me pongo on line y monitorizo la variable.


En el PLC no voy a tocar nada más. A continuación lo que haré será una aplicación en Visual Basic, usando la biblioteca Libnodave a través de ethernet, que se conectará al PLC y leerá y escribirá en esa variable como prueba que el sistema funciona.

El aspecto que tendrá mi aplicación puede ser algo tan sencillo como esto:


Para realizar la conexión es nesaria una dirección IP (en mi caso la de la máquina virtual donde tengo el WinAC), un número de puerto (que según la documentación de Libnodave debe ser el 102), un número de rack (lo habitual aquí es un cero) y un número de slot (que será el número de slot donde tengamos configurado el PLC, lo podemos ver en la configuración hardware, en mi caso el dos). La programación en Visual Basic va ser muy parecida a la que hice en esta entrada, uso la misma biblioteca de la misma forma así que no repito aquí el procedimiento para incluirla en el proyecto. He adaptado la clase que creé en su momento para encapsular las funciones de acceso al PLC a través de ethernet, quedando de la siguiente manera:
Public Class Libnodave_WinAC
Dim daveSerie As libnodave.daveOSserialType
Dim daveInter As libnodave.daveInterface
Dim daveConex As libnodave.daveConnection

Public BufferLectura(1000) As Byte
Public BufferEscritura(1000) As Byte

Public Conectado As Boolean = False
Public Mensaje As String

Public Function Conectar(Optional ByVal Puerto As Integer = 102, _
Optional ByVal IP As String = "192.168.65.18", _
Optional ByVal Rack As Integer = 0, _
Optional ByVal Slot As Integer = 2) As Boolean
If Conectado Then
Mensaje = "Conexión abortada, ya existe una conexión."
Conectar = False
Exit Function
End If

Dim Respuesta As Integer

Mensaje = "Abriendo una conexión serie..."
daveSerie.rfd = libnodave.openSocket(Puerto, IP)
daveSerie.wfd = daveSerie.rfd

If daveSerie.rfd > 0 Then
Mensaje = "Conexión OK, creando interface..."

daveInter = New libnodave.daveInterface(daveSerie, "", _
0, _
libnodave.daveProtoISOTCP, _
libnodave.daveSpeed187k)

daveInter.setTimeout(1000000) 'Make this longer if you have a very long response time

Mensaje = "Inicialización del adaptador OK, creando conexión..."
daveConex = New libnodave.daveConnection(daveInter, 0, Rack, Slot)
Respuesta = daveConex.connectPLC()

If Respuesta = 0 Then
Mensaje = "Conexión correcta, lista para operar."
Conectado = True
Else
libnodave.closeSocket(daveSerie.rfd)
Mensaje = "Error al abrir la conexión [" & _
libnodave.daveStrerror(Respuesta) & "]"
Conectado = False
End If

Else
Mensaje = "Error al abrir la conexión"
Conectado = False
End If

Conectar = Conectado

End Function

Public Function Desconectar() As Boolean
If Conectado Then
daveConex.disconnectPLC()
libnodave.closeSocket(daveSerie.rfd)
Conectado = False
Mensaje = "Conexión correctamente terminada."
Desconectar = True
Else
Mensaje = "No existe conexión activa."
Desconectar = False
End If
End Function

Public Function LeerBytesDB(ByVal NumDB As Integer, _
ByVal Dir As Integer, _
ByVal NumBytes As Integer) As Boolean

Dim Respuesta As Integer

Respuesta = daveConex.readBytes(Libnodave.daveDB, NumDB, Dir, NumBytes, BufferLectura)

If Respuesta = 0 Then
Mensaje = "Leídos " & NumBytes & " bytes a partir de la dirección " & _
Dir & " en el DB " & NumDB
LeerBytesDB = True
Else
Mensaje = "Error al leer " & NumBytes & " bytes a partir de la dirección " & _
Dir & " en el DB " & NumDB
LeerBytesDB = False
End If

End Function

Public Function EscribirBytesDB(ByVal NumDB As Integer, _
ByVal Dir As Integer, _
ByVal NumBytes As Integer) As Boolean
Dim Respuesta As Integer

Respuesta = daveConex.writeBytes(Libnodave.daveDB, NumDB, Dir, NumBytes, BufferEscritura)

If Respuesta = 0 Then
Mensaje = "Escritos " & NumBytes & " bytes a partir de la dirección " & _
Dir & " en el DB " & NumDB
EscribirBytesDB = True
Else
Mensaje = "Error al escribir " & NumBytes & " bytes a partir de la dirección " & _
Dir & " en el DB " & NumDB
EscribirBytesDB = False
End If

End Function

End Class
Lo que he hecho es cambiar el protocolo serie por el protocolo ethernet. Su uso es muy sencillo, a la función Conectar se le pasan la dirección IP, el puerto, el rack y el slot. Si no hay error, con las funciones LeerBytesDB y EscribirBytesDB accedemos a datos almacenados en cualquier DB de la memoria del PLC (son exactamente las mismas funciones que en la versión serie). Al acabar debemos desconectarnos con la función Desconectar. La clase se podría completar con funciones para acceder a otras zonas de memoria permitidas por Libnodave.

Ejecuto mi aplicación, pongo los parámetros de conexión y pulso Conectar. Si todo va bien me pondrá un mensaje que el enlace está realizado. Con los botones de lectura y escritura puedo ver como modifico y leo el contenido del DB10 en mi PLC.


Si nos equivocamos al dar la dirección IP o el puerto, nos dará error. Sin embargo si ponemos un rack o slot incorrectos, puede que nos diga que la conexión está correcta, pero evidentemente no lograremos leer ni escribir nada.

Si quieres ver el código completo de este sencillo proyecto, lo tienes aquí. Si además quieres echar un vistazo a la configuración de Step7 que he usado, descárgate este proyecto.

Aunque esta prueba está hecha sobre un WinAC en una máquina virtual, pienso que el código servirá para acceder a un PLC S7-300/400 con puerto ethernet. Si algún lector hace la prueba, le agradeceré una reseña en los comentarios.

Este es un ejemplo muy sencillo, símplemente para comprobar que Libnodave funciona y es sencillo de usar. Ahora mismo se me ocurren un par de antiguos proyectos en los que podría haber usado Libnodave, consiguiendo abaratar su coste, al ahorrarnos licencias. Sin embargo no debemos olvidar que Libnodave, a pesar de su buen desempeño, no tiene una empresa detrás que nos de garantía o soporte, y que si lo usamos es por nuestra cuenta y riesgo.

Como siempre, agradeceré cualquier comentario.

59 comentarios:

  1. Gracias de nuevo por tus articulos !

    Conocí LIBNODAVE gracias a ti, pero siempre he tenido un problema, la libreria dll de libnodave no puedo compilarla al crear el "instalador" desde visual basic, tienes alguna solucion ?

    Gracias de nuevo

    ResponderEliminar
    Respuestas
    1. Puedes ponerla en el directorio system32 de windows. y no necesitas compilarla para usarla en tu equipo local
      Para una instalación puedes añadirsela manualmente en el proceso de crear el setup y te la pondra en dicho directorio

      Eliminar
  2. Cuando tengo problemas de una dll lo que hago es ponerla en el mismo directorio donde está el ejecutable. Lo ideal sería que un instalador te la metiese en el sistema para no tener que ir arrastrándola.

    Creo que te refieres a eso.

    Un saludo y gracias por el interés.

    ResponderEliminar
  3. Hola

    Madre mia parece que me leyeras el pensamiento.

    Precisamente tengo que generar unos informes en excel de datos de produccion contenidos en un DB.

    Ya conocia la libreria pero nunca la habia usado y no sabia si funcionaria por Ethernet.

    De todas maneras, hay otra libreria que incorpora libnodave y que viene con bastante documentacion y ejemplos en .NET (yo soy mas de C#)

    http://siemensplctoolboxlib.codeplex.com/

    Esta es la que voy a usar proximamente.

    PD: Por cierto que luego he visto la otra entrada de OPC con RS Logix y adivina que tengo que hacer tambien....

    Pues eso generar los mismos informes Excel usando OPC y el RSLInx Classic :)))))

    Un saludo y como siempre los articulos geniales.

    ResponderEliminar
  4. Hola Ragundo, me alegra que lo que escribo te sea de utilidad. Y gracias por el enlace, le echaré un vistazo.

    ResponderEliminar
  5. PODRIAS ACLARAR MAS AL DETALLE LO DEL RACK Y LO DEL SLOT, PORQUE LO DEL RACK ME SUENA A LOS ARMARIOS DE TELECOMUNICACIONES, Y EN ESTE CASO HABLAMOS DE PLC, MUCHAS GRACIAS. JG
    ¿¿¿¿¿¿¿¿
    un número de rack (lo habitual aquí es un cero) y un número de slot (que será el número de slot donde tengamos configurado el PLC, lo podemos ver en la configuración hardware, en mi caso el dos) ??????

    ResponderEliminar
  6. Cuando realizas la configuración hardware de un proyecto de Step7, el primer paso es añadir un bastidor. Entiendo que el número de rack es el número de bastidor, y como lo habitual es tener solamente uno (nunca me he topado con un proyecto con múltiples bastidores), le corresponderá el número cero.

    Dentro de cada bastidor hay una serie de huecos donde poner los distintos componentes. Cada uno de estos huecos es un slot. El slot uno suele estar reservado para una fuente de alimentación y en el dos suele colocarse el PLC.

    Espero haber aclarado tu duda, un saludo.

    ResponderEliminar
  7. ACLARADO, MUY BIEN.
    SENCILLEZ, CLARIDAD, CALIDAD, BUENOS ARTICULOS.
    MUCHAS GRACIAS. JG

    ResponderEliminar
  8. Por si ha alguien le resulta interesante, he logrado leer y escribir datos a un S7-1200 utilizando la libreria Libnodave y el código expuesto en este articulo.
    No hay que hacer modificación alguna al código en VB, simplemente configurar el Rack = 0 y el Slot = 1. Respecto al PLC, en el STEP 7 BASIC hay que controlar que los DBs que vayamos a leer o escribir NO hayan sido creados "solo para acceso simbólico".
    Espero mi comentario sea de utilidad.

    Gracias por artículos tan buenos como estos!

    Saludos.

    ResponderEliminar
    Respuestas
    1. hola, me llamo mucho la atención tu comentario, estoy programando un s7 1200 y utilizando la librería que amablemente nos compartió GR, ya puedo conectar el PLC pero aun no me es posible recibir ni enviar ningún dato, con respecto a lo que dices de los DB no encuentro esa opción "solo para acceso simbólico" supongo ese es lo que ocasiona no pueda leer ni escribir datos, estoy utilizando TIA PORTAL v12, lo que quisiera hacer es que los datos de una señal analógica los pueda guardar en excel o cualquier otro programa, espero tu ayuda ya que soy nuevo en esto.. saludos cordiales

      Eliminar
  9. Muchas gracias amigo anónimo por tu aporte, estoy seguro de que a más de uno le resultará de utilidad.

    ResponderEliminar
  10. ANONIMO DIJO:

    hay que controlar que los DBs que vayamos a leer o escribir NO hayan sido creados "solo para acceso simbólico".

    SI SE PONE:

    L valores.N1

    Acceso simbólico a la variable
    n1. “valores” es el nombre simbólico
    del DB que contiene dicha variable.

    ENTONCES QUEDARIA ASI ?

    L N1

    Acceso a la variable n1.

    PUEDEN DEFINIRLO MAS CLARAMENTE, GRACIAS.JG

    ResponderEliminar
  11. Saludos,

    me dejaron un proyecto que me parecia colosal hasta que encontré tu ejemplo, te lo agradezco mucho.

    veras actualmente leo y escribo el plc desde una película flash empotrada en mi vb.
    yo realmente no se mucho de plc solo he recibido un curso de LOGO de siemens por con esto he leido y escritro las entradas fisicas de maravilla.

    tengo una pregunta. quisiera poder llevar mas lejos y tener lecturas analogicas, save si debería diferir en algo o me puedes orientar??

    ResponderEliminar
  12. Hola CH4V3Z,

    No veo ningún inconveniente en tener lecturas analógicas, de hecho con libnodave puedes leer del área de entradas directamente.

    Un saludo.

    ResponderEliminar
  13. Hola me parece genial tu trabajo. Lo estoy probando pero tengo un pequeño problemilla.

    Quiero hacer la conexión con un PLC en remoto mediante una VPN. Levanto la VPN y establezco correctamente la comunicación con el automata, el problema es cuando quiero leer de un DB que no lo consigo, me da error y no obtengo los datos.

    ResponderEliminar
  14. Si en conexión directa te funciona bien quizá exista alguna incompatibilidad. Nunca he usado una VPN y lamento no poder resultar de ayuda.

    Un saludo.

    ResponderEliminar
  15. Hola GR ya he conseguido que funcionará a través de una VPN. Como aporte decir que si levantas una VPN contra el autómata a través de dos routers con el ejemplo que ha aportado nuestro amigo GR puedes obtener los datos del PLC remotamente.

    Tan sólo tengo una pregunta porque me pasa algo curioso y es lo siguiente.

    Estoy leyendo varias variables de un bloque de varios DBs, el buffer de lectura lo tengo con 200 posiciones por ejemplo, la primeras veces lee bien pero tras varias repeticiones deja de leer y la respuesta da el código -1025 que no he logrado interpretar que es. Yo creo que es como si se llenará el buffer pero corrígeme si me equivoco en cada lectura se sobrescriben los datos o se guardan al final del último dato existente en el buffer.
    Otra cosa que me llama la atención es que si cierro la conexión después de una lectura y la abro antes nunca falla.

    ResponderEliminar
  16. Según lo he programado, en cada lectura guarda los datos desde el principio del buffer. Prueba a ampliar el buffer, no vayas a estar leyendo más bytes de los que caben.

    Un saludo.

    ResponderEliminar
  17. GR, si quisiera hacer mi propio programador de PLC es decir enviar el archivo con el código awl podría hacerlo usando esta libreria?

    ResponderEliminar
    Respuestas
    1. Según pone en la página de libnodave: Can load program blocks into 300/400 CPUs

      Así que lo que planteas es posible, pero nunca le he intentado.

      Un saludo.

      Eliminar
  18. Amigo tengo problemas para conectar con un Logo Oba7, puedes ayudarme porfavor

    ResponderEliminar
    Respuestas
    1. No tengo experiencia con los Logo. Prueba a poner tu consulta en http://www.infoplc.net/foro/ o http://automatas.org/foro/, eso sí, explica los detalles de tu problema. En estos foros suele haber gente dispuesta a echar una mano.

      Un saludo.

      Eliminar
  19. Hola, lo primero gracias por el aporte y te quería preguntar como se podrían leer y escribir variables reales o booleanas mediante esta libreria; no tengo mucha idea como te puedes dar cuenta jaja. graias de antemano

    ResponderEliminar
  20. Hola queria hacerte otra pregunta: ¿como puedo acceder al bit M0.0 de un bloque por ejemplo OB1? Creo haber visto que se puede hacer algo con daveFlags pero no se muy bien como utilizarlo. Gracias

    ResponderEliminar
    Respuestas
    1. Creo que no tienes muy claro el direccionamiento en Step7. Las marcas como la M0.0 no pertenecen a ningún OB, son accesibles desde cualquier parte de programa. Y sí, con libnodave puedes acceder al área de marcas con la opción daveFlags.

      Un saludo.

      Eliminar
  21. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
    Respuestas
    1. En la web de libnodave mencionan que están trabajando en una biblioteca java, pero no dan mucha información.

      Un saludo.

      Eliminar
  22. GR, muchas gracias por tus respuestas y el tiempo que te tomas en redactarlas y transmitirlas.
    Puedes por favor ayudarme con esto?: Como hago para leer o escribir una variable en el PLC, digamos por ejemplo MD0, ya se que la sentencia
    -> Respuesta = daveConex.writeBytes(Libnodave.daveFlags, NumDB, Dir, NumBytes, BufferEscritura) <-
    intercambia datos con el PLC, pero como se que valores poner en NumDB y Dir ?

    Te agradecería mucho cualquier explicación básica que pudieras darme...

    Un saludo cordial!

    ResponderEliminar
    Respuestas
    1. En mi ejemplo solo leo de bloques de datos (DB). Si quieres leer la MD0 tienes que modificar el código para que lea del área de marcas.

      Otra opción es copiar la MD0 a una variable dentro de un DB y acceder a esta.

      Un saludo.

      Eliminar
  23. GR, muchas gracias, lo solucione copiando MD0 a una variable dentro de un DB, como lo mencionas en tu respuesta. Es mas fácil acceder a los datos del plc de esta forma.

    ResponderEliminar
  24. GR é possível converter o software WinAC para Visual Studio 2008 e me enviar???
    Gostaria de comunicar com S7-1200 (Ethernet)!!
    Por favor, ajude-me!!

    ResponderEliminar
    Respuestas
    1. Con el código de esta entrada no deberías tener problemas. Yo nunca he comunicado con un 1200, pero en un comentario de esta misma entrada un lector nos cuenta que funciona.

      Un saludo.

      Eliminar
    2. Usa el modo de conexion ISO TCP para un autómata de la serie 1200. Yo lo he probado con uno nuevo V3.0 de firmware y funciona

      Eliminar
  25. Hola, queria hacer una pregunta referente a la comunicación con un S300. He usado libnodave para comunicar con un S315 por ethernet y no he tenido problema.
    El problema lo encuentro al leer. La lectura la hace por bytes almacenandolo en el buffer; si la información en el DB ocupa mas de un byte, puedo leer mas de un byte de golpe para mantener el valor total?
    Por ejemplo,un decimal con valor 1300, como puedo interpretar al leer los dos bytes que ocupa que el 5 del primer byte y el 20 del segundo byte es una word con valor 1300?
    Gracias por adelantado!

    ResponderEliminar
    Respuestas
    1. Hola Lluc, entiendo que lo único que te queda por hacer es la siguiente operación: 5 * 256 + 20 = 1300 (5 es el valor del byte alto y 20 el valor del byte bajo).

      Un saludo.

      Eliminar
    2. res2 = daveReadBytes(Dc, daveFlags, 0, Direccion, 2, 0)
      If res2 = 0 Then
      v1 = daveGetS16(Dc)

      con esto te devuelve en v1 el valor de dos bytes directamente P.E. Una memoria de palabra (MW)
      En direccion le pones el bloque a leer p.e. 60 para la %M60 y te devolvera los 1300 de marras

      Eliminar
    3. Me colé hasta la oreja.
      Lo que debia haber puesto es:
      res2 = daveReadBytes(Dc, daveFlags, 0, Bloque de memoria(MW), 2, 0)
      If res2 = 0 Then
      v1 = daveGetU8(Dc)
      v2 = daveGetS8(Dc)
      resultado = v1 * 256 + v2
      end if

      Eliminar
  26. Hola de nuevo.

    GR, entiendes perfectamente. Y es mucho mejor solución que la opción que estaba probando de convertir los dos bytes a binario, juntarlos y volverlos a pasar a decimal (estoy leyendo datos desde una aplicación de visual - me olvidé comentarlo), porqué aunque funcionaba, bueno... no hay comparación; eso demuestra la importancia de atender en clase!

    Muchísimas gracias por tu ayuda.
    Un saludo!

    ResponderEliminar
  27. Este comentario ha sido eliminado por el autor.

    ResponderEliminar
  28. Solo tengo una pregunta (de momento)

    Como diantres funciona el davesetbit y daveclrbit? No consigo que funcionen (al menos en un 1200)
    El resto de funciones principales grosso modo funcionan bien.

    Muchas gracias de antemano

    ResponderEliminar
  29. como puedo cargar directamente un Word a una variable o campo de texto? y después mandarlo al PLC?

    muchas gracias por el aporte

    ResponderEliminar
  30. Muy buen aporte GR !! Me basé en tu programa y en el ejemplo simpleISO_TCP para acceder a la memoria imagen de un S7-1200 vía Ethernet.

    ResponderEliminar
  31. Muchas gracias por el aporte, en estos momentos estoy trabajando con la entrada anterior (vía MPI) el problema va a ser la velocidad y el costo del adaptador (si quiero hacerlo para más de una máquina), así que esta solución me parece más viable, pero no entiendo bien algo, la comunicación es con un módulo de ethernet como el CP 343?


    Saludos cordiales y muchas gracias por su respuesta.

    ResponderEliminar
  32. Buen dia, me ha sido muy util tu articulo, estoy programando una aplicacion en VB pero tengo una pregunta, como puedo leer un valor real? con los booleanos no tube problemas pero no he visto como leer los reales, si me pudieras orientar te lo agradeseria muchisimo.

    ResponderEliminar
  33. Saludos, tengo una consulta puedo usar el libnodave para comunicarme con un plc s7-1200 a traves de excel usando VBA? gracias.

    ResponderEliminar
  34. SALUDOS UNA PREGUNTA COMO O QUE CODIGO PONDO EN VISUAL BASIC PARA PODER ESCRIBIR EN LA SALIDAS DEL PLC S7-1200 QUIERO CONTROLAR LAS ENTRADAS Y SALIDAS PARA PODER MANIPULAR DESDE VISUAL BASIC..TOME EL EJEMPLO CON LAS LIBRERIA LIBNODAVE PERO NO SE QUE CODIGO DEBO PONER EN VISUAL PARA ENCENDER LA Q0.0 DEL PLC POR FA ALGUIEN ME PUDE AYUDAR LO NECESITO DE URGENCIA

    ResponderEliminar
    Respuestas
    1. Hola, supongo que podrías definir una variable de tipo booleana en tu DB, esta variable la escribes desde VB (con un botón por ejemplo) y en tu programa del PLC la utilizas para activar la salida.
      Saludos!

      Eliminar
  35. Hola, gracias, me ha resultado muy útil. Una pregunta, que a lo mejor es trivial, si se interrumpe la conexión ¿Cómo detecto esta situación antes de leer o esribir?. Muchas gracias

    ResponderEliminar
    Respuestas
    1. Hola Tecno, yo lo que hago es usar una marca que contiene un Entero, el cual corre de cero a 15 como tiempo establecido máximo de una conexión de la CPU con un sistema SCADA, este entero nunca puede ser llegar a 15,por lo que yo en mi programa VB2010 lo que he hecho es añadir un TIMER con una latencia de 1 seg. en el cual programo la lectura dicha marca de la CPU y verifica que nunca esta por encima 15 y que ha variado cada 2 segundos, en cuanto estos estados no se cumplen genero una desconexión del programa y usu un MSGBOX para comunicarselo al usuario, funciona bastante bien. Espero haberte sido de ayuda,aunque llegue algo tarde ;)

      Eliminar
  36. Saludos a todos;

    soy principiante en esto de programación de PLC's siemens, al momento estoy con un proyecto para conectar un HMI Brainchild 450 a un PLc Siemens S7 1200 vía ethernet y no lo consigo, en el manual de la pantalla hay un ejemplo de comunicación con siemens pero no funciona en mi proyecto.

    alguien tal vez sabe que sucede...?, estoy usando El tia portal V13 y el panel studio.

    muchas gracias amigos.

    ResponderEliminar
  37. Hola GR. Muchas gracias por el aporte, me ha ayudado muchísimo. Lo he usado para un proyecto en VB 2010 que modifica ciertas variables en distintas CPUs s400 y va de cine. Mi pregunta es, ¿Seria posible realizar una conexión simultánea a varios autómatas? Quiero crear con VS2010 un pequeño sistema SCADA de la instalación en la que trabajo y seria interesante poder mantener comunicación con todas las CPUs que tengo. Muchas gracias.

    ResponderEliminar
  38. Estoy iniciando en el desarrollo para aplicaciones para PLC, usu TIA Portal V13 como debo configurar el bloque de datos para que sean accesibles unas variables de entradas análogicas desde VB.NET

    ResponderEliminar
  39. Gracias por el ejemplo me ha sido de mucha utilidad. Funciona ok con S7-1200

    ResponderEliminar
    Respuestas
    1. Hola marc disculpa que te moleste, podras poner un ejemplo pequeño de como lo has logrado, estoy hace tiempo intentando y no he conseguido nada.
      Gracias

      Eliminar
  40. que tal yo soy principiante y estoy trabajando con la libreria solo que necesito leer un valor string del plc con esta libreria me podrian ayudar hasta ahora ya puedo leer pero puro valor entero.

    ResponderEliminar

Por favor, no pidas copias de programas comerciales, licencias o números de serie.