Wiesemann & Theis GmbH

Tecnología de redes, sensores e interfaces para la industria, la oficina y la informática

Tutorial al Web-IO digital:

Activar Web-IO Digital con
Visual Basic.Net vía
sockets binarios


Ya se dispone de VB.Net en diferentes versiones, hasta VB 2019, como sucesor de MS Visual Basic 5 y 6. También la actual versión de Visual Basic ofrece todo lo necesario para programar aplicaciones TCP/IP, incluso es compatible con estructuras binarias. Por eso, Visual Basic sigue siendo hoy una herramienta preferente para crear aplicaciones que se comuniquen con Web-IO digital siendo además que la versión Express de Visual Basic está disponible para descargar gratuitamente en Microsoft. No se necesitan controladores adicionales ni DLL.

Dirigir con Visual Basic

Con el siguiente ejemplo de programa usted puede activar su Web-IO Digital, con sus entradas y salidas, en una aplicación de Windows a través del modo de socket binario.


Preparativos


Recopilación de los diferentes elementos de manejo y objetos de visualización en formulario VB.net

Elementos de manejo Visual Basic

Además de los objetos aquí mostrados el programa necesita además un Timer para el Polling (timer_polling).

Al denominar cada uno de los objetos, es de gran ayuda usar nombres con sentido. En este ejemplo la primera parte del nombre describe la clase de objeto y la segunda la función.

Información general

Mientras que la formación de superficies de usuario gráficas en Visual Basic Express es tan fácil de hacer como en las versiones anteriores, otras tareas precisan primeramente de costumbre.

Para la actual versión de VB ya no está disponible el elemento de control Winsock conocido de VB5 y VB6.

En lugar de eso se tiene que instanciar para el acceso de red a través del Import statement el espacio del nombre para las clases usadas de zócalo en el cabezal del texto de origen. Además de ello se tiene que instalar el zócalo en el que se debe tramitar la comunicación, y tiene que definirse un Buffer para los datos de entrada.

Además también se impulsó de tal manera el encapsulado de algunos objetos separados en VB.Net que los objetos que están depositados dentro de un Thread, no permiten el acceso desde otro Thread. Así pues no se puede asentar p. ej. de Thread B una caja de chequeo que se depositó en Thread A.

Pero no obstante, para hacer accesibles características de objeto para otros Threads, tienen que depositarse en el propio Thread sub-procedimientos para cambiar el objeto. Se forman entonces delegados para estos sub-procedimientos, a través de los cuales los otros Threads pueden tener acceso.

Como p. ej. para dar línea libre a elementos de mando del formulario después de una conexión favorable para el manejo o para bloquear al finalizar la conexión, pero también para adaptar las cajas de chequeo Input/Output después de recibidos los datos a los estados reales IO.

							
Imports System.Net.Sockets
Imports System.Net

Public Class Form1
  Public Structure IO_State
    Dim outputstate0 As Boolean
    Dim outputstate1 As Boolean
    Dim inputstate0 As Boolean
    Dim inputstate1 As Boolean
    Dim countervalue0 As Long
    Dim countervalue1 As Long
  End Structure

  Private Delegate Sub DelegateSub()
  Private connectenable As New DelegateSub(AddressOf connect_enable)
  Private disconnectenable As New DelegateSub(AddressOf disconnect_enable)
  Private formupdate As New DelegateSub(AddressOf form_update)
  Dim TCP_client As Socket
  Dim connection_ar As IAsyncResult
  Dim receivebuffer(511) As Byte
  Dim IOState As IO_State

  Private Sub connect_enable()
    bt_connect.Enabled = False
    gb_io.Enabled = True
    bt_disconnect.Enabled = True
    Timer_polling.Enabled = True
    ToolStripStatusLabel1.Text = "Connected to " + tb_ip.Text + " : " + tb_port.Text
  End Sub

  Private Sub disconnect_enable()
    bt_connect.Enabled = True
    gb_io.Enabled = False
    bt_disconnect.Enabled = False
    timer_polling.Enabled = False
    ToolStripStatusLabel1.Text = "No Connection"
  End Sub

  Private Sub form_update()
    If IOState.inputstate0 = True Then
      cb_input0.Checked = True
    Else
      cb_input0.Checked = False
    End If
    If IOState.inputstate1 = True Then
      cb_input1.Checked = True
    Else
      cb_input1.Checked = False
    End If
    If IOState.outputstate0 = True Then
      cb_output0.Checked = True
    Else
      cb_output0.Checked = False
    End If
    If IOState.outputstate1 = True Then
      cb_Output1.Checked = True
    Else
      cb_Output1.Checked = False
    End If
    tb_counter0.Text = IOState.countervalue0
    tb_counter1.Text = IOState.countervalue1
  End Sub
							
						

Las estructuras binarias

Para el acceso binario es imprescindible definir las estructuras binarias requeridas con las que deba tener lugar la comunicación con el Web-IO. Encontrará una descripción detallada de esas estructuras en el breve resumen de estructuras binarias o en manual de programación para Web-IO.

La estructura EADriver
Con sus cuatro variables de 16 bits EADriver es la estructura básica que también forma parte de todas las demás estructuras binarias.

							
Public Structure structEADriver
  Dim Start_1 As UInt16
  Dim Start_2 As UInt16
  Dim StructType As UInt16
  Dim StructLength As UInt16
End Structure

<StructLayout(LayoutKind.Explicit)> Public Structure structOptions
  <FieldOffset(0)> Dim EADriver As structEADriver
  <FieldOffset(8)> Dim Version As UInt32
  <FieldOffset(12)> Dim Options As UInt32
End Structure

Public Structure structSetBit
  Dim EADriver As structEADriver
  Dim Mask As UInt16
  Dim Value As UInt16
End Structure

Public Structure structReadCounter
  Dim EADriver As structEADriver
  Dim CounterIndex As UInt16
End Structure

Public Structure structWriteRegister
  Dim EADriver As structEADriver
  Dim Amount As UInt16
  Dim Value As UInt16
End Structure

Public Structure structRegisterState
  Dim EADriver As structEADriver
  Dim DriverID As UInt16
  Dim InputValue As UInt16
  Dim OutputValue As UInt16
End Structure

<StructLayout(LayoutKind.Explicit)> Public Structure structCounter
  <FieldOffset(0)> Dim EADriver As structEADriver
  <FieldOffset(8)> Dim CounterIndex As UInt16
  <FieldOffset(10)> Dim CounterValue As UInt32
End Structure

<StructLayout(LayoutKind.Explicit)> Public Structure structAllCounter
  <FieldOffset(0)> Dim EADriver As structEADriver
  <FieldOffset(8)> Dim CounterNoOf As UInt16
  <FieldOffset(10)> Dim CounterValue0 As UInt32
  <FieldOffset(14)> Dim CounterValue1 As UInt32
End Structure
							
						

En las estructuras es importante que las distintas variables se encuentren agrupadas sucesivamente en la memoria. Visual Basic no lo maneja así automáticamente, especialmente cuando una estructura agrupa variables de diferentes tamaños. Aun así, para garantizar una ocupación agrupada de la memoria se determina mediante <StructLayout(LayoutKind.Explicit)> que se asigne cada variable individual a través de <FieldOffset(14)> un offset fijo para el primer puesto de la memoria de la estructura.

El control de conexión

Introducir la conexión

La conexión se arranca entrando la dirección IP del Web-IO en el campo de texto ed_ip y chasqueando el botón bt_connect.

							
  Private Sub bt_connect_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bt_connect.Click
    Dim WebIOep As New IPEndPoint(IPAddress.Parse(tb_ip.Text), Val(tb_port.Text))
    If tb_ip.Text <> "" And tb_port.Text <> "" Then
      TCP_client = New Socket(AddressFamily.InterNetwork, SocketType.Stream, _ ProtocolType.Tcp)
      bt_connect.Enabled = False
      Try
        TCP_client.BeginConnect(WebIOep, New AsyncCallback(AddressOf callback_connect), TCP_client)
      Catch ex As Exception
      End Try
    End If
  End Sub
							
						

