Page 1 of 1

Colectores de datos

PostPosted: Fri Apr 04, 2008 7:17 am
by fgondi
Estimados Srs.

Tengo un cliente con una maquina Zebex PDL-10L con una base CRD-10 Cradle y me ha podido que la ponga en funcionamiento.

El problema es que lo tiene sin ningún tipo de CD y/o manual.

A través de la página de Zebex http://www.zebex.com y su modelo PDL-20 he conseguido ver como poder configurarla para que pida los datos que yo quiera y como volcar los datos a través del menú que aparece en ella.

Sin embargo, no se si existe la posiblidad de forzar a volcar los datos sin necesidad de entrar en su menú, ya que en él aparace toda la configuración de la misma.

He visto, lo que parece una serie de comando para enviar a la pistola, por ejemplo: <SOH><CR><LF>W<EOT> muestra la versión, pero no he conseguido hacerlo funcionar.

¿Alguno conoce el funcionamiento de estas pistolas?
¿Cómo puedo enviar a la pistola esos códigos? y ¿cómo y dónde devuelve la información solicitada?
He probado de la siguiente forma:
Code: Select all  Expand view
nBytes := WriteComm( nComm, chr(1)+chr(13)+chr(10)+"W"+chr(4) )

No da error, nBytes coge un valor correcto y en base veo que se enciende el led RX, por tanto parece que envía la información correctamente, pero ya esta, no hace nada mas.

Gracias por vuestra ayuda

PostPosted: Wed Apr 09, 2008 7:29 am
by fgondi
Hola foro,

Esta claro que nadie a tenido que trabajar con maquinas Zebex. Es una pena.

Lo que creo que si me podíais ayudar es a como funciona el envío de ordenes a los puerto comm y recoger la información devuelta.

Uso las instrucciones de FWH para comunicación con un puerto comm

OpenComm( )
BuildCommDcb( )
SetCommState( )
oWnd:bCommNotify
EnableCommNotification( )

Y funciona correctamente.
Ahora esto tratando de probar
WriteComm()

Lo que no sé, es is la orden que envío con WriteComm fuerza a la maquina a devolver una cadena de caracteres, como puedo recogerla.
¿Debería recogerse automáticamente en bCommNotify?, ¿Hay que forzar de alguna manera el ReadComm?

Espero haberme explicado.

PostPosted: Wed Apr 09, 2008 10:39 am
by cmsoft
Hola Fgondi:
Por la experiencia que tengo en comunicaciones seriales, todo depende del protocolo del aparato al que quieras comunicarte. Por ejemplo

abrirpuerto
mandar_enq
leer_ack
mandardatos
leer_ack
mandardatos
leer_ack
mandar_eot
leer_eot
CerrarPuerto

Esta secuencia es un ejemplo para comunicarse con una registradora NCR 2050.

Espero que te sirva de algo esta info

PostPosted: Wed Apr 09, 2008 4:26 pm
by fgondi
Hola,

Muchas gracias cmsoft por tu respuesta. Por lo que leo de este tipo máquinas, usa ese mismo protocolo.

Lo que no se es como introduccirlo con código xHarbour/FWH

Code: Select all  Expand view
AbrirPuerto
Lo OpenComm, BuildCommDcb, etc. para la apertura y escucha del puerto

Code: Select all  Expand view
mandar_enq

Me imagino que sea WriteComm( nComm, chr(5)+CRLF )

Code: Select all  Expand view
leer_ack
Esto es lo que no se como hacer

Code: Select all  Expand view
mandardatos
Otra vez WriteComm con los datos/códigos a mandar

Code: Select all  Expand view
leer_ack
Esto es lo que no se como hacer

Code: Select all  Expand view
mandar_eot
WriteComm( nComm, chr(4)+CRLF )

¿Serias tan amable de ayudarme con el código que me falta?

PostPosted: Mon Apr 14, 2008 8:21 am
by fgondi
Hola foro,

Nadie puede ayudarme?

Gracias por vuestro tiempo

PostPosted: Mon Apr 14, 2008 8:43 am
by Antonio Linares
Fernando,

fwh\samples\TestComm.prg sirve cuando es una comunicación rápida. Se envian datos y se lee una respuesta inmediata.

fwh\samples\phone.com es cuando la comunicación no es inmediata, sino que hay demoras y entonces hay que usar eventos.

PostPosted: Mon Apr 14, 2008 1:10 pm
by cmsoft
Disculpá la tardanza:
Aca te pongo el código que yo utilizo:
Code: Select all  Expand view
FUNCTION crearbcc(p1)
LOCAL bcc,i
bcc = CHR(0)
FOR i = 1 TO LEN(p1)
    bcc := charxor(bcc,SUBSTR(p1,i,1))
NEXT
RETURN bcc

FUNCTION abrirport(n)
LOCAL IdPort,cDcb,nError
IdPort := OpenComm("COM"+STR(n,1),1024,256)
IF IdPort <= 0
   nError = GetCommError( IdPort)
   MsgInfo( "Error al abrir: " + Str( nError ) )
   ELSE
   MsgRun("Puerto abierto como " + STR(IdPort))
ENDIF
IF ! BuildCommDcb("COM"+STR(n,1)+":9600,n,8,1" , @cDcb)
   nError = GetCommError( IdPort)
   MsgInfo( "Error al Configurar: " + Str( nError ) )
   RETURN 0
   ELSE
   MsgRun("Puerto Configurado")
ENDIF
IF ! SetCommState( IdPort, cDcb )
   nError = GetCommError( IdPort)
   MsgInfo( "Error al setear: " + Str( nError ) )
   RETURN 0
   ELSE
   MsgRun("Puerto Seteado")
ENDIF
RETURN IdPort

PROCEDURE mandar(port,string)
LOCAL nBytes
IF (nBytes := WriteComm( port,string) ) < 0
   MsgAlert("Mando mal string")
ENDIF
RETURN

FUNCTION leer_ack(port)
LOCAL fallo, ack := " ", nBytes,i := 1
fallo = .t.
DO WHILE .t.
   MsgWait("Leyendo Ack ","Espere",.15)
   nBytes := ReadComm( port,@ack)
   i++
   IF i > 20 .or. ack <> " "
      EXIT
   ENDIF
ENDDO
IF ack <> ""
   fallo = .f.
   MsgInfo(asc(ack),memvar->musuanom)
ENDIF
RETURN fallo

FUNCTION  leer_enq(port)
LOCAL fallo,enq:=" ",nBytes,i := 1
fallo = .t.
DO WHILE .t.
   MsgWait("Leyendo Enq","Espere",.3)
   nBytes := ReadComm( port,@enq)
   i++
   IF i > 20 .or. enq <> " "
      EXIT
   ENDIF
ENDDO
IF enq <> ""
   fallo = .f.
   MsgInfo(asc(enq),memvar->musuanom)
ENDIF
RETURN fallo

FUNCTION  leer_eot(port)
LOCAL fallo,eot := " " ,nBytes,i := 1
fallo = .t.
DO WHILE .t.
   MsgWait("Leyendo EoT","Espere",.3)
   nBytes := ReadComm( port,@eot)
   i++
   IF eot = CHR(6)
      MsgWait("Esperando por EoT","Espere",5)
      LOOP
   ENDIF
   IF i > 20 .or. eot <> " "
      EXIT
   ENDIF
ENDDO
IF eot <> ""
   fallo = .f.
   MsgInfo(asc(eot),memvar->musuanom)
ENDIF
RETURN fallo

PROCEDURE mandar_eot(port)
LOCAL nBytes
*IF ( nBytes := WriteComm( port, "" )) <= 0
IF ( nBytes := WriteComm( port, CHR(4) )) <= 0
   MsgAlert("Mando mal EOT")
ENDIF
RETURN

FUNCTION mandar_enq(port)
LOCAL mcont,retorno,nBytes
retorno = .t.
FOR mcont := 1 TO 10
*   IF ( nBytes := WriteComm( port, "" )) <= 0
    IF ( nBytes := WriteComm( port, CHR(5))) <= 0
       MsgAlert("Mando mal ENQ")
       retorno := .f.
       ELSE
       retorno := .t.
       EXIT
    ENDIF
    MsgWait("Enviando datos...","Aguarde",1)
NEXT
RETURN retorno

PROCEDURE mandar_ack(port)
LOCAL nBytes
*IF ( nBytes := WriteComm( port, "" )) <= 0
IF ( nBytes := WriteComm( port, CHR(6))) <= 0
   MsgAlert("Mando mal ACK")
ENDIF
RETURN

FUNCTION  leer_bloque(port,n)
LOCAL bloque:= SPACE(n),bcc1,nBytes,i:=1
DO WHILE .t.
   *MsgWait(bloque,"Espere",.2)
   nBytes := ReadComm( port,@bloque)
   i++
   IF EMPTY(bloque)
      MsgWait("Esperando ENQ","Espere",3)
      mandar_enq(port)
      LOOP
   ENDIF
   *bloque := IF(EMPTY(bloque),"",bloque)
   IF i > 20 .or. bloque <> SPACE(n)
      EXIT
   ENDIF
ENDDO
bcc1 = crearbcc(SUBSTR(bloque,2,LEN(bloque)-2))
IF RIGHT(bloque,1) <> bcc1 .and. !(""$bloque)
   *MsgAlert(OemtoAnsi(bloque),STR(ASC(bcc1))+" <> "+STR(ASC(RIGHT(bloque,1))))
   MEMVAR->falla = .t.
ENDIF
RETURN bloque


PostPosted: Mon Apr 14, 2008 5:32 pm
by fgondi
Hola cmsoft,

Muchisimas gracias por tu respuesta.

Ahora entiendo como puedo obtener respuesta del aparato a las ordenes que le envío.

Con esto ya puedo probar el protocolo propio, que es practicamente identico al que usas, de la colectora de datos para hacerla funcionar de la forma deseada.

Antonio, gracias también por tu respuesta. Ya había visto los ejemplos pero lo que no entendía era como hacer el readcom de forma correcta.
Por cierto, y aunque no venga al caso, muy buena la evolución de la clase xbrowse. Con la evolución que lleva me ha hecho tomar la decisión de cambiar mis browse a dicha clase.