Solved

Com Ports

Posted on 1997-04-21
2
1,515 Views
Last Modified: 2013-12-04
Hi,

I've been using the following code to open and read data from a com port

      h = CreateFile("Com1",
                           GENERIC_READ|GENERIC_WRITE,
                           0,NULL,
                           OPEN_EXISTING,FILE_FLAG_OVERLAPPED,NULL);

      if(h == INVALID_HANDLE_VALUE) {
         PrintError("Failed to open port",ComNumber);
         return;
      }

***** To read from the port

      COMMTIMEOUTS cto = { 2, 1, 1, 0, 0 };
            
      if(!SetCommTimeouts(h,&cto))
            PrintError("SetCommTimeouts failed",ComNumber);


      // create event for overlapped I/O
   osRead.hEvent = CreateEvent(NULL,FALSE,FALSE,NULL);
   if(osRead.hEvent == INVALID_HANDLE_VALUE)
      PrintError("CreateEvent failed", ComNumber);

   // wait for received characters
   if(!SetCommMask(h,EV_RXCHAR | EV_RLSD))
      PrintError("SetCommMask failed", ComNumber);

   Finished=FALSE;
   while( !Finished ) {
      // get the event mask
      if( !WaitCommEvent(h,&mask,&osRead) ) {
         DWORD e = GetLastError();
         if( e == ERROR_IO_PENDING ) {
            DWORD r;
            if( !GetOverlappedResult(h,&osRead,&r,TRUE) ) {
               PrintError("GetOverlappedResult failed",ComNumber);
               break;
            }
         } else {
            PrintError("WaitCommEvent failed", ComNumber);
            break;
         }
      }

      // if no event, then UI thread terminated with SetCommMask(h,0)
      if( mask == 0 ) {
         return ExitThread;
      }

      if( mask & EV_RLSD)
        {
              return CDLost;
        }
        else{
         char buf[10];
         DWORD read;

   

             do {
                  memset(buf,'\0',sizeof(buf));
             read = 0;
            if( !ReadFile(h,buf,sizeof(buf),&read,&osRead) ) {
               if( GetLastError() == ERROR_IO_PENDING ) {
                  if( !GetOverlappedResult(h,&osRead,&read,TRUE) ) {
                     PrintError("GetOverlappedResult failed", ComNumber);
                     break;
                  }
               } else {
                  PrintError("ReadFile failed", ComNumber);
                  break;
               }
            }
            if(read)
                  {
*** We have some data

All works ok.  The routine waits until data is received then reads it in.  If their is a change in CD signal this is also recognised.

The problem I have is I wish the GetOverlappedresult function to return after a set time interval.   Whether there is any data or not.

I have tried the following

      COMMTIMEOUTS cto = { 200, 1, 3000, 0, 0 };


    if(!SetCommTimeouts(h,&cto))
        PrintError("SetCommTimeouts failed",ComNumber);            
        if( !ReadFile(h,buf,MaxCharNumber,&read,&osRead) ) {
                        PrintError("ReadFile failed", ComNumber);
                        return FALSE;
                        break;
                  }

            if (read)
            {
            *** We have data      

Which works as required. I.E if after 3 seconds no data is received ReadFile returns with read=0, if data is received ReadFile returns straight away with the data.

But.  If i call  ReadFile again it returns straight away even when there is no data,  How do I get it to perform as it does the first time i called ReadFile.

Or can I change the first example code so that  GetOverLappedResult returns after a set interval.
      
0
Comment
Question by:Robert888
2 Comments
 
LVL 15

Expert Comment

by:NickRepin
ID: 1334703
Can you post source code with ReadFile and comments for what ReadFile(), GetOverlappedResult(), GetLastError() returns in each case?
0
 
LVL 3

Accepted Solution

by:
Melange earned 100 total points
ID: 1334704
   Instead of immediately calling GetOverlappedResult after WaitCommEvent, wait on your event object with WaitForSingleObject. You can set the timeout period for waiting on the event in milliseconds in the call to WaitForSingleObject.
    Also I would recommend using a manual reset event when doing timeouts. This way if you do timeout, you can still check the status of the event later on without having to worry about missing it.
    Once you get a signalled event (not a timeout), call ResetEvent and then call GetOverlappedResult. Since the operation should now be completed, GetOverlappedResult will now return immediately with the requested info (either success or failure). If you need more info, let me know.
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity
What interoffice LAN only messenger is recommended? 5 71
Web Browsers Start Page Hijacker 14 110
JItbit AD intergration 4 76
Easy to use inventory management software 7 69
A list of useful business intelligence software.
Today, still in the boom of Apple, PC's and products, nearly 50% of the computer users use Windows as graphical operating systems. If you are among those users who love windows, but are grappling to keep the system's hard drive optimized, then you s…
The viewer will learn how to successfully download and install the SARDU utility on Windows 7, without downloading adware.
An overview on how to enroll an hourly employee into the employee database and how to give them access into the clock in terminal.

910 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now