|
Página 1 de 2
|
SerialPort: Problema Con ¿longitud Del Buffer?
Autor |
Mensaje |
ariel
Aprendiz
Registrado: Octobre 2009
Mensajes: 51
Edad: 55
|
SerialPort: Problema Con ¿longitud Del Buffer?
Hola amigos!
Este es mi primer mensaje en el foro.
Estoy armando una aplicacion para conectar mi PC con un osciloscipio digital.
Todo venia viento en popa hasta que necesite leer un "paquete" de bytes de aproximadamente 1KB de longitud. Al hacerlo, me da un error que dice algo como:
(SerialPort:12473): Gtk-CRITICAL **: gtk_text_buffer_emit_insert: assertion `g_utf8_validate (text, len, NULL)' failed
Con comandos "pequeños", que devuelven solo unos pocos bytes, no tengo problema.
supongo que de alguna manera debo tener que modificar la longitud del buffer que recibe los caracteres que me envia el osciloscopio via el puerto serie, pero la verdad es que no se de donde hacerlo.
¿Alguien puede darme una idea?
Gracias!
|
#1 Lunes, 05 Octobre 2009, 18:07 |
|
|
jguardon
Administrador
Registrado: Septiembre 2009
Mensajes: 2708
Edad: 57 Ubicación: Granada
|
Re: SerialPort: Problema Con ¿longitud Del Buffer?
Hola ariel
Eso tiene pinta de que el tamaño del buffer es limitado y no puede manejarlo si se sobrepasa ese límite.
No sé, se me ocurre que podrías limitar el tamaño de los datos recibidos, pongamos a 256 bytes, e ir encadenando el paquete en las siguientes llamadas hasta completarlo. Es una idea, pero ahora no sé cómo ponerla en práctica. Una cosa parecida al método asíncrono del httpClient get:
Si se me enciende la bombilla, ya te avisaré...
Saludos
=================== Jesús Guardón
Por favor, usemos el corrector ortográfico antes de pulsar el botón "Enviar".
"uo ǝs ʇɐu pıɟıɔıן ɐdɹǝupǝɹ ɐ dɹoƃɹɐɯɐɹ, soןo ɥɐʎ bnǝ dɹodouǝɹsǝןo"
|
#2 Lunes, 05 Octobre 2009, 18:34 |
|
|
ariel
Aprendiz
Registrado: Octobre 2009
Mensajes: 51
Edad: 55
|
Re: SerialPort: Problema Con ¿longitud Del Buffer?
Gracias por la ayuda!
Mi rutina de recepción es muy simple:
Recien arranco con gambas, y esto lo saque de la aplicacion que trae de ejemplo. Asumo que lee todo el buffer a la vez.
Voy a ver si puedo usar lo que me pasas para modificarla.
Y........gracias por la ayuda!!!
|
#3 Lunes, 05 Octobre 2009, 18:36 |
|
|
ariel
Aprendiz
Registrado: Octobre 2009
Mensajes: 51
Edad: 55
|
Re: SerialPort: Problema Con ¿longitud Del Buffer?
Parece que encontré la causa del problema.
Los primeros 6 bytes a leer son "#41008". Entre otras cosas, el "1008" es la longitud de la cadena que viene detrás. El problema es que los bytes siguentes son algo asi como "0x39 0x83 0x12 0x6F...............:" , es decir, son valores en hexadecimal que pueden varia desde 0 a 255. Es muy posible que algunos de ellos sean tomados como caracteres de control o algo asi por gambas, y eso provoca el "corte" de la recepcion de datos. ¿Podrá ser?
¿Hay alguna forma de "abrir" el puerto en modo ....binario...o algo asi, donde no me pase esto?
Gracias de nuevo!
EDITO: Parece que puedo leer bien hasta que me llega el código hexadecimal "0x83". ....
|
#4 Lunes, 05 Octobre 2009, 19:18 |
|
|
soplo
Analista Programador
Registrado: Septiembre 2009
Mensajes: 843
Edad: 44
|
Re: SerialPort: Problema Con ¿longitud Del Buffer?
Yo creo que no te estoy entendiendo bien. Vamos a ver
Si te envían datos en string entonces parece razonable que leas 0x83 que es un string de cuatro caracteres y que a efectos de transmisión son CUATRO BYTES. Sin embargo si te envían datos en binario 0x83 se corresponde con el valor decimal 110 y en binario 100000011 que es UN BYTE.
Si miras el valor de un byte que contiene el valor binario 100000011 lo normal es que se te muestre el resultado en hexadecimal en la pantalla y tu veas 0x83.
Osea que no es que se lie con la 'x' sino que no lee ese byte.
La orden read que te puso jguardion es la de lectura de un flujo y la variable que lee lo que hace es leer valores binarios o una string según como hayas declarado la variable. Si la declaraste como string entonces debes darle la longitud. Si la declaraste como binaria entonces no.
Menciono otro tema que veo:
Has utilizado la orden sleep. Esta orden retrasa la ejecución un determinado tiempo en el que no hay eventos. La orden wait hace igual salvo que en ese lapso de tiempo si hay eventos.
No estoy seguro pero creo recordar que cuando lees del puerto serie y se levanta read si utilizas wait puedes causar un agotamiento de la pila porque se ejecuta read y tu haces wait y como siguen los eventos puede llegar otro read con su respectivo wait, ..., etc.
Sin embargo si usas sleep puedes estar causando que el retardo haga que para cuando haya pasado ese lapso de tiempo sin eventos ya no haya datos a recibir porque hayan sido enviados todos.
Pudiera ser eso lo que te pasa.
No te digo que uses uno u otro. Solo que consideres esa posibilidad.
|
#5 Lunes, 05 Octobre 2009, 20:30 |
|
|
ariel
Aprendiz
Registrado: Octobre 2009
Mensajes: 51
Edad: 55
|
Re: SerialPort: Problema Con ¿longitud Del Buffer?
Hola Soplo!
Gracias por la respuesta.
Vamos por parte, por que me parece que en el apuro por resolver esto no he sido nada (pero nada!) claro
Tengo un osciloscopio con salida para PC, por puerto serie. Uno le manda comandos, y el responde con una cadena de bytes. La mayoria de los comandos devuelven cadenas cortas (una tension, frecuencia, cosas asi). Peeeeeero .....hay uno que devuelve la imagen de la pantalla, y me interesa de sobre manera poder leerla por que de esa forma podria graficar e imprimir (entre otras cosas) lo que estoy midiendo.
Aclaro de nuevo que no tengo mucha idea de gambas (aunque creo que eso ya quedó reclaro! )
Use "Sleep" por que lo vi en otro ejemplo....y sin ella no podia leer nada. Con ese pequeño retardo los comandos "cortos"andan.
La cadena larga que quiero leer tiene el siguiente formato:
No se ve muy bien, pero la idea es que hay 6 bytes al principio -4 de los cuales contienen la longitud total de la cadena ( el "1008")- y atras vienen los datos en si. Los datos están en hexadecimal....
Mi codigo parece que los trata como caracteres, y ahi me aparece el problema.
Si hago esto:
Lee los primeros 7 bytes bien. Si intento leer 8, me sale el error del post anterior.
Asi es como abri la conexion:
PUBLIC SUB Form_Open()
conPuertoSerie = NEW SerialPort AS "conPuertoSerie"
END
PUBLIC SUB bConectar_Click()
IF conPuertoSerie.Status = Net.Active THEN
CLOSE conPuertoSerie
TextArea1.Text = "Desconectado."
bConectar.Text = "Conectar"
ELSE
' Line parameters
conPuertoSerie.PortName = "/dev/ttyS0"
conPuertoSerie.Speed = 19200
conPuertoSerie.Parity = 0
conPuertoSerie.DataBits = 8
conPuertoSerie.StopBits = 1
conPuertoSerie.FlowControl = 0
conPuertoSerie.Open()
conPuertoSerie.DTR = 1
conPuertoSerie.RTS = 1
'Check_Status()
IF conPuertoSerie.Status = Net.Active THEN
TextArea1.Text = "Conectado a " & conPuertoSerie.PortName & "(" &
conPuertoSerie.Speed & "baudios, " & conPuertoSerie.Parity & "," & conPuertoSerie.DataBits & "," &
conPuertoSerie.StopBits & ")" & Chr(13) & Chr(10)
bConectar.Text = "Desconectar"
END IF
END IF
END
Espero ahora, mas tranquilo, haber sido mas claro
El 0x83 que me manda el aparato debe darme un error por estar encima del caracter (decimal) 127....o al menos eso es lo que me imagino. Seguramente estoy equivocado ......
|
#6 Lunes, 05 Octobre 2009, 22:54 |
|
|
soplo
Analista Programador
Registrado: Septiembre 2009
Mensajes: 843
Edad: 44
|
Re: SerialPort: Problema Con ¿longitud Del Buffer?
Bueno, a ver
El problema que tengo es que mas o menos se como funciona esto, pero nunca he trabajado con serialport.
Intenta esto
La idea es la siguiente:
creas un array de bytes al que irás añadiendo cada byte que leas. Para ello y como parte de saber la longitud del mensaje que te envian haces un bucle para leer cada byte y añadirlo a mensaje.
Al final obtienes en Mensaje todos los bytes recibidos. de esta menera los tendrás en un array de bytes, pero si quieres también puedes guardarlos en un fichero
cuando hayas acabado de leer cierras
y allí tendrás tu archivo imagen.jpg con los datos que has leído.
|
#7 Martes, 06 Octobre 2009, 16:53 |
|
|
ariel
Aprendiz
Registrado: Octobre 2009
Mensajes: 51
Edad: 55
|
Re: SerialPort: Problema Con ¿longitud Del Buffer?
Soplo, eres un maldito genio!!!!
Tu respuesta me llevó a la solucion. Finalmente, puedo leer todos los valores. Ahora "solo" me falta recorrer el vector graficando los puntos. Cada punto tiene un valor de Y dado por dos bytes consecutivos, y no me deberia ser muy dificil.
Ya veremos!
Asi me quedó el código, lo pongo por si alguien necesita algo parecido (no hay muchos ejemplos de uso del control SerialPort):
PUBLIC SUB bLeerDatos1_Click()
DIM saux AS String 'String auxiliar
DIM buffer AS Byte 'Almacena cada byte leido
DIM Contador AS Integer 'Variable para el FOR... que recorre los datos
DIM TotalbytesEnviados AS Integer 'Cantidad de datos a leer.
DIM mensaje[512] AS Byte
'Si el puerto está abierto......
IF conPuertoSerie.Status = Net.Inactive THEN
Message("Hay que conectarse antes!")
ELSE
'Envio mensaje al osciloscopio, solicitando los datos.
PRINT #conPuertoSerie, ":ACQ1:POIN"; Chr$(13); Chr$(10);
'Espero.....
SLEEP 0.125
'...y leo la longitud de los datos.
TRY READ #conPuertoSerie, saux, 6
TextArea1.Text = saux
TotalbytesEnviados = Val(Mid$(saux, 3, 4))
'Recorro el buffer leyendo los bytes de séptimo al ultimo.
FOR Contador = 0 TO TotalbytesEnviados
READ #conPuertoSerie, buffer
mensaje[Contador] = buffer
NEXT
'Aqui va el llamado a la rutina que grafica los puntos leídos.
END IF
END
Nuevamente, gracias a todos.
(Ya volveré a preguntar alguna cosilla... )
|
#8 Martes, 06 Octobre 2009, 19:05 |
|
|
soplo
Analista Programador
Registrado: Septiembre 2009
Mensajes: 843
Edad: 44
|
Re: SerialPort: Problema Con ¿longitud Del Buffer?
Me alegro de que te funcione, pero veo que has dimensionado un espacio máximo de 512 bytes.
Y luego para poner cada byte en su sitio utilizas el índice del array
FOR Contador = 0 TO TotalbytesEnviados
READ #conPuertoSerie, buffer
mensaje[Contador] = buffer
NEXT
A mi entender esto puedes mejorarlo de las siguientes formas:
Declarar la variable sin dimensionar
y luego añadir cada byte que lees
FOR Contador = 0 TO TotalbytesEnviados
READ #conPuertoSerie, buffer
mensaje.add (buffer)
NEXT
La otra forma que veo es dimensionar utilizando una variable. Dado que tienes el valor máximo del mensaje debes saber que es posible dimensionar utilizando variables
Dim Mensaje[TotalbytesEnviados]
En ambos casos la rutina se adaptará a cualquier longitud y no dependerá de que sean 512 bytes.
|
#9 Martes, 06 Octobre 2009, 19:31 |
|
|
jguardon
Administrador
Registrado: Septiembre 2009
Mensajes: 2708
Edad: 57 Ubicación: Granada
|
Re: SerialPort: Problema Con ¿longitud Del Buffer?
Fantástico, soplo y ariel
Pero aún me queda la duda de porqué usas la expresión SLEEP, que aunque sea necesaria, provocará la congelación momentánea de la aplicación.
En su lugar yo utilizaría WAIT 0.125 que debería hacer lo mismo pero sin congelar la aplicación completa. ¿Habéis probado de esa forma?
Saludos
=================== Jesús Guardón
Por favor, usemos el corrector ortográfico antes de pulsar el botón "Enviar".
"uo ǝs ʇɐu pıɟıɔıן ɐdɹǝupǝɹ ɐ dɹoƃɹɐɯɐɹ, soןo ɥɐʎ bnǝ dɹodouǝɹsǝןo"
|
#10 Martes, 06 Octobre 2009, 19:43 |
|
|
|
Temas parecidos
Temas parecidos
|
Página 1 de 2
|
Usuarios navegando en este tema: 0 registrados, 0 ocultos y 1 invitado Usuarios registrados conectados: Ninguno
|
No puede crear mensajes No puede responder temas No puede editar sus mensajes No puede borrar sus mensajes No puede votar en encuestas No puede adjuntar archivos Puede descargar archivos No puede publicar eventos en el calendario
|
|
|
|
|