none
Problemas con Puerto Serie. RRS feed

  • Pregunta

  • Hola.

     

    Espero que esto le pase a alguien más porque estoy algo desesperado buscando soluciones.

     

    Estoy trabajando con una aplicación en Visual Basic (VS2005) que simplemente abre el puerto serie y muestra por pantalla lo que recibe. En el puerto serie tengo conectado un escaner (mediante un adaptador Serie - USB ya que mi equipo no dispone de puerto serie estándar).

     

    Mi problema es que al saltar el evento DataReceived ejecuto el ReadExisting para capturar la información pero esta nunca está completa. Si lo que recibo es una cadena de caracteres de longitud 13 (código de barras que lee el escaner), lo mas habitual es que reciba dos eventos y reciba los datos en dos grupos de por ejemplo 4 y 9 caracteres.

     

    El código es bien sencillo.

     

    También he probado a leer en un bucle mientras el valor de BytesToRead sea mayor que 0, pero el resultado es el mismo.

     

    La única solución que he encontrado es esperar medio segundo en el código del evento DataReceived (desde que se lanza hasta que hago el ReadExisting) pero no me parece una solución nada buena.

     

    ¿Alguien sabe a qué es debido y cómo solucionarlo?

    miércoles, 18 de abril de 2007 13:48

Respuestas

  • Hola Javi,

     y Gracias por lo de maquina! Luis!, supongo que lo dices porque pertenezco a la epoca en que los ordenadores aun tenian Puerto Serie... ja ja ja ja :-))

     

    Primero debemos ser muy cautelosos en escoger conversores USB-Serie... pues algunos no terminan de funcionar o integrarse bien en el sistema, y por ahi podemos tener alguna que otra sorpresa.

     

    Lo que te ocurre... no es un problema!, ten en cuenta que estamos hablando de comunicaciones serie asincronas, por lo tanto los bits se serializan y viajan lentamente  como mucho a velocidades de 19,2k o 38,4. El evento DataReceived se dispara cuando el controlador de comunicaciones recibe el primer byte en el buffer, no es de extrañar que el gran procesador lea todo el buffer antes de que termine de llegar la transmision completa. (tambien puede ocurrir que ciertos conversores usb/serie tengan una carga puntual entre la recepcion y la transmision que provoque ese efecto).

     

    En tu caso, deberiamos entender o responder a la pregunta : ¿como identificamos el final de una trama?... por longitud?... por un CR al final?... por ambas?, una de las tecnicas es montar un array o string de recepcion en funcion a si estamos en una transmisión binaria o ascii, para poder tomar de ella tramas completas, indistintamente se reciban de un solo golpe o en diversas recepciones. Queda claro que despues de 'ReadExisting' cuando el controlador reciba otro caracter, volvera a disparar el evento!

     

    Por ejemplo : Imaginemos que esperamos 9 caracteres y un 'Carriage Return', podriamos hacerlo como sigue :

     

    Code Snippet

        '

        'procesar cada vez que recibimos un caracter 13 por COM1

        '(contemplar la recepcion sin un Chr(13) para descartar la trama)

        Private Sub RecibirdeCOM1(ByVal sender As Object, ByVal e As SerialDataReceivedEventArgs)

            RecibidosCOM1 += MiCOM1.ReadExisting

            If RecibidosCOM1.IndexOf(Chr(Keys.Enter)) > -1 Then

                Me.Invoke(New ProcesarCOM1(AddressOf RecepcionesdeCOM1))

                RecibidosCOM1 = ""  'Borrar datos procesados

            End If

        End Sub

        '

        'Añadir los datos recibidos por COM1 a Su lista

        Private Sub RecepcionesdeCOM1()

            If RecibidosCOM1.Length = 9 Then

                'procesar la trama

            Else

                'descartar por no cumplir la longitud

            End If

        End Sub

     

    Entorno a esta SUB, deberemos construir nuestros procedimentos de identidicacion de tramas, que en tu caso desconozco, por no tener detalle del dispositivo. Como veis MUY BASICO.

     

    Me gustara recibir vuestros comentarios!

    Saludos,

    Pep Lluis,

    miércoles, 18 de abril de 2007 16:38
    Moderador