La conexión

Para la tramitación del manejo TCP/IP se define primero un IPEndPoint de la dirección IP y puerto TCP y así inicializar el zócalo TCP_client. En el transcurso de la solicitud de conexión se crea una referencia a un procedimiento Callback.

Se establece la conexión

Tan pronto como el Web-IO acepta la conexión, se ejecuta el procedimiento Callback. A través de Invoke se llama al delegado para el procedimiento, que libera los elementos de mando e indica el estado de Connect en la barra de estado. Además de ello se cera una referencia a una rutina Callback para la recepción de datos.

Mediante el envío de la estructura Options al Web-IO, se le está ordenando que, al aplicar una salida transmita la modificación del estado de conmutación a través de la estructura RegisterState.

							
Private Sub callback_connect(ByVal ar As IAsyncResult)
  Invoke(connectenable)
  connection_ar = ar
  Try
    TCP_client.EndConnect(ar)
    TCP_client.BeginReceive(receivebuffer, 0, 512, SocketFlags.None, New AsyncCallback(AddressOf callback_readdata), TCP_client)
    Dim BufPtr As IntPtr
    Dim Options As structOptions
    Options.EADriver.Start_1 = 0
    Options.EADriver.Start_2 = 0
    Options.EADriver.StructType = &H1F0
    Options.EADriver.StructLength = 16
    Options.Version = 1
    Options.Options = 1
    BufPtr = Marshal.AllocHGlobal(Runtime.InteropServices.Marshal.SizeOf(Options))
    Marshal.StructureToPtr(Options, BufPtr, True)
    sendstructure(BufPtr, Options.EADriver.StructLength)
  Catch ex As Exception
    closeconnections()
  End Try
End Sub
							
						

Separar la conexión

La conexión se mantiene hasta que el usuario la finalice pulsando el botón Disconnect o hasta que sea finalizada por el Web-IO.

							  Private Sub bt_disconnect_Click(ByVal sender	As System.Object, ByVal e As System.EventArgs) Handles bt_disconnect.Click
    Invoke(disconnectenable)
    closeconnections()
  End Sub
							
						

En este caso se llama un procedimiento correspondiente.

							  Private Sub closeconnections()
    Try
      TCP_client.EndReceive(connection_ar)
    Catch ex As Exception
    End Try
    Try
      TCP_client.Shutdown(SocketShutdown.Both)
    Catch ex As Exception
    End Try
    Try
      TCP_client.Close()
    Catch ex As Exception
    End Try
    Invoke(disconnectenable)
  End Sub
							
						

Error de conexión

Todas las acciones correspondientes a la comunicación TCP/IP se ejecutan dentro de la orden Try. Si aparecen errores se activa también el procedimiento CloseConnection.

Manejo y comunicación por parte del cliente

Enviar comandos

Una vez establecida la conexión con el Web-IO, el usuario puede enviar estructura binarias al Web-IO utilizando los correspondientes elementos de programa.

							
Private Sub sendstructure(ByVal BufPtr As IntPtr, Bufsize As Integer)
  Dim senddata As Byte()
  ReDim senddata(Bufsize - 1)
  Marshal.Copy(BufPtr, senddata, 0, Bufsize)
  Try
    TCP_client.Send(senddata)
  Catch ex As Exception
    closeconnections()
  End Try
  Marshal.FreeHGlobal(BufPtr)
End Sub
							
						

