Tech Support > Microsoft Windows > Development Resources > First time opening COM port using CreateFile
First time opening COM port using CreateFile
Posted by pedronf65@gmail.com on January 26th, 2008


Hello all,
When I power up my PC and use my test application, which opens COM1
and reads a string of data (sent by a serial barcode reader), the
first time it just doesn't work.
If I close my application, call HyperTerminal application and open
COM1 (just open it), then close HyperTerminal, open my test
application, it starts working fine.
This looks like HyperTerminal is doing something else then my
application, in order to open the COM port.
I use this line of code:
m_hFile = ::CreateFile(m_csCommPortName, GENERIC_READ | GENERIC_WRITE,
0, 0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED, 0);

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

Posted by Scott McPhillips [MVP] on January 26th, 2008


<pedronf65@gmail.com> wrote in message
news:ee6d39ee-7268-4720-95aa-ab06b8b9f028@q39g2000hsf.googlegroups.com...
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]


Posted by Owen Ransen on January 27th, 2008


On Sat, 26 Jan 2008 14:37:21 -0800 (PST), pedronf65@gmail.com wrote:

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/

Posted by pedronf65@gmail.com on January 27th, 2008


Well in fact I do a little more than that, this is the complete code:

--------------------------------------------------------------------------------------------------------------------------------------------
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?

Posted by Ulrich Eckhardt on January 28th, 2008


pedronf65@gmail.com wrote:
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.

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.

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


Posted by pedronf65@gmail.com on January 28th, 2008


Thank you for all your hints and help!
I'm back from work, didn't have the time to work on this today...
I'll check it out tomorrow and I'll let you know if I manage to solve
my problem.

Posted by pedronf65@gmail.com on January 28th, 2008


Thank you for all your hints and help!
I'm back from work, didn't have the time to work on this today...
I'll check it out tomorrow and I'll let you know if I manage to solve
my problem.

Posted by pedronf65@gmail.com on January 28th, 2008


humm...
I just tryed the "mode com1" with my home computer, one thing got my
attention, the line "Timeout: OFF" changed to "Timeout: ON" and I'm
not changing this configuration in my application so I guess it must
be it...!
I'll try it tomorrow at work.
Many thanks once again for you help!

Posted by pedronf65@gmail.com on January 28th, 2008


humm...
I just tryed the "mode com1" with my home computer, one thing got my
attention, the line "Timeout: OFF" changed to "Timeout: ON" and I'm
not changing this configuration in my application so I guess it must
be it...!
I'll try it tomorrow at work.
Many thanks once again for you help!

Posted by pedronf65@gmail.com on January 28th, 2008


humm...
I just tryed the "mode com1" with my home computer, one thing got my
attention, the line "Timeout: OFF" changed to "Timeout: ON" and I'm
not changing this configuration in my application so I guess it must
be it...!
I'll try it tomorrow at work.
Many thanks once again for you help!


Similar Posts