• Domingo 22 de Diciembre de 2024, 14:06

Autor Tema:  Puerto Serial  (Leído 2708 veces)

benegas

  • Nuevo Miembro
  • *
  • Mensajes: 24
    • Ver Perfil
Puerto Serial
« en: Viernes 27 de Enero de 2006, 18:16 »
0
ESTOY CON UN PROYECTO PARA LEER DATOS DEL PUERTO SERIAL, PERO TENGO UN PROBLEMA QUE ME GUARDA LOS DATOS DE FORMA ENTRE CORTADA LO QUE NO ME SIRVE. LOS DATOS SON MENSAJES DE TEXTOS. MI IDEA ES QUE GUARDE DE FORMA AUTOMATICA EN LA BASE DE DATOS (ACCESS).
SI ALGUIEN ME PUEDE AYUDAR O SUGERIR ALGO LE ESTARIA MUY AGRADECIO.
SALUDOS DESDE PARAGUAY.  :kicking:

Private Sub Form_Load()
    recmen.rsmensajes.Open
    With MSComm1
        .RThreshold = 15
        .InputLen = 0
        'Abre el Puerto
        .PortOpen = True
    End With
End Sub

Private Sub MSComm1_OnComm()
    Dim i As Integer
    Dim Valor As String
    Dim fecha As String
    Dim hora As String
       
    Select Case MSComm1.CommEvent
      Case comEvReceive
     
        Do While MSComm1.InBufferCount > 0
            Valor = MSComm1.Input
            Label1.Caption = "Mensaje Nuevo"
            i = InStr(Valor, Chr(13))
            'MsgBox
            If i = 0 Then
              Cadena = Cadena & Valor
            Else
            Cadena = Cadena & Left(Valor, i - 1)
            Text1.Text = Text1.Text & Cadena
            Text1.SelStart = Len(Text1.Text)
            Cadena = ""
            'MsgBox Cadena
            End If
        Loop
        'MsgBox Cadena
        fecha = Date
        hora = Time$
        recmen.rsmensajes.AddNew
        recmen.rsmensajes!mensaje = Trim(Cadena)
        recmen.rsmensajes!fecha = CStr(fecha)
        recmen.rsmensajes!hora = CStr(hora)
        recmen.rsmensajes.Update
        Mensajes.Refresh
        DataGrid1.Refresh
       
        Case comEvEOF
       
    End Select
End Sub

 :comp:

patitofeo

  • Miembro MUY activo
  • ***
  • Mensajes: 145
    • Ver Perfil
Re: Puerto Serial
« Respuesta #1 en: Lunes 30 de Enero de 2006, 14:06 »
0
Probablemente pierdas datos porque tu rutina de atencion es demasiado pesada.

La rutina de atencion al puerto (evento OnComm del control) debe ser muy ligera ya que si mientras estas en esta rutina, te llegan nuevos datos, el programa volvera a entrar en ella y perdaras los datos anteriores que no le haya dado tiempo a procesar.

Create un buffer para realizar el consumo de datos de modo cliente-servidor

La función MSComm1_OnComm simplemente guarará los datos que le lleguen al buffer con, como mucho, alguna comprobacion de errores sencilla.

Cuando haya recogido los datos puedes activar un flag de modo que avises a la rutina cliente que tiene datos que recoger.

Esta rutina cliente comprobara el buffer que has creado periodicamente y sera la encargada de recogerlos y procesarlos.

    En primer lugar los recogemos del buffer y empezamos el prcesado.

    Mientras procesamos estos datos, la rutina OnComm sigue recibiendo y guardando en el buffer intermedio los datos que llegan por el puerto interrumpiendo a la funcion que procesa los datos  Pero en este caso, ningun dato se perdera.
por que se mantine esperando en el buffer intermedio



Un pseudocodigo:

   Rutina OnComm:
          BufferLlegada=BufferLlegada & MSComm1.Input
          FlagLlegada=True


  Rutina periodica: (el evento Timer de un control Timer programado a 200ms me parece buena idea)
           
       Si FlagLlegada
           BufferProcesado=BufferLlegada
           FlagLlegada=False
           BufferLlegada=""

           FuncionParaProcesarLosDatos



Espero que te sirva

Para cualquier duda, por aqui andare.

Saludos  :hola:

benegas

  • Nuevo Miembro
  • *
  • Mensajes: 24
    • Ver Perfil
Re: Puerto Serial
« Respuesta #2 en: Lunes 30 de Enero de 2006, 16:04 »
0
Que tal Patitofeo? Gracias por responder.
La verdad que es mi Primer proyecto con MSCOMM y no estoy cachando bien el pseudocodigo que me enviaste. Prodias mostrar ejemplos mas claros?
Gracias :blink:

patitofeo

  • Miembro MUY activo
  • ***
  • Mensajes: 145
    • Ver Perfil
Re: Puerto Serial
« Respuesta #3 en: Viernes 3 de Febrero de 2006, 13:35 »
0
Vale,

A ver si me explico:

La cuestion es que tu lo haces todo dentro de la rutina de atencion.

Esto es el evento OnComm. El programa entra en la rutina cada vez que reciva tantos caracteres como tu le digas. En tu caso 15

Código: Text
  1.  
  2.  .RThreshold = 15
  3.  
  4.  

Depende a que velocidad este trabajando el puerto, esto ocurre cada muy poco tiempo y esposible que antes de que la funcion haya terminado de procesar estos 15 caracteres ya hayan llegado otros 15. De esta forma se van produciendo retrasos y al final pierdes datos.

Lo que tienes que hacer es no procesarlos del tiron. Simplemente guardalos.

Crea un buffer de almacenamiento temporal. Del tipo string si estas trabajando en modo texto.

Algo como por ejemplo:
Código: Text
  1.  
  2. Private BufferComm as String
  3.  
  4.  

Y que la rutina de atencion simplemente valla metiendo ahi los datos

Código: Text
  1.  
  2. Private Sub MSComm1_OnComm()
  3.      BufferComm = BufferComm & MSComm1.Input
  4. End Sub
  5.  
  6.  

Esto lo hara muy rapido

Después habrá otra función que se encargue de procesar estos datos

Código: Text
  1.  
  2. Private Sub ProcesoDatosComm()
  3. Dim datos as string
  4.  
  5. datos = BufferComm
  6. BufferComm=""
  7.  
  8. Call HazLasCuentas   ' Esto sería el procesado como tal. Lo que hagas con los datos
  9.  
  10. End Sub
  11.  
  12.  

Aunque mientras estes haciendo esto te lleguen nuevos datos, no los pierdes porque quedan almacenados en el Buffer que has creado esperando a que vuelvas a llamar al procedimiento ProcesoDatosComm

El cuando tines que llamar a la funcion ProcesoDatosComm depende del programa.

Si los datos no llegan frecuentemente si no que son comandos de control por ejemplo y que siempre acaban con un caracter de fin de trama (esto es un supuesto. Tu tendras que mirar cual es tu caso) puedes añadir algo de codigo en la rutina de atencion que se mantenga esperando a que llegue este caracter

algo como:

Código: Text
  1.  
  2. If instr(BufferComm, caracterControl) <> 0 then Call ProcesoDatosComm
  3.  
  4.  

Si los datos simplemente son rocogidos en un momento dado por otro control (es otro supuesto) entonces en la funcion OnComm activas un flag

Cuando el control quiera los datos mirara el flag. Si esta activado entonces sabra que hay datos en el buffer y puede llamar a la rutina ProcesaDatosComm

En el ejemplo que te puse en el anterior Post te decia que podias comprobar que hubiera datos periodicamente (otro supuesto también distinto. Tu mira cual es tu caso y que se te ocurre que es lo mejor que puedes hacer)

Para hacer esto, añades un control Timer y lo programas con un periodo que tu elijas (cada segundo, cada 200 milisegundos, lo que quieras...)

Si no sabes usar el control Timer, mira la ayuda o en google, es muy facil.

En el evento "Timer" de este control añade una comprobacion.Algo como:

Código: Text
  1.  
  2. Private Sub Timer1_Timer()
  3. If BufferComm <> "" then
  4.        Call ProcesaDatosComm
  5. End If
  6. Timer1.Enable=True
  7. End Sub
  8.  
  9.  

De esta forma, se comprobara el buffer periodicamente pero sin interrumpir la llegada de datos.

Espero que esta vez me hayas entendido y que te haya servido de algo.

Por favor dime si conseguiste resolverlo y si por el contrario aun tienes dudas o problemas no dudes en preguntar ¿vale?

Suerte y un saludo

benegas

  • Nuevo Miembro
  • *
  • Mensajes: 24
    • Ver Perfil
Re: Puerto Serial
« Respuesta #4 en: Miércoles 22 de Febrero de 2006, 21:40 »
0
Buenas Patitofeo. :lol:


Saludos de Paraguay :hola:

patitofeo

  • Miembro MUY activo
  • ***
  • Mensajes: 145
    • Ver Perfil
Re: Puerto Serial
« Respuesta #5 en: Viernes 24 de Febrero de 2006, 17:38 »
0
No es nada.

Me alegro MUCHO de haberte ayudado.   :lol:

Para cualquier cosa ya sabes...