Visual Basic no prevé ningún método para el envío directo de estructuras binarias. Los datos binarios solo pueden ser enviados como un array de bytes. Por eso al abrir la función sendstructure se transmite un pointer (puntero). Ese puntero hace referencia al puesto de la memoria a partir del cual se encuentra el contenido de la estructura a enviar. Aquí se pone de manifiesto, por qué las variables de la estructura tienen que estar agrupadas por bytes en la memoria. Como segundo parámetro se transmite la longitud de la estructura.

A través de Marshal.Copy(BufPtr, senddata, 0, Bufsize) se copian los datos de la estructura en un array de bytes. Ese array de bytes será enviado luego al Web-IO.

Poner Outputs

El usuario puede poner los Outputs a través de dos casillas de verificación cb_outputx. El programa utiliza para ello la acción MouseUP de ese objeto. Cuando se registra un MouseUp, es decir se suelta la casilla de verificación de la salida, el programa ejecuta el procedimiento correspondiente y, en función de si está aplicada o no la casilla de verificación, transmite la correspondiente estructura Set-Bit rellenada al Web-IO.

							
Private Sub cb_output0_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles cb_output0.MouseUp
  Dim BufPtr As IntPtr
  Dim SetBit As structSetBit
  SetBit.EADriver.Start_1 = 0
  SetBit.EADriver.Start_2 = 0
  SetBit.EADriver.StructType = 9
  SetBit.EADriver.StructLength = 12
  SetBit.Mask = 1
  If cb_output0.Checked Then
    SetBit.Value = 1
  Else
    SetBit.Value = 0
  End If
  BufPtr = Marshal.AllocHGlobal(Runtime.InteropServices.Marshal.SizeOf(SetBit))
  Marshal.StructureToPtr(SetBit, BufPtr, True)
  sendstructure(BufPtr, SetBit.EADriver.StructLength)
End Sub

Private Sub cb_Output1_MouseUp(ByVal sender As Object, ByVal e As System.Windows.Forms.MouseEventArgs) Handles cb_Output1.MouseUp
  Dim BufPtr As IntPtr
  Dim SetBit As structSetBit
  SetBit.EADriver.Start_1 = 0
  SetBit.EADriver.Start_2 = 0
  SetBit.EADriver.StructType = 9
  SetBit.EADriver.StructLength = 12
  SetBit.Mask = 2
  If cb_Output1.Checked Then
    SetBit.Value = 2
  Else
    SetBit.Value = 0
  End If
  BufPtr = Marshal.AllocHGlobal(Runtime.InteropServices.Marshal.SizeOf(SetBit))
  Marshal.StructureToPtr(SetBit, BufPtr, True)
  sendstructure(BufPtr, SetBit.EADriver.StructLength)
End Sub
							
						

Solicitar estado de Output/Input

El usuario puede solicitar el estado de los Outputs e Inputs chasqueando el botón correspondiente.

							
  Private Sub bt_outputs_read_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bt_outputs_read.Click
    Dim BufPtr As IntPtr
    Dim RegisterRequest As structEADriver
    RegisterRequest.Start_1 = 0
    RegisterRequest.Start_2 = 0
    RegisterRequest.StructType = &H21
    RegisterRequest.StructLength = 8
    BufPtr = Marshal.AllocHGlobal(Runtime.InteropServices.Marshal.SizeOf(RegisterRequest))
    Marshal.StructureToPtr(RegisterRequest, BufPtr, True)
    sendstructure(BufPtr, RegisterRequest.StructLength)
  End Sub
							
						

Mediante el envío de la estructura RegisterRequest se solicitan los estados de conmutación de las entradas y salidas. Web-IO responde a esa solicitud con la estructura RegisterState.

