Lenguajes de programación para PC => Visual Basic => Mensaje iniciado por: Javicho en 07 de Enero de 2010, 17:31:05
Título: Error de recepción RS232
Publicado por: Javicho en 07 de Enero de 2010, 17:31:05
Saludos a todos:
Estoy haciendo un programa para mostrar datos en un MSFlexgrid los cuales los envia mi pic via RS232. El pic envia asi: 1Javier(13)2jueves(13)307/01/10(13) ... el (13) en realidad el pic envia d'13' es decir retorno de carro, mi plan era el siguiente (tal vez aqui está mi error ojalá me corrijan) configuro RThreshold=1 para que el evento OnComm se dispare cada 1 byte, luego en la variable "cadena" almaceno de forma concatenada los bytes que llegan y dentro de un IF esperar la llegada del (13) luego extraer lo que me interesa y mostrarlo en la tabla en el casillero correspondiente, pero no me funciona.
Ayudandome de una caja de texto veo que cuando el pic envia los bytes lento (cada 1seg) cadena muestra solo un caracter, esto no ocurre cuando envio rapido bytes tras byte sin delay de por medio y cuando hago text2.text=buffer me muestra la llegada de varios caracteres a pesar que he configurado el RThreshold=1.
Cuando se produce el evento OnComm hago:
Dim buffer As String Dim cadena As String
buffer=MSComm1.input text2.text=buffer cadena = cadena & buffer If buffer = chr(13) then ... aqui viene codigo end if
pero el flujo del programa nunca pasa por el If, que puede estar pasando?
Javicho.
Título: Re: Error de recepción RS232
Publicado por: Suky en 07 de Enero de 2010, 21:40:30
Yo lo haría:
Código: FreeBasic
Dim buffer As object
if MSComm1.InBufferCount >1then
buffer=MSComm1.input
text2.text=buffer(0)
cadena = cadena & buffer(0)
If buffer(0) = chr(13)then
... aqui viene codigo
endif
endif
Y la variable cadena seria global.
Saludos!
Título: Re: Error de recepción RS232
Publicado por: Ducky en 08 de Enero de 2010, 01:35:28
Hola, estoy de acuerdo con lo que Suky comenta, umm pero tambien podrias enviar una "," y ocupar un split en visual para separar tus datos, bueno esta es otra opcion.
Ej. tu pic envia: 1Javier,2jueves,307/01/10
en visual seria algo así:
cadena = TxtRx.Text array = Split(cadena, ",") For i = LBound(array) To UBound(array) msgbox = arreglo(i) 'Aqui podrias agregar tu dato al flexgrid Next
saludos!! :)
Título: Re: Error de recepción RS232
Publicado por: Javicho en 14 de Enero de 2010, 19:28:06
Saludos a todos:
Disculpen que no haya podido contestar estos dias, tuve que ausentarme pero ya regresé. Gracias
por contestar, pero retomando el tema encontré un problema grave ... mi pic envia a la PC lo siguiente: 1PIC, H'0D', (2seg), 2RS232, H'0D', (2seg), 301/02/03, H'0D', (2seg), 4TodoPic, H'0D', (4seg) y todo esto en bucle infinito. Envio H'0D' para indicar que finalizó una cadena.
En el Visual Basic 6 tengo lo siguiente:
Private Sub Form_Activate() With MSComm1 .CommPort = 1 'Com1 .Settings = "9600,N,8,1" '9600bps, sin paridad, 8 bits de datos, 1 bit de stop .Handshaking = comNone 'Sin Control de flujo .InputLen = 0 'Cuando se use Input leerá el buffer RX completo .RThreshold = 1 'Cuando recibe 1byte se produce el evento OnComm .EOFEnable = False 'No espero disparar el OnComm al recibir d'26' End With End Sub
Private Sub MSComm1_OnComm() Dim a1 As String Static i As Integer i = i + 1 Label1.Caption = i 'Incrementar por cada byte que llega al puerto Select Case MSComm1.CommEvent Case comEvReceive a1 = MSComm1.Input Text1.Text = a1 'Lo que llega lo muestro en la caja de texto End Select End Sub
Cuando corro el programa veo que el Label se incrementa de 1 en 1 pero el Text1 aparece toda la cadena, es como si hubiese configurado al programa para que se muestre el resultado solo cuando llegue una determinada cantidad de caracteres y no es asi, yo tengo configurado el puerto para que se dispare cuando llega 1 byte. Pero este problema se soluciona si agrego un delay de 1seg entre cada caracter enviado, es decir: 1, (1seg), P, (1seg), I, (1seg), C, (1seg), H'0D', (1seg), 2, (1seg), R, (1seg), etc Y en este caso recien aparece lo que deberia aparecer es decir en el Text se ve un caracter y a la vez el label incrementa en 1, luego aparece el siguiente caracter y el label vuelve a incrementar en 1.
Que es lo que estoy haciendo mal? espero me puedan aconsejar. Gracias
Javicho.
Título: Re: Error de recepción RS232
Publicado por: PalitroqueZ en 14 de Enero de 2010, 20:09:31
Hola javicho.
según lo que he entendido, parece que tienes problemas con el flujo de los datos, deberías implementar un control, es decir, controlar los datos que te están llegando. El software sería una especie de "master" se encargaría de decirle al pic cuando detenerse y cuando está listo para recibir el siguiente dato.
una forma básica de hacerlo es con un eco (mandas un dato apenas recibas, y el pic debe recibir ese dato antes de enviar el siguiente)
Título: Re: Error de recepción RS232
Publicado por: Javicho en 15 de Enero de 2010, 11:28:38
Saludos:
Claro mi objetivo es enviar los datos por paquetes es decir un byte de cabecera + NBytes + OpCode + "datos" + Checksum, donde NBytes es la cantidad de bytes que vienen a continuación, OpCode indica el tipo de trama que ha llegado, luego si el Checksum es correcto el visual le responde al PIC con otra trama indicando que la última trama recibida llegó en perfectas condiciones.
Por eso simulo enviando desde el pic: 1PIC, H'0D' ... 4TodoPic, H'0D' pero no trabaja como quiero, tal vez el visual necesita un poco de tiempo para procesar cada byte que llega, he bajado el delay de 1seg entre caracteres hasta 100ms y funciona bien, pero queria enviar los datos sin delay entre caracter y caracter.
Algo debo estar haciendo mal o deberia emplear una mejor técnica de recepción porque tengo entendido que desde el visual se puede comunicar con modems etc y estos no perdonan y envian sus tramas de datos byte tras byte sin delay entre ellos.
A ver si alguien me da alguna luz en esto, gracias.
Javicho.
Título: Re: Error de recepción RS232
Publicado por: Ducky en 15 de Enero de 2010, 20:38:31
Hola!!, umm si lo que quieres es recibir los datos de manera continua sin utilizar un buffer, porque no usas un Timer en visual, que te sirva para la recepcion de datos, mira yo lo manejo así y no me da problemas para recibir:
Private Sub Timer1_Timer() Dim txtin As String txtin = MSComm1.Input If txtin <> "" Then Text2 = Text2 + txtin End If End Sub
NOTA: El timer en su Intervalo debe estar entre 40 y 60 (Yo uso Intervalo de 60), umm y mientras no tengas el puerto abierto debe estar deshabilitado y al abrir el puerto lo habilitas
Saludos!!
Título: Re: Error de recepción RS232
Publicado por: Javicho en 16 de Enero de 2010, 13:52:38
Saludos:
En realidad los datos llegan, el problema es la forma en que estos llegan. Estuve haciendo varias pruebas mas y he encontrado lo siguiente ... el pic envia las tramas siguientes en bucle infinito (no hay delay entre caracteres, solo hay delay de 2seg entre tramas): -------------------------- Cadena1: tiene 28 caracteres (2seg) Cadena2:PIC (2seg) Trama3:Serial (2seg) Fincad (2seg) -------------------------- El programa en Visual:
Private Sub Form_Activate() With MSComm1 .CommPort = 1 'Com1 .Settings = "9600,N,8,1" '9600bps, sin paridad, 8 bits de datos, 1 bit de stop .Handshaking = comNone 'Sin Control de flujo .InputLen = 0 'Cuando se use Input leerá el buffer RX completo .RThreshold = 1 'Cuando recibe 1byte se produce el evento OnComm .EOFEnable = False 'No usar d'26' como fin de trama .PortOpen = True 'Abre el Puerto End With End Sub
Private Sub MSComm1_OnComm() Dim a1 As String Static i, n As Integer
Label1.Caption = "Caracteres sin leer=" & MSComm1.InBufferCount Select Case MSComm1.CommEvent Case comEvReceive i = i + 1 Label2.Caption = "i=" & i 'Indica las veces que se dispara el comEvReceive. 'InBufferCount en este punto debe ser 1 ya que RThreshold = 1. n = n + MSComm1.InBufferCount Label3.Caption = "Contador de caracteres recibidos=" & n a1 = MSComm1.Input Text1.Text = a1 'Muestra solo lo que hay actualmente en el buffer de entrada cadena = cadena + a1 Text2.Text = cadena 'Muestra de forma concatenada todos los caracteres llegados Label4.Caption = "Longitud de Input=" & Len(a1) End Select End Sub --------------------------
Los resultados que muestro estan separados por cadena recibida al puerto y con "/ " :
Caracteres sin leer=4 / 3 / 5 / 6 i=4 / 6 / 8 / 9 grupos de 8 Contador de caracteres recibidos=28 / 39 / 52 / 58 Longitud de Input=4 / 3 / 5 / 6 Text1 = eres / PIC / erial / Fincad Text2 = Cadena1: tiene 28 caracteres / Cadena1: tiene 28 caracteresCadena2:PIC / Cadena1: tiene 28 caracteresCadena2:PICTrama3:SerialFincad
Es decir, cuando llega la cadena "Cadena1: tiene 28 caracteres" el label "Caracteres sin leer" muestra el valor de 4, i=4, Contador de caracteres recibidos=28, Longitud de Input=4, Text1 = eres y Text2 = Cadena1: tiene 28 caracteres
Luego de 2 seg llega la siguiente cadena "Cadena2:PIC" y ahora los valores son: Caracteres sin leer=3, i=6, Contador de caracteres recibidos=39, Longitud de Input=3, Text1 = PIC y Text2 = Cadena1: tiene 28 caracteresCadena2:PIC
... y asi las otras 2 cadenas restantes.
De aqui me parece que cuando el Visual recibe datos uno tras otro sin delay entre ellos, presenta los datos de 8 bytes en 8 bytes, eso explica según mi punto de vista la incongruencia aparente de los resultados que he mostrado.
Por ejemplo la cadena "Cadena1: tiene 28 caracteres" he visto que la PC lo muestra asi en el Text1: Cadena1: (luego se borra y se muestra los siguientes 8 caracteres) tiene 2 (luego se borra y se muestra los siguientes 8 caracteres) 8 caract (luego se borra y se muestra los caracteres restantes) eres
... y esto concuerda con lo que aparece en el Text1 luego de recbida esta trama, pero esto sucede tan rapido y pareciera que solo llegaran los caracteres "eres" de esta trama,pero en realidad llega la trama pero de 8 en 8 caracteres y solo se muestra lo ultimo.
Espero alguien pueda explicarme un poco lo que sucede.
Javicho.
PD: Cuando el pic envia lo mismo pero con delay de 1seg entre caracteres todo funciona bien y los valores registrados son coherentes.
Título: Re: Error de recepción RS232
Publicado por: PalitroqueZ en 16 de Enero de 2010, 16:33:58
umm pues yo sigo pensando que sin un control de flujo, los datos no llegarán como quieres.
cuando empecé a transmitir por rs232, recuerdo que tenía el mismo problema, a veces llegaban los datos de forma extraña. por ej: la cadena "montaña" en bucle infinito, me llegaba a veces "añamon" y cosas así por es estilo.
la soluciones a estos problemas, es controlar el flujo o también sirve, cerrar y abrir el puerto ante cada recepción.
Título: Re: Error de recepción RS232
Publicado por: Javicho en 17 de Enero de 2010, 00:03:28
Saludos:
Claro, obviamente usando control por hardware es mucho mas seguro pero igual debería funcionar usando solo las lineas TX y RX, quisiera saber porque no responde adecuadamente. Si no trabaja bien el puerto es por algo,debe haber una razón lógica para ello.
Javicho
Título: Re: Error de recepción RS232
Publicado por: Javicho en 17 de Enero de 2010, 11:24:44
Saludos:
Luego de muchas pruebas mas creo haber llegado a una conclusión ojala opinen y me corrijan si estoy equivocado: Para el Visual una cadena está formada por bytes consecutivos y no existe delay entre byte y byte. Ejemplo: "Todopic2010" Si por X motivos se colase un delay dentro de la cadena por ejemplo: "Todop(100ms)ic2010" entonces el visual asumirá que llegaron 2 cadenas: "Todop" "ic2010"
Por tanto hay que tener mucho cuidado al enviar nuestras tramas desde el pic. Si deseamos enviar varias tramas consecutivas desde el pic hay que incluirle un delay entre trama y trama o mejor aun deberiamos esperar una respuesta de la PC para que el PIC sepa que la trama que envió fue recibida.
Y sobre el software en visual efectivamente se produce el Evento "comEvReceive" por cada byte recibido y si hacemos: Input_temp = MSComm1.Input cadena = cadena + Input_temp Text1.text=Input_temp Text2.Text = cadena
En Text1 se mostrará solo los ultimos 8 bytes recibidos de la cadena o trama En Text2 se mostrará toda la cadena recibida, pero siempre y cuando declaremos "cadena" en Option Explicit, porque si lo declaramos en "Private Sub MSComm1_OnComm()" se mostrará lo mismo que en Text1.