Solved

Com Ports

Posted on 1997-04-21
2
1,516 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

Courses: Start Training Online With Pros, Today

Brush up on the basics or master the advanced techniques required to earn essential industry certifications, with Courses. Enroll in a course and start learning today. Training topics range from Android App Dev to the Xen Virtualization Platform.

Question has a verified solution.

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

Suggested Solutions

Storage devices are generally used to save the data or sometime transfer the data from one computer system to another system. However, sometimes user accidentally erased their important data from the Storage devices. Users have to know how data reco…
Healthcare organizations in the United States must adhere to the guidance of both the HIPAA (Health Insurance Portability and Accountability Act) and HITECH (Health Information Technology for Economic and Clinical Health Act) for securing and protec…
The viewer will learn how to set up a document for the web and print and the recommended PPI for printing.
Using Adobe Premiere Pro, the viewer will learn how to set up a sequence with proper settings, importing pictures, rendering, and exporting the finished product.

813 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

14 Experts available now in Live!

Get 1:1 Help Now