Si solo deben consultarse las entradas, esto se activa pulsando el botón bt_inputs. Para ello se envía la estructura ReadRegister, a la que Web-IO responde con la estructura WriteRegister.

							
  Private Sub bt_inputs_read_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bt_inputs_read.Click
    Dim BufPtr As IntPtr
    Dim ReadRegister As structEADriver
    ReadRegister.Start_1 = 0
    ReadRegister.Start_2 = 0
    ReadRegister.StructType = 1
    ReadRegister.StructLength = 8
    BufPtr = Marshal.AllocHGlobal(Runtime.InteropServices.Marshal.SizeOf(ReadRegister))
    Marshal.StructureToPtr(ReadRegister, BufPtr, True)
    sendstructure(BufPtr, ReadRegister.StructLength)
  End Sub
							
						

Contadores preguntar/borrar

También los estados de los contadores de la entrada pueden ser consultados o borrados. Para ello se envía la estructura ReadCounter o ReadClearCounter, donde se transmite con CounterIndex el número del contador. Web-IO responde con la estructura Counter.

							
  Private Sub bt_counter_read0_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bt_counter_read0.Click
    Dim BufPtr As IntPtr
    Dim ReadCounter As structReadCounter
    ReadCounter.EADriver.Start_1 = 0
    ReadCounter.EADriver.Start_2 = 0
    ReadCounter.EADriver.StructType = &HB0
    ReadCounter.EADriver.StructLength = 10
    ReadCounter.CounterIndex = 0
    BufPtr = Marshal.AllocHGlobal(Runtime.InteropServices.Marshal.SizeOf(ReadCounter))
    Marshal.StructureToPtr(ReadCounter, BufPtr, True)
    sendstructure(BufPtr, ReadCounter.EADriver.StructLength)
  End Sub

  Private Sub bt_counter_read1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bt_counter_read0.Click
    Dim BufPtr As IntPtr
    Dim ReadCounter As structReadCounter
    ReadCounter.EADriver.Start_1 = 0
    ReadCounter.EADriver.Start_2 = 0
    ReadCounter.EADriver.StructType = &HB0
    ReadCounter.EADriver.StructLength = 10
    ReadCounter.CounterIndex = 1
    BufPtr = Marshal.AllocHGlobal(Runtime.InteropServices.Marshal.SizeOf(ReadCounter))
    Marshal.StructureToPtr(ReadCounter, BufPtr, True)
    sendstructure(BufPtr, ReadCounter.EADriver.StructLength)
  End Sub

  Private Sub bt_counter_clear0_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bt_counter_clear0.Click
    Dim BufPtr As IntPtr
    Dim ReadClearCounter As structReadCounter
    ReadClearCounter.EADriver.Start_1 = 0
    ReadClearCounter.EADriver.Start_2 = 0
    ReadClearCounter.EADriver.StructType = &HC0
    ReadClearCounter.EADriver.StructLength = 10
    ReadClearCounter.CounterIndex = 0
    BufPtr = Marshal.AllocHGlobal(Runtime.InteropServices.Marshal.SizeOf(ReadClearCounter))
    Marshal.StructureToPtr(ReadClearCounter, BufPtr, True)
    sendstructure(BufPtr, ReadClearCounter.EADriver.StructLength)
  End Sub

  Private Sub bt_counter_clear1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bt_counter_clear0.Click
    Dim BufPtr As IntPtr
    Dim ReadClearCounter As structReadCounter
    ReadClearCounter.EADriver.Start_1 = 0
    ReadClearCounter.EADriver.Start_2 = 0
    ReadClearCounter.EADriver.StructType = &HC0
    ReadClearCounter.EADriver.StructLength = 10
    ReadClearCounter.CounterIndex = 1
    BufPtr = Marshal.AllocHGlobal(Runtime.InteropServices.Marshal.SizeOf(ReadClearCounter))
    Marshal.StructureToPtr(ReadClearCounter, BufPtr, True)
    sendstructure(BufPtr, ReadClearCounter.EADriver.StructLength)
  End Sub
							
						

