Page 1 of 1

Read Com port

Posted: Wed Sep 26, 2018 9:45 am
by Jack
Hi,
I have a analytical scale connected to a com port .
I test sample testcom3.prg and it works fine but it return the information in 2 parts, (2 MsgInfo box) .
The total lenght is 18 string .
How to return the total 18 strings from the BytesAtPort function ??

Thanks

#include "FiveWin.ch"

function Main()

local oDlg, nComm := InitComm()

DEFINE DIALOG oDlg TITLE "Testing Comm functions"

oDlg:bCommNotify = { | nComm, nStatus | BytesAtPort( nComm, nStatus ) }

ACTIVATE DIALOG oDlg ;
ON INIT EnableCommNotification( nComm, oDlg:hWnd, 20, 20 )

CloseComm( nComm )

return nil

function InitCOMM()

local cDcb, nError, nBytes
local nComm := OpenComm( "COM1", 1024, 128 )

if ! BuildCommDcb( "COM1:9600,n,8,1", @cDcb )
MsgStop( "Error BUILD!" )
return .f.
endif

#ifdef __CLIPPER__
if ! SetCommState( cDcb )
#else
if ! SetCommState( nComm, cDcb )
#endif
MsgStop( "Error SETCOMM!" )
return .f.
endif

return nComm

function BytesAtPort( nComm, nStatus )

local cBuffer := Space(20 )

Msginfo( nSTATUS)
ReadComm( nComm, @cBuffer ) // <<<<---- program will lock here
Msginfo( AllTrim( cBuffer ))

return nil

Re: Read Com port

Posted: Wed Sep 26, 2018 11:49 am
by dutch
I've got the same problem.
BytesAtPort() is returning 2 times.
1. 1 byte
2. from 2nd byte to the rest.

For your example,
1. 1 byte
2. 17 bytes.

I'm waiting for reply too.

Thanks in advance,

Re: Read Com port

Posted: Fri Sep 28, 2018 5:49 am
by Jack
Hi,
Could we have some help about this ?

What is the right way to read all the info from a COM port .

Thanks

Re: Read Com port

Posted: Fri Sep 28, 2018 11:04 am
by Diego Decandia
In the first post, you say that the example Testcom3 returns two msginfo, and it is just so: first the status, then the text received.

If you don't need the status, delete it.

>> What is the right way to read all the info from a COM port .

It's difficult/simple to answer the question. In fact you read all the info, if on the other side the instrument send you all the info.
If send you a single control character, you need to respond to that control character.

It depends on the interface protocol...

Re: Read Com port

Posted: Fri Sep 28, 2018 11:11 am
by Jack
Hi,
I have delete the MsgInfo for the status .
I have only this :

ReadComm( nComm, @cBuffer ) // <<<<---- program will lock here
Msginfo( AllTrim( cBuffer ))

But it gives me 2 times the MsgInfo , first with a part of the info and the second with the rest .

What can i do to read all in 1 step and then add it to a dbf file .

Thanks

Re: Read Com port

Posted: Fri Sep 28, 2018 1:02 pm
by Diego Decandia
>>ReadComm( nComm, @cBuffer ) // <<<<---- program will lock here
>>Msginfo( AllTrim( cBuffer ))

Excuse me, but I do not understand how from these lines, if you run only once, can result two msginfo...

In any way, what is the total string?

Re: Read Com port

Posted: Sat Sep 29, 2018 2:55 pm
by Jack
I suppose there is a buffer but ???

Any help ?

Thanks

Re: Read Com port

Posted: Sat Sep 29, 2018 3:39 pm
by Diego Decandia
Hi Jack,
I don't use the library you're using, so let's go for trial...

The Readcomm function expects Cbuffer as:
A string variable supplied by reference where ReadComm() will place the read bytes.
The length of the initial supplied value specifies the wished number of bytes to be read.You may use, i.e., Space( ... ) to initialize this buffer.

So, set the buffer exactly to 18 bytes, otherwise the function waits for two more characters.

Also, delete bCommNotify and EnableCommNotify, and enter a button to run BytesAtPort

Test and good luck.

Re: Read Com port

Posted: Tue Oct 02, 2018 6:11 am
by Jack
Hi,
It works with the last suggestion ==> delete : bCommNotify and EnableCommNotify

Thanks for this feed back.

Re: Read Com port

Posted: Tue Oct 02, 2018 9:19 am
by dutch
Hi Jack,

How do you get automatic readcom() function to replace oDlg:bCommNotify ?
Jack wrote:Hi,
It works with the last suggestion ==> delete : bCommNotify and EnableCommNotify

Thanks for this feed back.

Re: Read Com port

Posted: Wed Oct 03, 2018 5:50 am
by Jack
Dutch,
I use a timer .

DEFINE TIMER oTmr INTERVAL 6000 ACTION (BytesAtPort( nComm),oLbx:Refresh()) OF oWnd
ACTIVATE TIMER oTmr


function BytesAtPort( nComm, nStatus )

local cBuffer:=space(18)

ReadComm( nComm, @cBuffer )
select RAWPOIDS
append blank
replace data with cBuffer

return nil

Re: Read Com port

Posted: Wed Oct 03, 2018 7:51 am
by dutch
Dear Jack,

Thanks, but it doesn't fix all case. If there is 2nd process coming during 1st process that doesn't finish.
Jack wrote:Dutch,
I use a timer .

DEFINE TIMER oTmr INTERVAL 6000 ACTION (BytesAtPort( nComm),oLbx:Refresh()) OF oWnd
ACTIVATE TIMER oTmr


function BytesAtPort( nComm, nStatus )

local cBuffer:=space(18)

ReadComm( nComm, @cBuffer )
select RAWPOIDS
append blank
replace data with cBuffer

return nil

Re: Read Com port

Posted: Wed Oct 03, 2018 8:27 am
by Enrico Maria Giordano
This is a working sample of a simple terminal:

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: Read Com port

Posted: Thu Oct 04, 2018 7:10 am
by dutch
Dear EMG,

I will test, thanks a lot.
Enrico Maria Giordano wrote:This is a working sample of a simple terminal:

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