Conectar a un puerto serie (COM) usando Vb.net

Cuando se desea controlar algún dispositivo electrónico a través del computador, una forma muy sencilla de lograrlo es mediante el uso del puerto serie, que opera con las mismas configuraciones de la interfaz RS-232; en esta ocasión vamos a colocar a prueba una pequeña aplicación que se comunica con un dispositivo externo a través del pc.

Para empezar, creamos un nuevo proyecto de vb.net y elaboramos un diseño similar al que se observa en la siguiente imagen:

Tal y como se observa, usaremos un control SerialPort, 3 botones, 1 combobox, 2 textbox y varios labels.

Ahora declaramos las siguientes variables como globales:


Dim az As String     ‘utilizada para almacenar los datos que se reciben por el puerto

Dim sib As Integer    ‘ sera utilizada como contador

Dim msn(1000) As String    ‘vector que servira de buffer para los datos que van llegando al puerto

Luego, creamos la siguiente función o subrutina con la que se configurara el puerto serie:


Sub Setup_Puerto_Serie()

   Try

      With SerialPort1

        If .IsOpen Then

         .Close()

        End If

       .PortName = ComboPorts.Text

       .BaudRate = 19200 '// 19200 baud rate

       .DataBits = 8 '// 8 data bits

       .StopBits = IO.Ports.StopBits.One '// 1 Stop bit

       .Parity = IO.Ports.Parity.None '

       .DtrEnable = False

       .Handshake = IO.Ports.Handshake.None

       .ReadBufferSize = 2048

       .WriteBufferSize = 1024

       '.ReceivedBytesThreshold = 1

       .WriteTimeout = 500

       .Encoding = System.Text.Encoding.Default

       .Open() ' ABRE EL PUERTO SERIE

    End With

    Catch ex As Exception

      MsgBox("Error al abrir el puerto serial: " & ex.Message, MsgBoxStyle.Critical)

    End Try

 End Sub

Si deseas obtener más información sobre que significa cada una de las propiedades establecidas en la configuración del puerto, al final del post encontraras un link que contiene toda la información detallada.

Ahora, creamos la función que se encargará de buscar y listar todos los puertos serie disponibles en el computador.

Sub GetSerialPortNames()

    ' muestra COM ports disponibles.

     Dim l As Integer

     Dim ncom As String

       Try

        ComboPorts.Items.Clear()

        For Each sp As String In My.Computer.Ports.SerialPortNames

        l = sp.Length

        If ((sp(l - 1) >= "0") And (sp(l - 1) <= "9")) Then
             ComboPorts.Items.Add(sp)
             Else
             'hay una letra al final del COM
             ncom = sp.Substring(0, l - 1)
             ComboPorts.Items.Add(ncom)
          End If
      Next
     If ComboPorts.Items.Count >= 1 Then

      ComboPorts.Text = ComboPorts.Items(0)

     Else

     ComboPorts.Text = ""

     End If

    Catch ex As Exception

    End Try

  End Sub

Básicamente lo que hace esta función es recorrer  a través de un ciclo (For Each) todos los puertos series que estén disponibles e ir almacenando el nombre de cada puerto descubierto en la variable sp, luego viene una comparación para determinar que el nombre del puerto no contenga al final una letra (en muchas ocasiones cuando se conectan dispositivos como microcontroladores, teléfonos celulares, PDA’s, etc, el computador establece un valor basura al final del nombre del puerto, por ejemplo: COM7i; en estas ocasiones hay una “ i ” que podría ocasionar problemas para conectarse al puerto), si no se encuentra una letra al final, se guarda el nombre del puerto en el combobox, de lo contrario se crea un nuevo substring donde se le recorta el ultimo carácter a la varia sp.


Bien, teniendo las funciones de configuración del puerto y de búsqueda, podemos proceder a usarlas o invocarlas. Entonces, en el evento load del formulario colocamos lo siguiente:

Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
 GetSerialPortNames()
 CheckForIllegalCrossThreadCalls = False ' DESACTIVA ERROR POR SUBPROCESO
End Sub

En el botón BuscarComm (que tiene la imagen), colocamos lo siguiente:


Private Sub BtnBuscarComm_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnBuscarComm.Click
GetSerialPortNames()
End Sub

Luego, el código en el botón conectar quedara de la siguiente manera:


Private Sub BtnConectar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnConectar.Click

    Try

      If BtnConectar.Text = "Conectar" Then

        BtnConectar.Text = "Desconectar"

        Setup_Puerto_Serie()

      Else

       If SerialPort1.IsOpen Then

        SerialPort1.Close()

       End If

       BtnConectar.Text = "Conectar"

   End If

   Catch ex As Exception

   End Try

End Sub

El botón para enviar los datos quedara de la siguiente manera:


Private Sub Button_enviar_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button_enviar.Click

 sib = 0

 Try

   SerialPort1.Write(Me.Text_denviados.Text)

   Me.Text_drecibidos.Clear()

   Catch ex As Exception

   MsgBox(ex.Message)

 End Try

End Sub

La instrucción SerialPort1.Write() es la que se encarga de escribir o de enviar los datos por el puerto.

Para procesar los datos recibidos a través del puerto serie se utiliza el evento DataReceived del SerialPort, lo que se realiza dentro de esta subrutina consiste en ir almacenando en la variable az el carácter o palabra que va llegando y luego construir un buffer o vector llamado msn que va a almacenar el mensaje completo para al final poder mostrarlo; se hace esto porque en ciertas ocasiones el puerto se satura y se sobrecarga la transferencia de datos, así se evita la perdida de información y la sobrecarga.


Private Sub SerialPort1_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived

 Try

   az = SerialPort1.ReadExisting.Trim

   msn(sib) = az

   Me.Text_drecibidos.Text += msn(sib) + " "

   sib = sib + 1

 Catch ex As Exception

 MsgBox(ex.Message)

 End Try

End Sub

Básicamente la variable “sib” trabaja como un simple contador para ir llevando el valor de la cantidad de datos almacenados en el vector, dicha variable se reinicia o vuelve a cero cuando se envía un nuevo dato.

La instruccion SerialPort1.ReadExisting es la que se encarga de leer o recibir los datos que van llegando al puerto.

Bien ya hemos terminado nuestra aplicación, ahora pasemos a probarla, para ello podemos usar un cable serial (db-9 si es que aun los utilizan o el cable de datos de algún teléfono celular, hay ciertos cables que pueden generar el puerto COM los más conocidos son los de los celulares Nokia usados para trabajar con micro controladores, aunque también se puede usar cualquier otro).

En este caso yo estoy usando el cable USB de un teléfono celular Motorola l6 manteniendo una conexión entre el computador y el teléfono celular, este cable no me genera el puerto COM ya que en si quien lo está creando o virtualizando es el celular así que puedo aprovechar las propiedades del teléfono para enviar comandos AT o para enviar cualquier información el dispositivo externo lo recibe y me retransmite dichos datos.  En la siguiente imagen se puede observar el funcionamiento de la aplicación:

Bien Amigos, eso es todo, aqui les dejo el link para que descarguen el proyecto y tambien para que encuentren la documentacion del puerto serie y la utilizacion del control en vb.net

Descargar Aplicacion

Detalles del Serial Port

Anuncios