A través de la estructura ReadAllCounter o ReadAllCounter se puede leer o borrar también todos los contadores. Web-IO responde con la estructura AllCounter.

							
  Private Sub bt_counter_readall_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bt_counter_readall.Click
    Dim BufPtr As IntPtr
    Dim ReadAllCounter As structEADriver
    ReadAllCounter.Start_1 = 0
    ReadallCounter.Start_2 = 0
    ReadAllCounter.StructType = &HB1
    ReadAllCounter.StructLength = 10
    BufPtr = Marshal.AllocHGlobal(Runtime.InteropServices.Marshal.SizeOf(ReadAllCounter))
    Marshal.StructureToPtr(ReadAllCounter, BufPtr, True)
    sendstructure(BufPtr, ReadAllCounter.StructLength)
  End Sub

  Private Sub bt_counter_clearall_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles bt_counter_clearall.Click
    Dim BufPtr As IntPtr
    Dim ReadClaerAllCounter As structEADriver
    ReadClaerAllCounter.Start_1 = 0
    ReadClaerAllCounter.Start_2 = 0
    ReadClaerAllCounter.StructType = &HC1
    ReadClaerAllCounter.StructLength = 10
    BufPtr = Marshal.AllocHGlobal(Runtime.InteropServices.Marshal.SizeOf(ReadClaerAllCounter))
    Marshal.StructureToPtr(ReadClaerAllCounter, BufPtr, True)
    sendstructure(BufPtr, ReadClaerAllCounter.StructLength)
  End Sub
							
						

Recepción de datos del Web-IO

Evaluar e indicar los datos recibidos

Web-IO envía la estructura acorde a la solicitud o la acción que lo activa. Para la recepción de datos se activa el correspondiente procedimiento Callback. Para la evaluación, los primeros 8 bytes del array de bytes recibido rellenan en primer lugar una estructura EADriver a través de una operación de puntero. La aplicación identifica el tipo de estructura a través de la variable EADriver.StructType.

  • EADriver.StructType = 8
    Estructura WriteRegister para el estado de las entradas

  • EADriver.StructType = 31 (hex.)
    Estructura RegisterState para el estado de las entradas y salidas

  • EADriver.StructType = B4 (hex.)
    Estructura Counter para el valor de los diferentes contadores

  • EADriver.StructType = B5 (hex.)
    Estructura AllCounter para el valor de todos los contadores

Para la evaluación, el array de bytes recibido rellena ahora la estructura adecuada a través de una operación de puntero.

Los valores transmitidos de ese modo son evaluados y presentados. Para las entradas y salidas se transmite a través de WriteRegister.Value, RegisterStae.InputValue y RegisterStae.outputValue el patrón de bits de todas las entradas o salidas.

							
Private Sub callback_readdata(ByVal ar As IAsyncResult)
  If TCP_client.Connected Then
    Dim bytesread As Integer
    Try
      bytesread = TCP_client.EndReceive(ar)
    Catch ex As Exception
    End Try
    If bytesread = 0 Then
      closeconnections()
    Else
      Try
        TCP_client.BeginReceive(receivebuffer, 0, 512, SocketFlags.None, New AsyncCallback(AddressOf callback_readdata), TCP_client)
      Catch ex As Exception
        closeconnections()
      End Try
      Dim MyGC As GCHandle = GCHandle.Alloc(receivebuffer, GCHandleType.Pinned)
      Dim EADriver As structEADriver = Marshal.PtrToStructure(MyGC.AddrOfPinnedObject, EADriver.GetType)

      Select Case EADriver.StructType
      Case 8
        Dim WriteRegister As structWriteRegister = Marshal.PtrToStructure(MyGC.AddrOfPinnedObject, WriteRegister.GetType)
        If (WriteRegister.Value And 1) = 1 Then
          IOState.inputstate0 = True
        Else
          IOState.inputstate0 = False
        End If
        If (WriteRegister.Value And 2) = 2 Then
          IOState.inputstate1 = True
        Else
          IOState.inputstate1 = False
        End If
      Case &H31
        Dim RegisterState As structRegisterState = Marshal.PtrToStructure(MyGC.AddrOfPinnedObject, RegisterState.GetType)
        If (RegisterState.InputValue And 1) = 1 Then
          IOState.inputstate0 = True
        Else
          IOState.inputstate0 = False
        End If
        If (RegisterState.InputValue And 2) = 2 Then
          IOState.inputstate1 = True
        Else
          IOState.inputstate1 = False
        End If
        If (RegisterState.OutputValue And 1) = 1 Then
          IOState.outputstate0 = True
        Else
          IOState.outputstate0 = False
        End If
        If (RegisterState.OutputValue And 2) = 2 Then
          IOState.outputstate1 = True
        Else
          IOState.outputstate1 = False
        End If
      Case &HB4
        Dim Counter As structCounter = Marshal.PtrToStructure(MyGC.AddrOfPinnedObject, Counter.GetType)
        If Counter.CounterIndex = 0 Then IOState.countervalue0 = Counter.CounterValue.ToString
        If Counter.CounterIndex = 1 Then IOState.countervalue1 = Counter.CounterValue.ToString
      Case &HB5
        Dim AllCounter As structAllCounter = Marshal.PtrToStructure(MyGC.AddrOfPinnedObject, AllCounter.GetType)
        IOState.countervalue0 = AllCounter.CounterValue0.ToString
        IOState.countervalue1 = AllCounter.CounterValue1.ToString
      End Select
      Invoke(formupdate)
      MyGC.Free()
    End If
  End If
End Sub
							
						

Polling

Solicitud cíclica de determinados valores

A fin de posibilitar una actualización automática de la indicación, se utiliza un Timer.

Dependiendo de las casillas de verificación para el Polling de Output, Input y Counter se llaman las informaciones correspondientes a un intervalo ajustado del Web-IO.

							
  Private Sub timer_polling_Elapsed(ByVal sender As System.Object, ByVal e As System.Timers.ElapsedEventArgs) Handles timer_polling.Elapsed
    If ((cb_input_polling.Checked Or cb_output_polling.Checked) And TCP_client.Connected) Then
      Dim BufPtr As IntPtr
      Dim RegisterRequest As structEADriver
      RegisterRequest.Start_1 = 0
      RegisterRequest.Start_2 = 0
      RegisterRequest.StructType = 1
      RegisterRequest.StructLength = &H21
      BufPtr = Marshal.AllocHGlobal(Runtime.InteropServices.Marshal.SizeOf(RegisterRequest))
      Marshal.StructureToPtr(RegisterRequest, BufPtr, True)
      sendstructure(BufPtr, RegisterRequest.StructLength)
    End If
    If (cb_counter_polling.Checked And TCP_client.Connected) Then
      Dim BufPtr As IntPtr
      Dim ReadAllCounter As structEADriver
      ReadAllCounter.Start_1 = 0
      ReadAllCounter.Start_2 = 0
      ReadAllCounter.StructType = &HB1
      ReadAllCounter.StructLength = 10
      BufPtr = Marshal.AllocHGlobal(Runtime.InteropServices.Marshal.SizeOf(ReadAllCounter))
      Marshal.StructureToPtr(ReadAllCounter, BufPtr, True)
      sendstructure(BufPtr, ReadAllCounter.StructLength)
    End If
  End Sub
							
						

El intervalo deseado puede entrarse en el campo correspondiente de texto. En caso de un cambio el intervalo del Timer se adapta automáticamente.

							
  Private Sub tb_interval_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles tb_interval.TextChanged
    timer_polling.Interval = Val(tb_interval.Text)
  End Sub
							
						

El programa ejemplo es compatible con todas las funciones habituales de Web-IO en el modo de socket binario, optimizado para Web-IO 2x entradas digitales, 2x salidas digitales. Para otros modelos de Web-IO puede ser necesario adaptar el programa. Encontrará una descripción detallada de las estructuras binarias en el breve resumen de estructuras binarias o en manual de programación para Web-IO.

Descargar el programa ejemplo


Productos



^