PROBLEMAS CON COMUNICACION SERIE
PROBLEMAS CON COMUNICACION SERIE
Buenos dias, perdonarme pero soy practicamente nuevo en esto y me he encontrado con programamcion en fivewin que no conocia, mi problema es con la lectura del puerto serie, intento conectarme con una bascula y leer el peso que me envia pero en la informacion que recibo aparecen caracteres extraños y no recibo el peso correcto, a traves del hiperterminal recibo el peso con la misma trama siempre (una cara, tres espacios en blanco, el peso y un corazon), pero a mi en la aplicacion me llega otra cosa diferente (&wq78Ç), algunos valores del peso pero otros no llegan y caracteres extraños.
FUNCTION CapPes_Des(aAlias,aVars)
LOCAL cCad
cCad := ""
// abre puerto
IF !AbrePu_Des()
RETURN (NIL)
ENDIF
f_info("Ahora ponga el articulo en la bascula")
DO WHILE EMPTY(cCad)
// lee puerto
oCom1:ReadPort(5000)
// descarga el buffer
cCad:= StrCad_Des(oCom1:cBuffer)
ENDDO
// cierra puerto
oCom1:ClosePort()
// destruye objeto
DeleteObject(oCom1)
RETURN (.F.)
FUNCTION StrCad_Des (cCad)
LOCAL cStr,nCt
// inicia variables
cStr := ""
IF EMPTY(cCad)
RETURN ("")
ENDIF
FOR nCt := 1 TO LEN(cCad)
IF SUBSTR(cCad,nCt,1) $ "0123456789"
cStr += SUBSTR(cCad,nCt,1)
ENDIF
NEXT
RETURN (cStr)
FUNCTION AbrePu_Des (aAlias)
LOCAL cConf1,nConf2,cConf3,nConf4,nConf5,nConf6
// abre puertos serie para el scanner
cConf1 := "COM4"
nConf2 := 9600
cConf3 := "n"
nConf4 := 8
nConf5 := 1
nConf6 := 0.1
oCom1 := TRS232():New(cConf1,,,nConf2,cConf3,nConf4,nConf5,nConf6)
// control error
IF oCom1:nError <> 0
F_Stop("ERROR al abrir puerto.Maniobra abortada.")
RETURN (.F.)
ENDIF
F_INFO("PUERTO ABIERTO")
RETURN (.T.)
LA CLASE QUE UTULIZO ES
#INCLUDE "FIVEWIN.CH"
CLASS TRS232
// variables de instancia
DATA cCom // identificacion puerto
DATA nCom // numero identificacion puerto.
DATA cDcb // guarda la configuracion del puerto para lecturas
DATA cBuffer // buffer del puerto.
DATA nError // numero de error provocado.
DATA nDelay // tiempo de retardo de emisor.
// metodos
METHOD New() CONSTRUCTOR // metodo constructor
METHOD ClosePort() // cierra el puerto
METHOD WritePort() // escribir en el puerto
METHOD ReadPort() // leer puerto
METHOD Error() // control de errores
ENDCLASS
****************************************************************************
* *
* CONSTRUCTOR *
* *
****************************************************************************
METHOD New (cCom,nInBytes,nOutBytes,nBaud,cParity,nData,nStop,nDelay) CLASS TRS232
LOCAL cDcb,cError
// inicializa parametros por defecto
DEFAULT nInBytes := 1024
DEFAULT nOutBytes := 128
DEFAULT nDelay := 0
// inicializa variables de instancia
::cCom := cCom
::nError := 0
::nDelay := nDelay
// abrir el puerto
::nCom := OpenComm(::cCom,nInBytes,nOutBytes)
// control de error al abrir el puerto
IF ::nCom < 0
: :Error(1)
RETURN (SELF)
ENDIF
// configurar parametros del puerto
IF !BuildCommDcb(::cCom+":"+STR(nBaud)+","+cParity+","+STR(nData)+","+STR(nStop),@cDcb)
::Error(2)
::ClosePort()
RETURN (SELF)
ENDIF
// comprobar estado del puerto
IF !SetCommState(cDcb)
::Error(3)
::ClosePort()
ENDIF
// guarda la configuracion enviada por BuidCommDcb
::cDcb := cDcb
RETURN (SELF)
****************************************************************************
* *
* LEER EN EL PUERTO *
* *
****************************************************************************
METHOD ReadPort (nTime) CLASS TRS232
LOCAL cBuffer,lSalir,oTimer
// inicializa parametros por defecto
DEFAULT nTime := 0 // tiempo en milisegundos intentando leer
// inicializa variables
lSalir := .F.
// objeto TIMER (temporizador para una lectura finita (0=ilimitado))
IF nTime > 0
oTimer := TTimer():New(nTime,{|| lSalir:=.T. })
oTimer:Activate()
ENDIF
// proceso
DO WHILE !lSalir
* leer el puerto
cBuffer := ::cDcb
IF ReadComm(::nCom,@cBuffer) > 0
::cBuffer := cBuffer
lSalir := .T.
ENDIF
* tiempo de espera antes de vaciar el buffer
SysWait(::nDelay)
* vacia el buffer
IF FlushComm(::nCom,0) <> 0
::Error(6)
RETURN (.F.)
ENDIF
* refresca sistema
SysRefresh()
ENDDO
// destruye el temporizador
IIF(nTime>0,oTimer:Deactivate(),)
RETURN (NIL)
FUNCTION CapPes_Des(aAlias,aVars)
LOCAL cCad
cCad := ""
// abre puerto
IF !AbrePu_Des()
RETURN (NIL)
ENDIF
f_info("Ahora ponga el articulo en la bascula")
DO WHILE EMPTY(cCad)
// lee puerto
oCom1:ReadPort(5000)
// descarga el buffer
cCad:= StrCad_Des(oCom1:cBuffer)
ENDDO
// cierra puerto
oCom1:ClosePort()
// destruye objeto
DeleteObject(oCom1)
RETURN (.F.)
FUNCTION StrCad_Des (cCad)
LOCAL cStr,nCt
// inicia variables
cStr := ""
IF EMPTY(cCad)
RETURN ("")
ENDIF
FOR nCt := 1 TO LEN(cCad)
IF SUBSTR(cCad,nCt,1) $ "0123456789"
cStr += SUBSTR(cCad,nCt,1)
ENDIF
NEXT
RETURN (cStr)
FUNCTION AbrePu_Des (aAlias)
LOCAL cConf1,nConf2,cConf3,nConf4,nConf5,nConf6
// abre puertos serie para el scanner
cConf1 := "COM4"
nConf2 := 9600
cConf3 := "n"
nConf4 := 8
nConf5 := 1
nConf6 := 0.1
oCom1 := TRS232():New(cConf1,,,nConf2,cConf3,nConf4,nConf5,nConf6)
// control error
IF oCom1:nError <> 0
F_Stop("ERROR al abrir puerto.Maniobra abortada.")
RETURN (.F.)
ENDIF
F_INFO("PUERTO ABIERTO")
RETURN (.T.)
LA CLASE QUE UTULIZO ES
#INCLUDE "FIVEWIN.CH"
CLASS TRS232
// variables de instancia
DATA cCom // identificacion puerto
DATA nCom // numero identificacion puerto.
DATA cDcb // guarda la configuracion del puerto para lecturas
DATA cBuffer // buffer del puerto.
DATA nError // numero de error provocado.
DATA nDelay // tiempo de retardo de emisor.
// metodos
METHOD New() CONSTRUCTOR // metodo constructor
METHOD ClosePort() // cierra el puerto
METHOD WritePort() // escribir en el puerto
METHOD ReadPort() // leer puerto
METHOD Error() // control de errores
ENDCLASS
****************************************************************************
* *
* CONSTRUCTOR *
* *
****************************************************************************
METHOD New (cCom,nInBytes,nOutBytes,nBaud,cParity,nData,nStop,nDelay) CLASS TRS232
LOCAL cDcb,cError
// inicializa parametros por defecto
DEFAULT nInBytes := 1024
DEFAULT nOutBytes := 128
DEFAULT nDelay := 0
// inicializa variables de instancia
::cCom := cCom
::nError := 0
::nDelay := nDelay
// abrir el puerto
::nCom := OpenComm(::cCom,nInBytes,nOutBytes)
// control de error al abrir el puerto
IF ::nCom < 0
: :Error(1)
RETURN (SELF)
ENDIF
// configurar parametros del puerto
IF !BuildCommDcb(::cCom+":"+STR(nBaud)+","+cParity+","+STR(nData)+","+STR(nStop),@cDcb)
::Error(2)
::ClosePort()
RETURN (SELF)
ENDIF
// comprobar estado del puerto
IF !SetCommState(cDcb)
::Error(3)
::ClosePort()
ENDIF
// guarda la configuracion enviada por BuidCommDcb
::cDcb := cDcb
RETURN (SELF)
****************************************************************************
* *
* LEER EN EL PUERTO *
* *
****************************************************************************
METHOD ReadPort (nTime) CLASS TRS232
LOCAL cBuffer,lSalir,oTimer
// inicializa parametros por defecto
DEFAULT nTime := 0 // tiempo en milisegundos intentando leer
// inicializa variables
lSalir := .F.
// objeto TIMER (temporizador para una lectura finita (0=ilimitado))
IF nTime > 0
oTimer := TTimer():New(nTime,{|| lSalir:=.T. })
oTimer:Activate()
ENDIF
// proceso
DO WHILE !lSalir
* leer el puerto
cBuffer := ::cDcb
IF ReadComm(::nCom,@cBuffer) > 0
::cBuffer := cBuffer
lSalir := .T.
ENDIF
* tiempo de espera antes de vaciar el buffer
SysWait(::nDelay)
* vacia el buffer
IF FlushComm(::nCom,0) <> 0
::Error(6)
RETURN (.F.)
ENDIF
* refresca sistema
SysRefresh()
ENDDO
// destruye el temporizador
IIF(nTime>0,oTimer:Deactivate(),)
RETURN (NIL)
- Antonio Linares
- Site Admin
- Posts: 37481
- Joined: Thu Oct 06, 2005 5:47 pm
- Location: Spain
- Contact:
Re: PROBLEMAS CON COMUNICACION SERIE
Prueba a cambiar estas líneas:
Code: Select all
DO WHILE EMPTY(cCad)
// lee puerto
oCom1:ReadPort(5000)
// descarga el buffer
cCad := oCom1:cBuffer
ENDDO
MsgInfo( Len( cCad ) )
Re: PROBLEMAS CON COMUNICACION SERIE
Gracias Antonio, por responder, pero sigo teniendo el mismo problema, con este cambio me devuelve la longitud de la cadena donde descarge el buffer (25), pero la informacion que captura sigue siendo erronea, con caracteres extraños y alguna vez algun digito del peso, pero no el peso correcto, la bascula esta conectada a un visor, y este lo tengo conectado por puerto serie al equipo, el visor transmite automaticamente cuando se estabiliza el peso (asi lo tengo comprobado con el hiperterminal, al que me llegua siempre la misma secuencia con cada pesada,un caracter con una cara, el signo mas, espacio en blanco,el peso, y un corazon ), pero al intentar capturar esto desde la plicacion me devuelve caracteres extraños.
Re: PROBLEMAS CON COMUNICACION SERIE
la comunicacion existe y quizas sea en la forma en la que se traduce la informacion leida donde falla, si por le mismo sistema conecto un lector de codigos de barras en vez de la bascula, la informacion se captura correctamente, es decir me muestra _ del codigo en pastalla sin ningun error ni caracter extraño
- Antonio Linares
- Site Admin
- Posts: 37481
- Joined: Thu Oct 06, 2005 5:47 pm
- Location: Spain
- Contact:
Re: PROBLEMAS CON COMUNICACION SERIE
Lo que queria que comprobases es si la longitud que lee es la misma que por el hyperterminal
Esa clase para uso del RS232 sabes si está probada y funciona bien ?
Esa clase para uso del RS232 sabes si está probada y funciona bien ?
Re: PROBLEMAS CON COMUNICACION SERIE
si conecto un scanner al puerto serie y leo un codigo de barras con la misma alpicacion me devuelve la lectura corretamente del codigo, es al interpretar _ especiales donde creo que tiene problenmas
- Antonio Linares
- Site Admin
- Posts: 37481
- Joined: Thu Oct 06, 2005 5:47 pm
- Location: Spain
- Contact:
Re: PROBLEMAS CON COMUNICACION SERIE
Analiza cada caracter de los que te devuelve usando:
for n = 1 to Len( cDatos )
MsgInfo( Asc( SubStr( cDatos, n, 1 ) ) )
next
y comprueba si se asemeja a lo que debes recibir. No te guies de que salga un determinado dibujo (puede variar segun el font usado, etc). Comprueba el valor Ascii usando Asc() de cada caracter
for n = 1 to Len( cDatos )
MsgInfo( Asc( SubStr( cDatos, n, 1 ) ) )
next
y comprueba si se asemeja a lo que debes recibir. No te guies de que salga un determinado dibujo (puede variar segun el font usado, etc). Comprueba el valor Ascii usando Asc() de cada caracter
Re: PROBLEMAS CON COMUNICACION SERIE
Buenos dias Antonio, al desgranar la cadena que me devuelve la lectura del puerto serie caracter a caracer y obteniendo el valor ASCII de cada uno obtengo que: (si en la bascula marca un peso de 6.48) entre los 25 caracteres devueltos estan el 4 y el 8 pero lo demas son espacios en blanco o caracteres extraños, no se que puede estar pasando ya que la bascula envia bien los datos porque el hyperterminal si recibe el peso completo, es a traves de la aplicacion donde parece que hay problemas, no captura _ correctamente, ¿puedo capturar los datos de otra forma que no sea con READCOMM? puede estar el problema al capturar esta funcion _ del buffer y no los interprete bien?
- Antonio Linares
- Site Admin
- Posts: 37481
- Joined: Thu Oct 06, 2005 5:47 pm
- Location: Spain
- Contact:
Re: PROBLEMAS CON COMUNICACION SERIE
Con que valores configuras el hyperterminal para acceder a la báscula ?
Re: PROBLEMAS CON COMUNICACION SERIE
Ya encontre el problema Antonio, la bascula tiene mas de 15 años, antes el código ASCII utilizaba 7 bits para representar _, aunque inicialmente empleaba un bit adicional (bit de paridad) que se usaba para detectar errores en la transmisión. he probado a modificar el parametro bits de datos de 8 a 7 y ahora si me devuelve lo mismo que en el hyperterminal, antes con 8 bits de datos en hyperterminal funcionaba correctamente pero desde la aplicacion no capturaba los valores correctos, con 7 bits de datos funciona en ambos, aunque en el hyper necesita paridad impar y en la aplicacion no es necesario.
Muchisimas gracias por tu ayuda y tu tiempo me fue muy util.
Muchisimas gracias por tu ayuda y tu tiempo me fue muy util.
- Antonio Linares
- Site Admin
- Posts: 37481
- Joined: Thu Oct 06, 2005 5:47 pm
- Location: Spain
- Contact: