Page 1 of 1

Clear COM port buffer

Posted: Fri Oct 03, 2014 4:19 pm
by Jeff Barnes
Hi,

Is there any other way to clear the com port buffer?
I have tried:

Code: Select all

if FlushComm( nComm, 0 ) != 0
   nError = GetCommError( nComm )
   MsgInfo( "FlushComm Error: " + Str( nError ) )
endif

if FlushComm( nComm, 1 ) != 0
   nError = GetCommError( nComm )
   MsgInfo( "FlushComm Error: " + Str( nError ) )
endif
 
I do not get any errors but it appears that the buffer is not getting cleared.

What I am doing:
I read (every second) data form a com port and display the info on the screen.

What's happening:
At the start, the data being sent to the com port from my device will match what I see on the pc screen. After a few minutes, the data seen on the device and the pc screen are out of sync. If I change the info being sent on the device it can take up to 30 seconds before the pc screen catches up.

Re: Clear COM port buffer

Posted: Sat Oct 04, 2014 10:56 am
by Antonio Linares
Jeff,

FWH provides CloseComm( nPort ), not sure if you may need to close it and open it again.

Anyhow if you post an example of how you are using it we will be able to provide you a better help,

Re: Clear COM port buffer

Posted: Sat Oct 04, 2014 1:27 pm
by Jeff Barnes
Here is a sample of the code.
lSetOX is set to .T. during the initial connection, then set to .F. after the connection is made.

The code below is called every second via a timer.

Code: Select all

IF lSetOX    //Connect to device
   nComm:= OpenComm("COM"+ALLTRIM(STR(nComPort)), 16,16 )
   Syswait(.01)
   BuildCommDcb( "COM"+alltrim(str(nComPort))+":9600,N,8,1", @cDcb ) 

   IF ! SetCommState(  nComm, cDcb )
      MsgInfo("Error setting COM state","ERROR")
      RETURN .f.
   ENDIF

   IF !ENABLECOMMNOTIFICATION( nComm, oDlgTest:hWnd, 1, -1 )
      MsgInfo("COM Noticication error","NOTICE")
      RETURN .f.
   ENDIF

   IF FlushComm( nComm, 1 ) != 0
      nError = GetCommError( nComm )
      MsgInfo( "Error flushing the COM port: " + Str( nError ) )
   ENDIF    
   lSetOX:=.F.
ENDIF


//Read from device
Memory(-1)
FlushComm( nComm, 1 ) 
FlushComm( nComm, 0 ) 
SysRefresh()
cDataRead:=Space(18)
cString := ""
READCOMM( nComm, @cDataRead) 
cString:=ALLTRIM(cDataRead)
cSat := LEFT( RIGHT(ALLTRIM(cString),12),3)
cHR  := LEFT( Right(ALLTRIM(cString), 5),3)
SysRefresh()
        
 

Re: Clear COM port buffer

Posted: Sat Oct 04, 2014 2:34 pm
by Enrico Maria Giordano
Jeff,

this is a sample of how should you use the communication device:

Code: Select all

#include "Fivewin.ch"


FUNCTION MAIN()

    LOCAL oDlg

    LOCAL oGet, cTxt := ""

    LOCAL nCom

    DEFINE DIALOG oDlg;
           SIZE 500, 500;
           TITLE "Terminale"

    @ 0, 0 GET oGet VAR cTxt MEMO READONLY

    oGet:bKeyDown = { | nKey | Tasti( nCom, nKey ) }

    ACTIVATE DIALOG oDlg;
             ON INIT ( oGet:AdjClient(),;
                       nCom := APRICOM( oDlg, oGet ),;
                       IF( nCom < 0, oDlg:End(), ) );
             CENTER

    IF nCom >= 0; CLOSECOMM( nCom ); ENDIF

    RETURN NIL


STATIC FUNCTION TASTI( nCom, nKey )

    SENDSTR( nCom, CHR( nKey ) )

    RETURN NIL


