Re: Serial ports in a console application

Tech Tip: Click here to run a free scan for Windows Errors and optimize PC performance

From: William DePalo [MVP VC++] (willd.no.spam_at_mvps.org)
Date: 07/21/04


Date: Wed, 21 Jul 2004 19:52:19 -0400


"Ray Mitchell" <RayMitchell_NOSPAM_@MeanOldTeacher.com> wrote in message
news:3D89558D-4A33-4330-A85C-627B35BE1B8D@microsoft.com...
> I've written Win32 and MFC code to communicate through
> the serial ports using the standard APIs within GUI
> applications and it worked fine.

I love it when this work as doc'd. :-)

> However, I would like to be able to do this from
> within a console-only application too.

OK. What are you having trouble with? Depending on the type of console
application you are writing, you may not care about its responsiveness. It
may be enough to allow the user to terminate with ctrl/c as is still done on
'nix these days. :-)

On the other hand, it may be that simple blocking and synchronous operation
doesn't cut it. In that case you may want to read up on NT's (and
2K/XP/2K+3) asynchronous I/O mechanism. This link introduces the topic about
which there is really quite a lot more to say:

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dllproc/base/synchronization_and_overlapped_input_and_output.asp

The little gawd-awful hack below uses async I/O to post a read and then a
write to the COMM port on which I have a modem on this box. What it writes
is the "Hayes" command "identify" to which which the modem responds by
identifying itself.

<beware>
Conspicuously absent is any reasonable level of error handling. It's just a
quick hack that's good for nothing except a jumpstart.
</beware>

Regards,
Will

#include <windows.h>
#include <stdio.h>

int main(int argc, char **argv)
{
 char szBuffer[80];
 DCB dcb = {0};
 DWORD dwRead, dwWritten;
 HANDLE hComm;
 OVERLAPPED ovlr = {0}, ovlw = {0};
 COMMTIMEOUTS cto;

 // Create events for overlapped operation

 ovlr.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
 ovlw.hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

 // Open the port

 hComm = CreateFile("\\\\.\\COM3", GENERIC_READ | GENERIC_WRITE,
            0, NULL, OPEN_EXISTING,
                 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL);

 // Get the state of the device and modify it

 dcb.DCBlength = sizeof(dcb);
 GetCommState(hComm, &dcb);
 dcb.BaudRate = CBR_9600;
 SetCommState(hComm, &dcb);

 // Set the timeout parameters

 cto.ReadIntervalTimeout = 1000;
 cto.ReadTotalTimeoutConstant = 1000;
 cto.ReadTotalTimeoutMultiplier = 1000;
 cto.WriteTotalTimeoutConstant = 1000;
 cto.WriteTotalTimeoutMultiplier = 1000;

 SetCommTimeouts(hComm, &cto);

 // Send a command and receieve a response. Note that
 // we post the receive in advance of sending the
 // command in order not to miss anything

 printf("\r\nSending: ATI1\r\n");

 ReadFile (hComm, szBuffer, sizeof(szBuffer), &dwRead, &ovlr);
 WriteFile(hComm, "ATI1\r", strlen("ATI1\r"), &dwWritten, &ovlw);

 // Wait for the receive to complete and display the response

 if ( GetOverlappedResult(hComm, &ovlr, &dwRead, TRUE) )
 {
  szBuffer[dwRead] = 0;
  printf("Received: %s\r\n", szBuffer);
 }

 // Close the device

 CloseHandle(hComm);

 return 0;
}


Quantcast