Portal    Foro    Buscar    FAQ    Registrarse    Conectarse


Publicar nuevo tema  Responder al tema 
Página 1 de 2
Ir a la página 1, 2  Siguiente
 
SerialPort: Problema Con ¿longitud Del Buffer?
Autor Mensaje
Responder citando   Descargar mensaje  
Mensaje 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!
 



 
ariel - Ver perfil del usuarioEnviar mensaje privado 
Volver arribaPágina inferior
Responder citando   Descargar mensaje  
Mensaje 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:
PRIVATE downloadBuffer AS String

PUBLIC SUB Socket1_Read()
  DIM buffer AS String
  READ #LAST, buffer, Lof(LAST)
  downloadBuffer &= buffer
END
 

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"
 
jguardon - Ver perfil del usuarioEnviar mensaje privado 
Volver arribaPágina inferior
Responder citando   Descargar mensaje  
Mensaje Re: SerialPort: Problema Con ¿longitud Del Buffer? 
 
Gracias por la ayuda!

Mi rutina de recepción es muy simple:

PUBLIC SUB conPuertoSerie_Read()
  DIM saux AS String
  SLEEP 0.25
  TRY READ #conPuertoSerie, saux, Lof(conPuertoSerie)
  TextArea1.Text = saux
END


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!!!  
 



 
ariel - Ver perfil del usuarioEnviar mensaje privado 
Volver arribaPágina inferior
Responder citando   Descargar mensaje  
Mensaje 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". ....
 



 
ariel - Ver perfil del usuarioEnviar mensaje privado 
Volver arribaPágina inferior
Responder citando   Descargar mensaje  
Mensaje 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.
 



 
soplo - Ver perfil del usuarioEnviar mensaje privado 
Volver arribaPágina inferior
Responder citando   Descargar mensaje  
Mensaje 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:

pantallazo

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:
PUBLIC SUB bLeerDatos1_Click()
  DIM saux AS String
  IF conPuertoSerie.Status = Net.Inactive THEN
    Message("Hay que conectarse antes!")
  ELSE
      PRINT #conPuertoSerie, ":ACQ1:POIN"; Chr$(13); Chr$(10);

      SLEEP 0.025
      TRY READ #conPuertoSerie, saux, 7
          TextArea1.Text = saux
      END IF      
END
 

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 ......
 



 
ariel - Ver perfil del usuarioEnviar mensaje privado 
Volver arribaPágina inferior
Responder citando   Descargar mensaje  
Mensaje 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
public mensaje AS byte[]

PUBLIC SUB Socket1_Read()
  DIM buffer AS byte, Contador as integer
  for Contador=0 to TotalbytesEnviados
     READ #LAST, buffer
     mensaje.add buffer
  next
END


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

public mensaje AS file

mensaje=open "imagen.jpg" for create
PUBLIC SUB Socket1_Read()
  DIM buffer AS byte, Contador as integer
  for Contador=0 to TotalbytesEnviados-1
     READ #LAST, buffer
     print #mensaje,buffer
  next
END


cuando hayas acabado de leer cierras
mensaje.close

y allí tendrás tu archivo imagen.jpg con los datos que has leído.
 



 
soplo - Ver perfil del usuarioEnviar mensaje privado 
Volver arribaPágina inferior
Responder citando   Descargar mensaje  
Mensaje 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...   )
 



 
ariel - Ver perfil del usuarioEnviar mensaje privado 
Volver arribaPágina inferior
Responder citando   Descargar mensaje  
Mensaje 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.
DIM mensaje[512] AS Byte

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
DIM mensaje[] AS Byte

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.

 
 



 
soplo - Ver perfil del usuarioEnviar mensaje privado 
Volver arribaPágina inferior
Responder citando   Descargar mensaje  
Mensaje 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"
 
jguardon - Ver perfil del usuarioEnviar mensaje privado 
Volver arribaPágina inferior
Mostrar mensajes anteriores:    
 
OcultarTemas parecidos
Tema Autor Foro Respuestas último mensaje
No hay nuevos mensajes Problema Al Intentar Ejecutar El Ejemplo D... pax General 2 Martes, 09 Noviembre 2010, 09:41 Ver último mensaje
jsbsan
No hay nuevos mensajes ¿como Vaciar El Buffer De Eventos? jsbsan General 4 Jueves, 03 Octobre 2013, 06:38 Ver último mensaje
jsbsan
No hay nuevos mensajes SerialPort hackermauro87 Controles/Librerías/Componentes 1 Jueves, 01 Octobre 2015, 23:05 Ver último mensaje
jguardon
No hay nuevos mensajes Copiar Página Web En Buffer calcena General 11 Jueves, 19 Octobre 2017, 17:29 Ver último mensaje
tincho
 

Publicar nuevo tema  Responder al tema  Página 1 de 2
Ir a la página 1, 2  Siguiente

Usuarios navegando en este tema: 0 registrados, 0 ocultos y 1 invitado
Usuarios registrados conectados: Ninguno


 
Lista de permisos
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



  

 

cron