Basically the functions in Main() are what I use to communicate with a medical device via a BlueTooth serial connection.
The Hex2Str() and Str2Hex() functions were put in for my specific needs ... you should be able to remove them.
Everything outside of Main() will be needed and should be placed at the bottom of your code.
Enjoy....
- Code: Select all Expand view
#include "Fwce.ch"
#define BUFF_IN 1024
#define BUFF_OUT 1024
#define GENERIC_READ 0x80000000
#define GENERIC_WRITE 0x40000000
#define GENERIC_REWRITE 0xC0000000
#define OPEN_EXISTING 3
#define FILE_ATTRIBUTE_NORMAL 0x00000080
#define NOPARITY 0
#define ODDPARITY 1
#define EVENPARITY 2
#define MARKPARITY 3
#define SPACEPARITY 4
#define ONESTOPBIT 0
#define ONE5STOPBITS 1
#define TWOSTOPBITS 2
Function Main()
Local cCommPort:=7, hComm, cData, nBytes:=8
//open the comm port
hComm:= OpenCom(nCommPort, 9600,0,8,1, .f. )
//send data to comm port
ComSend( hComm, Hex2Str("027002020803"))
//read data from comm port
cData := STR2HEX(ComRead( hComm,nBytes ))
//Close Comm Port
ComClose( hComm )
Return Nil
////Add the following code to the bottom of your app.
///////////////////////////////////////////////
//
// OpenCom
// Abre el puerto especificado y lo configura
//////////////////////////////////////////////
Function OpenCom( nCom, nBauds, nParity, nDataByt, nStopBits, lIRmode )
LOCAL hComm, cComm
DEFAULT nCom := 1, nBauds := 2400, nParity := NOPARITY, nDataByt := 8, lIRmode := .f.
DEFAULT nStopBits := ONESTOPBIT
cComm := "Com"+ AllTrim( Str( nCom, 2 ) )+ ":"
hComm := CreateFile( cComm, nOr(GENERIC_WRITE, GENERIC_READ) , 0, 0, OPEN_EXISTING, 0,0 )
IF hComm ==-1
Msginfo("Fallo al abrir "+ cComm)
Return -1
ENDIF
IF lIRMode
IF !RAWIRON( hComm )
Msginfo( "Fallo al iniciar RAWIR")
ComClose( hComm )
RETURN -1
ENDIF
ENDIF
IF !SetComm( hComm, nBauds, nParity, nDataByt, nStopBits )
MsgInfo("Fallo al configurar "+ cComm)
ComClose( hComm )
RETURN -1
ENDIF
RETURN hComm
///////////////////////////////////
//
// ComSend( nHdlCom, cString )
//
////////////////////////////////////////////
Function ComSend( hComm, cString )
LOCAL nBytesend, nBytes:= Len( cString )
nByteSend := WriteComm( hComm, @cString, nBytes )
Return ( nByteSend == nBytes )
////////////////////////////////////
//
// ComRead( nHdlCom, nChars )
//
////////////////////////////////////////////
Function ComRead( nHdlCom, nChars )
LOCAL nBytes, cBuffIn := Space(BUFF_IN)
nBytes := ReadComm( nHdlCom, @cBuffIn, nChars )
RETURN if( nBytes >0, Left( cBuffIn, nBytes ),"" )
////////////////////////////////////
//
// ComClose( nHdlCom)
//
////////////////////////////////////////////
FUNCTION ComClose( hComm )
RAWIROFF( hComm )
CloseHandle( hComm )
RETURN .t.
#pragma BEGINDUMP
#include <windows.h>
#include <winbase.h>
#include <hbapi.h>
#include <aygshell.h>
static far BYTE bChar[] = "0123456789ABCDEF";
HB_FUNC( STR2HEX )
{
LONG wHex = 0, w = 0;
LONG wLen = hb_parclen( 1 );
if( wLen > 0 )
{
char * pBuffer = ( char * ) hb_xgrab( wLen );
char * pBufferHex = ( char * ) hb_xgrab( wLen * 2 );
BYTE bByte ;
memcpy( pBuffer, hb_parc( 1 ), wLen );
while( w < wLen )
{
bByte = pBuffer[ w++ ] ;
pBufferHex[ wHex++ ] = bChar[ bByte / 16 ];
pBufferHex[ wHex++ ] = bChar[ bByte % 16 ];
}
hb_retclen( pBufferHex, wLen * 2 );
hb_xfree( pBuffer );
hb_xfree( pBufferHex );
}
else
hb_retclen( "", 0 );
}
HB_FUNC( HEX2STR )
{
LONG wHex = 0, w = 0;
LONG wLen = hb_parclen( 1 );
if( wLen > 0 )
{
char * pBuffer = ( char * ) hb_xgrab( wLen );
char * pBufferStr = ( char * ) hb_xgrab( wLen / 2 );
BYTE b1 ;
BYTE b2 ;
memcpy( pBuffer, hb_parc( 1 ), wLen );
while( w < wLen )
{
b1 = pBuffer[ w++ ] ;
if( b1 < 65 )
b1 = b1 - 48; // number 0..9
else
if( b1 > 96 )
b1 = b1 - 87; // lower case lettre a..f
else
b1 = b1 - 55; // capital letter A..F
b2 = pBuffer[ w++ ] ;
if( b2 < 65 )
b2 = b2 - 48; // number 0..9
else
if( b2 > 96 )
b2 = b2 - 87; // lower case lettre a..f
else
b2 = b2 - 55; // capital letter A..F
pBufferStr[ wHex++ ] = b1 * 16 + b2 ;
}
hb_retclen( pBufferStr, wLen / 2 );
hb_xfree( pBuffer );
hb_xfree( pBufferStr );
}
else
hb_retclen( "", 0 );
}
static LONG power( LONG nBase, LONG nPower )
{
LONG n = 0, nResult = 1;
while( n++ < nPower )
nResult *= nBase;
return nResult;
}
HB_FUNC( HEXTODEC ) // ( cHexNumber ) --> nDecNumber
{
char * pString = hb_parc( 1 );
LONG w = 0, wLen = hb_parclen( 1 );
BYTE bChar;
LONG nHex = 0;
while( w < wLen )
{
bChar = pString[ w ] ;
if ( bChar >= 97 ) bChar -= 39; // lowercase
if ( bChar >= 65 ) bChar -= 7 ; // uppercase
bChar -= 48;
nHex += bChar * power( 16, wLen - w - 1 );
w++;
}
hb_retnl( nHex );
}
HB_FUNC( SETCOMM )
{
DCB dcb;
COMMTIMEOUTS timeouts;
SetupComm(( HANDLE) hb_parnl( 1 ), 1024, 1024 ) ;
GetCommState( ( HANDLE ) hb_parnl( 1 ), &dcb );
dcb.BaudRate = hb_parnl( 2 );
dcb.Parity = hb_parni( 3 );
dcb.ByteSize = hb_parni( 4 );
dcb.StopBits = hb_parni( 5 );
dcb.fBinary = TRUE;
dcb.fParity = TRUE;
dcb.fOutxCtsFlow = FALSE;
dcb.fOutxDsrFlow = FALSE;
dcb.fDtrControl = DTR_CONTROL_DISABLE;
dcb.fDsrSensitivity = FALSE;
dcb.fTXContinueOnXoff = FALSE;
dcb.fOutX = FALSE;
dcb.fInX = FALSE;
dcb.fErrorChar = FALSE;
dcb.fNull = FALSE;
dcb.fRtsControl = RTS_CONTROL_DISABLE;
dcb.fAbortOnError = FALSE;
GetCommTimeouts(( HANDLE) hb_parnl, &timeouts);
timeouts.ReadIntervalTimeout = 0;
timeouts.ReadTotalTimeoutMultiplier = 0;
timeouts.ReadTotalTimeoutConstant = 1000;
timeouts.WriteTotalTimeoutMultiplier = 0;
timeouts.WriteTotalTimeoutConstant = 0;
SetCommTimeouts(( HANDLE) hb_parnl( 1 ), &timeouts );
hb_retl(SetCommState( ( HANDLE ) hb_parnl( 1 ), &dcb ));
}
HB_FUNC( READCOMM )
{
DWORD dw = 0;
ReadFile( ( HANDLE ) hb_parnl( 1 ), ( LPVOID ) hb_parc( 2 ), ( DWORD ) hb_parni( 3 ), &dw, NULL );
hb_retni( ( int ) dw ? dw : -1 );
}
HB_FUNC( WRITECOMM )
{
DWORD dw = 0;
WriteFile( (HANDLE ) hb_parnl( 1 ), ( LPVOID ) hb_parc( 2 ), ( DWORD ) hb_parni( 3 ), &dw, NULL );
hb_retni( ( int ) dw ? dw : -1);
}
HB_FUNC( RAWIRON )
{
hb_retl( EscapeCommFunction( ( HANDLE ) hb_parnl( 1 ), SETIR ) );
}
HB_FUNC( RAWIROFF )
{
hb_retl( EscapeCommFunction( ( HANDLE ) hb_parnl( 1 ), CLRIR ) );
}
#pragma ENDDUMP