STATIC FUNCTION APRICOM( oDlg, oGet )

    LOCAL nCom, cDcb

    BEGIN SEQUENCE
        nCom = OPENCOMM( "COM1", 16384, 16384 )

        IF nCom < 0
            ? "Errore di apertura della porta di comunicazione."
            BREAK
        ENDIF

        BUILDCOMMDCB( "COM1:115200,N,8,1", @cDcb )

        IF !SETCOMMSTATE( nCom, cDcb )
            ? "Errore di impostazione della porta di comunicazione."
            BREAK
        ENDIF

        oDlg:bCommNotify = { | nCom | Connect( nCom, oGet ),;
                                      EnableCommNotification( nCom, oDlg:hWnd, 1, -1 ) }

        IF !ENABLECOMMNOTIFICATION( nCom, oDlg:hWnd, 1, -1 )
            ? "Errore di abilitazione della notifica."
            BREAK
        ENDIF
    RECOVER
        nCom = -1
    END SEQUENCE

    RETURN nCom


STATIC FUNCTION CONNECT( nCom, oGet )

    LOCAL cStr

    ENABLECOMMNOTIFICATION( nCom, 0, 1, -1 )

    cStr = RECEIVESTR( nCom )

    cStr = STRTRAN( cStr, CHR( 13 ), "" )
    cStr = STRTRAN( cStr, CHR( 10 ), CRLF )

    oGet:Append( cStr )

    RETURN NIL


STATIC FUNCTION SENDSTR( nCom, cString )

    LOCAL nBytes := WRITECOMM( nCom, cString )

    RETURN nBytes = LEN( cString )


STATIC FUNCTION RECEIVESTR( nCom )

    LOCAL cBuf := SPACE( 1000 )

    RETURN LEFT( cBuf, READCOMM( nCom, @cBuf ) )
EMG

Re: Clear COM port buffer

Posted: Sun Oct 05, 2014 11:51 pm
by Jeff Barnes
Hi Enrico,

I have been playing with your sample and it works perfectly to show the data coming in via your dialog box and get.
The problem I am having is using your example to put the data into a string instead of a get (without the "terminal" dialog box).

When I try without your dialog box and just placing the data into the string (Then I manipulate the string and show the extracted data in 2 gets) I do get the data but every 30 seconds the data appears to shift then goes back to normal.

Ex
cString = the entire data string read at the com port.
When I display cString, the initial reading will show "SPO2=999 HR=999"
After 30 seconds, cString will show as follows every second:
"O2=999 HR=999"
"=999 HR=999"
"99 HR=999"
" HR=999"
"R=999"
"999"
"9"
Then goes back to "SPO2=999 HR=999" for another 30 seconds then repeats.

Do you have an example where I can just collect the data and put into cString ?

Re: Clear COM port buffer

Posted: Mon Oct 06, 2014 8:26 am
by Enrico Maria Giordano
Jeff,

this is how to read a string from the communication port:

Code: Select all

cStr = RECEIVESTR( nCom )
It should work fine. I don't understand your problem, sorry... :-(

Can I see a sample of the code you are using?

EMG

Re: Clear COM port buffer

Posted: Tue Oct 07, 2014 12:36 am
by fafi
Enrico Maria Giordano wrote:Jeff,

this is how to read a string from the communication port:

Code: Select all

cStr = RECEIVESTR( nCom )
It should work fine. I don't understand your problem, sorry... :-(

Can I see a sample of the code you are using?

EMG
add this :

Code: Select all

cStr = RECEIVESTR( nCom )
cStr := upper(alltrim(cStr))
?"Len of string : "+str(len(cStr),12)
if cStr $ "1234567890=QWERTYUIOPASDFGHJKLZXCVBNM"
  ?"this is good string : "+cStr
else
   ?"garbage string : "+cStr
endif

or save the cStr every time to dbf

 
best regards
fafi

Re: Clear COM port buffer

Posted: Wed Oct 08, 2014 12:18 pm
by Jeff Barnes
Got it working ... I had to adjust the buffer size.
Thanks everyone for the help.

Re: Clear COM port buffer

Posted: Wed Oct 15, 2014 2:21 pm
by PeterHarmes
HI,

I have just created a link to a badge reader and have noticed that when I use EnableCommNotification, it only reads in around 8 characters at a time - This is happening in Enricos demo application. Is there a way to read in more characters in one go (10-20)?

Best regards,

Pete

Re: Clear COM port buffer

Posted: Wed Oct 15, 2014 2:26 pm
by Enrico Maria Giordano
Peter,

you should not care of how many characters are read at a time. Just read and store any characters you receive.

EMG