Una alternativa al SerialPort.ReadLine

Atendiendo algunas dudas sobre como optimizar la recepción de datos utilizando ‘ReadLine’, y a falta de un ejemplo completo os facilito una alternativa.

La idea es llamar a la funcion de recepcion siempre que se reciben datos y disparar el evento de trama completa cuando se cumple la condicion de carácter final.

Imports
System.IO.Ports 
Public Class PortsSerie       
 ‘
   
 ‘Declarar el evento disparo fin de recepcion
   
 Public Event RxFin(ByVal Trama As String)
   
 ‘   
 ‘String de recepcion utilizado como buffer   
 Private PortSerie_Recepcion As String = “”
   
 ‘Anadir el manipulador de recepcion en la sub New, Load…
   
 AddHandler
PortSerie.DataReceived, AddressOf Rx
 
 Protected
Sub Rx(ByVal sender As Object, _
                  ByVal e As serialDataReceivedEventArgs)
       
   Try
    
‘Añadir la recepcion actual al buffer           
     
PortSerie_Recepcion += PortSerie.ReadExisting           
    
If PortSerie_Recepcion.Contains(Chr(13)) Then
               
        
RaiseEvent RxFin(PortSerie_Recepcion)               
        
PortSerie_Recepcion = “”
           
    
End If       
  
Catch ex As Exception
    
‘En caso de excepción        
 
End Try
   
 End Sub
End Class


Espero que esto os sirva de idea, esperando dejaros un ejemplo para descargar tan pronto como me sea posible.
Saludos,
Pep Lluis,

5 thoughts on “Una alternativa al SerialPort.ReadLine”

  1. Hola, estoy intentando recibir datos desde un micro. ¿Ese Ch(13) se supone que lo tengo que enviar con el micro al final de cada trama? ¿Qué es exactamente Ch(13)? He mirado la tabla ASCII y no pone que sea ningún carácter.

    Siento si la pregunta es tonta, pero es que estoy un poco perdida…

    Muchas gracias por la ayuda y los tutoriales.

  2. Hola!,
    En muchas aplicaciones el Chr(13) o CR se considera fin de trama. Una trama es una unidad de intercambio de informacion entre dos dispositivos. En tu caso si tienes control sobre lo que envia el Micro, puedes usar cualquier caracter que te apetezca como testigo de fin de trama…. por ejemplo imaginemos un dispositivo envia “#0101010101*” para indicar el estado de un byte, entonces podremos considerar el “*” como fin de trama, por poner un ejemplo.
    Saludos,

  3. Muchas gracias, PepLluis, ya veo lo que dices.

    Tengo otra duda, en los códigos que tienes para recibir datos siempre pones:

    ‘Anadir el manipulador de recepcion en la sub New, Load…
    AddHandler PortSerie.DataReceived, AddressOf Rx

    No sé muy bien a qué te refieres con eso, imagino que el AddHandler tiene que ir dentro de un procedimiento Sub, así que debería poner algo como:

    Sub New()handles X
    AddHandler MiPuerto.DataReceived, AddressOf Rx
    End Sub

    Pero no sé qué tiene que ser exactamente X

    También me dice que el tipo serialDataReceivedEventArgs no está definido, pero no sé muy bien qué hace, así que no sé cómo ni para qué definirlo.

    Muchísimas gracias.

  4. Thorgal,
    Tienes dos formas de llamar al constructor, una es arrastrando el “SerialPort” desde la barra de herramientas al form y la otra de forma manual en referencia al espacio de nombres. ejem: Dim MiPuertoSerie As New System.IO.Ports.SerialPort
    En el caso de arrastrar, visual estudio nos crea el objeto pudiendo referenciar sus funciones/metodos/eventos desde el editor de visual studio. En el caso que nos ocupa al construirlo manualmente debemos dar la funcionalidad del objeto tambien manualmente asignando por ejemplo el direccionamiento de eventos a las correspondientes funciones.
    En este caso, le estamos asignando el evento ‘DataReceived’ del PortSerie para que apunte a nuestra funcion de recepcion de datos ‘Rx’. El Addhandler puedes colocarlo en cualquier parte de la clase… pero es aconsejable en “load” si hablamos de “foms”.
    Si te parece que puede ser util, ponemos un ejemplo de cada y asi podras ver la diferencia.
    Saludos,

  5. Muchísimas gracias por tu ayuda, PepLluis, ya me funciona el programita :)

    Yo en realidad ya había hecho lo que dices de arrastrar el “SerialPort” de la barra de herramientas al Form1.

    En todo caso, imagino que en ambas situaciones habrá que hacer lo de asignar el evento DataRecived a la función Rx, ya que en ambos casos queremos procesar la información una vez nos haya llegado. He puesto como dices esa línea de código en el Load de mi Form.

    Lo de que el tipo serialDataReceivedEventArgs no estaba definido era que había importado ‘System.IO’ en lugar de ‘System.IO.Ports’.

    Bueno, ahora me queda pasar la información a un excel porque simplemente había puesto que me saliera por un messagebox.

    Muchísimas gracias otra vez, me has salvado la vida :)

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>