I don't have any error, but the application simply can't receive
anything from the COM port.
Someone has any ideas on where might be the problem?
Thanks in advance,
Pedro
There is no such thing as "just open it." HyperTerminal is also setting the
port's baud rate, number of data bits, parity mode, and perhaps flow
control. You have to set all of these things so the port matches the
settings being used by the barcode reader. At a minimum, after you open the
port do this:
DCD dcb;
dcb.DCBlength = sizeof(DCB);
GetCommState(m_hFile, &dcb);
dcb.BaudRate = ...
dcb.ByteSize = ...
dcb.Parity = ...
SetCommState(m_hFile, &dcb);
If these three parameters don't match the external device it can't work. In
simple cases the other DCB settings don't matter. You will probably also
need to call SetCommTimeouts to get ReadFile to return to you in a
reasonable period of time if there is no more input arriving.
--
Scott McPhillips [VC++ MVP]
>I use this line of code:
>m_hFile = ::CreateFile(m_csCommPortName, GENERIC_READ | GENERIC_WRITE,
>0, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
It is a long times since I used this code, but you might
find something useful in it (especially the TRACE statements
after GetCommState() :
char gszPort [_MAX_PATH+1] = "COM2" ;
HANDLE hComm;
hComm = CreateFile( gszPort,
GENERIC_READ | GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
0,// FILE_FLAG_OVERLAPPED,
0);
if (hComm == INVALID_HANDLE_VALUE) {
TRACE ("Could not open com2\n") ;
return (TRUE) ;
}
DCB Dcb ;
if (GetCommState (hComm,&Dcb)) {
TRACE ("Comm state got:\n") ;
TRACE ("Rate = %d\n",Dcb.BaudRate) ;
TRACE ("Binary = %d\n",Dcb.fBinary ) ;
} else {
TRACE ("Could not get com state") ;
return (TRUE) ;
}
unsigned long iNumBytesRead ;
char szMsgIn [_MAX_PATH+1] ;
do {
ReadFile (hComm,szMsgIn,1,&iNumBytesRead,NULL) ;
TRACE ("%c",szMsgIn[0]) ;
} while (szMsgIn[0] != '\n') ;
CloseHandle (hComm) ;
...
Easy to use graphics effects:
http://www.ransen.com/
--------------------------------------------------------------------------------------------------------------------------------------------
if (m_hFile == 0)
{
//
// Initialize the overlapped structures
//
// Read event
InitOverlapped(m_overlappedRead);
// Write event
InitOverlapped(m_overlappedWrite);
//
// Open COM port
//
m_hFile = ::CreateFile(m_csCommPortName, GENERIC_READ |
GENERIC_WRITE, 0, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);
if (m_hFile == INVALID_HANDLE_VALUE)
{
CString csLastError = LogLastError(_T("Error opening COM port!"));
p_errCode.Set(ERRMSG_ERROR_OPENING_COM_PORT, CErrCode::high,
CErrCode::nonRecoverable, csLastError);
return false;
}
//
// Configure COM port with current object attributes
//
BOOL bRet = FALSE;
DCB dcb;
bRet = ::GetCommState(m_hFile, &dcb);
ASSERT(bRet == TRUE);
// Set the new data
dcb.BaudRate = m_wBaudRate;
dcb.ByteSize = m_ucByteSize;
dcb.Parity = m_ucParity;
dcb.StopBits = m_ucStopBits;
dcb.fDtrControl = 0;
dcb.fRtsControl = 0;
// Determine if parity is used
dcb.fParity = (dcb.Parity != NOPARITY);
// Set the new DCB structure
bRet = ::SetCommState(m_hFile, &dcb);
ASSERT(bRet == TRUE);
--------------------------------------------------------------------------------------------------------------------------------------------
I noticed that in one of the replies there were:
dcb.DCBlength = sizeof(DCB);
that I'm not doing... do I need this when I make a GetCommState() ?
Can it be the cause of my problems?
Just one suggestion here: just throw an exception instea of doing all the
logging here and then only returning 'false' which doesn't give any hint
what actually went wrong.
> bRet = ::GetCommState(m_hFile, &dcb);
> ASSERT(bRet == TRUE);
[...]
> bRet = ::SetCommState(m_hFile, &dcb);
> ASSERT(bRet == TRUE);
Two things here:
1. Have you ever compared the settings after starting the computer with the
settings after starting hyperterm? Hint: type "mode com1" in a commandline
shell.
2. I personally wouldn't say that failure of GetCommState() is a
programmer's error, so I'd say that assertions are wrong here. Rather, just
throw an exception. ;)
> I noticed that in one of the replies there were:
> dcb.DCBlength = sizeof(DCB);
> that I'm not doing... do I need this when I make a GetCommState() ?
Yes, absolutely. This structure has been changed throughout the life of the
win32 API (or has been prepared to allow such changes). In order to remain
compatible, they only added fields and the implementation can detect
the 'version' from the size. This applies to all similar structures, too.
Uli
--
Sator Laser GmbH
Geschäftsführer: Michael Wöhrmann, Amtsgericht Hamburg HR B62 932