31 respuestas a “Conectar a un puerto serie (COM) usando Vb.net

  1. WOW amigo muchas gracias por el aporte , sin embargo tengo una pregunta:

    ¿Como podría hacer que al momento de qué ocurra una desconexión por parte del dispositivo(pic) ocasionando que este deje de enviar datos el programa se detenga o muestre en pantalla un mensaje de alerta?

  2. Segui los pasos que indicas pero no puedo hacer que lea el puerto no dispara el metodo DataReceived
    como checo que mi puerto esta recibiendo los datos agradeceria tus comentarios.

  3. Hola que tal, no se mucho de electrónica y mi experiencia con VB no es mucha tampoco y mi duda o mi necesidad es la siguiente, quiero levantar una pluma de estacionamiento utilizando el puerto com, ésto como se haría? en la pluma yo cierro un circuito y se levanta y tambien se baja la pluma. y eso necesito se haga con el puerto com, como es posible hacer esto? yo solo quiero cerrar el circuito por un instante para que la pluma se levante.

  4. buenas tardes, estoy intentando seguir tu programa de comunicación serial, lo eh probado y al parecer funciona, pero tengo problemas en la respuesta ya que estoy usando comandos AT, y en la respuesta solo me sale la primera linea de respuesta.. supongo q sabrás q en la respuestas de AT, la primera linea me reponde con el comando y hace unos espacios y después me da la respuesta…tienes alguna idea para ampliar la recepción del puerto?
    de ante mano les agradezco

    • Hola Luis Franco, lo que pasa es que tienes que concatenar los datos que estas recibiendo por el puerto. Intenta manejar la funcion de recepcion de la siguiente manera:

         Private Sub SerialPort2_DataReceived(ByVal sender As Object, ByVal e As System.IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort2.DataReceived
      
              Try
      
                  az2 = SerialPort2.ReadExisting.Trim
                  msn2(sib2) = az2
                  Me.Text_proceso_envio_sms.Text += msn2(sib2) + "   "
      
                  sib2 = sib2 + 1
      
              Catch ex As Exception
                  MsgBox(ex.Message)
              End Try
      
          End Sub
      
      

      donde:

      * az2 es una variable de tipo String
      * msn2 es un vector de tipo String, lo puedes definir asi, Dim msn2(1000) as String “en ese caso lo he definido con capacidad de 1000 caracteres”.
      * sib2 es un contador de tipo entero.

      Luego vas mostrando en un textbox los datos que vas recibiendo, espero y pueda serte de ayuda.

      Si tienes otra inquietud tengo muchos proyectos en los que uso el puerto serial usb, si lo deseas puedo enviarte alguno que te aclare mas lo que debes realizar.

    • Hola mauricio, para esto debes usar el control timer de la caja de herramientas y lo configuras al tiempo en que desees realizar el envio. aunque si deseas enviar 2 datos a la vez hacia un pic deberías usar algunos caracteres que identifiquen la trama para que cuando le llegue al pic este sepa procesar lo que esta recibiendo, por ejemplo si deseas enviar el numero 2 y la letra a simultáneamente, deberías establecer una cadena como la siguiente: {2,a} donde { indica el comienzo de la trama, “,” la coma representa que se esta enviando otro dato y } significa el fin de la trama. Saludos.

  5. Buen día compañero no tengo mucha experiencia programando me podrías apoyar y decirme como puedo ir limpiar e ir mostrando datos nuevos que van entrando por el puerto serie en el text box de Recibir datos.

    • Hola compañero, disculpa la demora en darte respuesta; para borrar los textbox solo tienes que colocar me.textbox.clear()

      Donde textbox corresponde al nombre del textbox que estés utilizando. Cualquier otra inquietud me la puedes hacer llegar.

      • Hola, estoy empezando en visual basic y tu código me llamó la atención, podrías resubir el enlace?
        Gracias

  6. Hola buenas tardes, llevo dias cabezeando con esto. Tu aplicacion junto a otras 2 parecidas a la tuya me funcionan solo en la parte de reconocer los puertos (COM) en mi sistema y tambien hacen la conexion aparentemente sin problemas. Pero ninguna de las 3 aplicaciones me logra imprimir el mensaje en el segundo textbox. Tengo conectada a la PC una impresora de facturacion IBM 4610 TF6 y siento que me estoy volviendo loco ya….

    • Hola amigo, gracias por tu comentario. Según lo que dices, la aplicación te reconoce los puertos COM del sistema y te conectas sin problemas.
      El problema que tienes es que deseas imprimir un texto que debe enviar como respuesta la impresora IBM 4610 TF6. Pienso que no estas obteniendo resultado porque debes usar comandos POS para comunicarte con esta impresora. Tengo una aplicación que te puede servir: Impresora de Facturas Epson Lo utilice para generar facturas en la impresora térmica epson TM-T20 pruebalo. Espero y te funcione.
      Saludos!

  7. Gracias, muchas gracias de antemano.
    …estoy tratando de imprimir con una impresora portatil, que se conecta a la pc por Blutooh, el puerto COM que me configura es el COM7, trato de configurar mi puerto desde mi aplicación pero la impresora da error, en ocasiones imprime otras no, pero no hay forma de recibir de ella en el evento ‘_DataReceived’…

    Si me pudieras dar una mano.

  8. Hola, muy buen post. Envio desde un pic que sensa la informacion, a un programa de VB donde la muestro en diferentes relojes. Cuando envio una sola variable, lo toma bien y lo muestra como debe. El problema surge cuando envio dos variables simultaneamente ya que el programa de VB no toma los datos correctamente. Agradeceria si tienes alguna solucion para este problema.

  9. buenas, como me puedo bajar el programa?. si uso el 4Share desktop mi antivirus me lo bloquea y los otros downloads que hay dan error de pagina al cargarla.
    Muchas gracias por el aporte.

  10. Muy Buen Aporte, Pero tengo un problema, estoy tratando de conectarme a una maquina cnc, y la respuesta en lugar de darme strings, solo me arroja 1 digito, y si continuo pidiendo respuestas a la maquina el digito se reemplaza por uno diferente hasta que desaparece y no vuelve a recibir respuesta aparente

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión /  Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión /  Cambiar )

Conectando a %s