Todas las respuestas

  • Hola Javi:

     

    Yo tengo el mismo problema en una aplicación y he optado por poner un retardo, pero no te preocupes que en cuanto el máquina de Pep lo vea seguro que nos da una buena solución.

     

    Salu2

     

    Colabora con el foro: Si la respuesta te es de utilidad marca la pregunta como respondida.

    Luis Ruiz Pavón

    MCP

    Blog: http://geeks.ms/blogs/lruiz

    miércoles, 18 de abril de 2007 14:37
  • Hola Javi,

     y Gracias por lo de maquina! Luis!, supongo que lo dices porque pertenezco a la epoca en que los ordenadores aun tenian Puerto Serie... ja ja ja ja :-))

     

    Primero debemos ser muy cautelosos en escoger conversores USB-Serie... pues algunos no terminan de funcionar o integrarse bien en el sistema, y por ahi podemos tener alguna que otra sorpresa.

     

    Lo que te ocurre... no es un problema!, ten en cuenta que estamos hablando de comunicaciones serie asincronas, por lo tanto los bits se serializan y viajan lentamente  como mucho a velocidades de 19,2k o 38,4. El evento DataReceived se dispara cuando el controlador de comunicaciones recibe el primer byte en el buffer, no es de extrañar que el gran procesador lea todo el buffer antes de que termine de llegar la transmision completa. (tambien puede ocurrir que ciertos conversores usb/serie tengan una carga puntual entre la recepcion y la transmision que provoque ese efecto).

     

    En tu caso, deberiamos entender o responder a la pregunta : ¿como identificamos el final de una trama?... por longitud?... por un CR al final?... por ambas?, una de las tecnicas es montar un array o string de recepcion en funcion a si estamos en una transmisión binaria o ascii, para poder tomar de ella tramas completas, indistintamente se reciban de un solo golpe o en diversas recepciones. Queda claro que despues de 'ReadExisting' cuando el controlador reciba otro caracter, volvera a disparar el evento!

     

    Por ejemplo : Imaginemos que esperamos 9 caracteres y un 'Carriage Return', podriamos hacerlo como sigue :

     

    Code Snippet

        '

        'procesar cada vez que recibimos un caracter 13 por COM1

        '(contemplar la recepcion sin un Chr(13) para descartar la trama)

        Private Sub RecibirdeCOM1(ByVal sender As Object, ByVal e As SerialDataReceivedEventArgs)

            RecibidosCOM1 += MiCOM1.ReadExisting

            If RecibidosCOM1.IndexOf(Chr(Keys.Enter)) > -1 Then

                Me.Invoke(New ProcesarCOM1(AddressOf RecepcionesdeCOM1))

                RecibidosCOM1 = ""  'Borrar datos procesados

            End If

        End Sub

        '

        'Añadir los datos recibidos por COM1 a Su lista

        Private Sub RecepcionesdeCOM1()

            If RecibidosCOM1.Length = 9 Then

                'procesar la trama

            Else

                'descartar por no cumplir la longitud

            End If

        End Sub

     

    Entorno a esta SUB, deberemos construir nuestros procedimentos de identidicacion de tramas, que en tu caso desconozco, por no tener detalle del dispositivo. Como veis MUY BASICO.

     

    Me gustara recibir vuestros comentarios!

    Saludos,

    Pep Lluis,

    miércoles, 18 de abril de 2007 16:38
    Moderador
  • Como siempre Pep un gran aporte, en mi caso espero un CR a final de trama.

     

    Lo probaré.

     

    Un saludo.

     

    Colabora con el foro: Si la respuesta te es de utilidad marca la pregunta como respondida.

    Luis Ruiz Pavón

    MCP

    Blog: http://geeks.ms/blogs/lruiz

    jueves, 19 de abril de 2007 10:02
  •  

     Hola Pep.

     

    En mi caso trabajo con un escaner que envia un CR al final de la trama. Imagino además que esto es configurable en los distintos tipos de escaner que existen.

     

    Lo probaré y de alguna manere u otra forzaré a que se envíe un caracter finalizador de trama.

     

    Gracias por tu ayuda y saludos a todos (me refiero a tí, Luis).

    jueves, 19 de abril de 2007 11:40
  • aqui hay videos sobre estos temas...

    http://www.fabianrene.com

    jueves, 3 de mayo de 2007 15:45