×
INTELLIGENT WORK FORUMS
FOR COMPUTER PROFESSIONALS

Log In

Come Join Us!

Are you a
Computer / IT professional?
Join Tek-Tips Forums!
  • Talk With Other Members
  • Be Notified Of Responses
    To Your Posts
  • Keyword Search
  • One-Click Access To Your
    Favorite Forums
  • Automated Signatures
    On Your Posts
  • Best Of All, It's Free!
  • Students Click Here

*Tek-Tips's functionality depends on members receiving e-mail. By joining you are opting in to receive e-mail.

Posting Guidelines

Promoting, selling, recruiting, coursework and thesis posting is forbidden.

Students Click Here

Jobs

Problem reading from the serial port.

Problem reading from the serial port.

Problem reading from the serial port.

(OP)
I'm having a problem reading from the comm port.  It is Com3:.  When trying to read from the serial port the WaitForSingleObject() times out.  Any ideas?

Here is my code snipet.

CODE


HANDLE hCAN;
char CAN_Port[64];
DCB dcb;
OVERLAPPED olwrite  = { 0 },
       olread   = { 0 },
           olstatus = { 0 };

DWORD byteswritten, bytesread;
bool fDone = false;
bool readingInput = false;          // Read operation in process
bool fSuccess = false;
char rcvData[512], buf[512];

SecureZeroMemory(CAN_Port, sizeof(CAN_Port));
sprintf_s(CAN_Port, sizeof(CAN_Port), "COM%s:", eol->CAN_CommPort);

hCAN = CreateFile(CAN_Port,
                  GENERIC_READ | GENERIC_WRITE,  
                  0, NULL, OPEN_EXISTING,
                  FILE_FLAG_OVERLAPPED,
                  NULL);

if (hCAN == INVALID_HANDLE_VALUE)
{
    // return with error
    strcat_s(m_print_fail_msg, sizeof(m_print_fail_msg), "\nFailed to open comm port to CAN");
    return TEST_FAIL;
}


// Set up comm port buffers
SetupComm(hCAN, 256, 256);

// Modify DCB and send.
GetCommState(hCAN, &dcb);

// Set the baud rate, dtr = 0, rts = 0, xonxoff = 0, rtscts = 0, dtrdsr = 0,
//   parity = none, databits = 8, stopbits = 1.
dcb.BaudRate = CBR_57600;       // Baud rate for the CAN converter
dcb.ByteSize = 8;              // 8 bits / char
dcb.StopBits = ONESTOPBIT;     // One stop bit
dcb.DCBlength = sizeof(DCB);   // Need to set this
dcb.fBinary = true;            // This must be true; Microsoft does not support non-binary mode transfers
dcb.fOutX = false;             // XON/XOFF disabled for transmit
dcb.fInX = false;              // XON/XOFF disabled for receive
dcb.fOutxCtsFlow = false;      // CTS disabled
dcb.fOutxDsrFlow = false;      // DSR disabled
dcb.fParity = false;           // No parity
dcb.fDsrSensitivity = false;   // DSR disabled
dcb.fDtrControl = DTR_CONTROL_ENABLE;  // Enables DTR line when opened, and stays on
dcb.fRtsControl = RTS_CONTROL_ENABLE;  // Enables RTS line when opened, and stays on
dcb.fInX = false;              // Disable receive XON/XOFF control
dcb.fOutX = false;             // Disable transmit XON/XOFF control

SetCommState(hCAN, &dcb);

// Only look for arrival of a character
SetCommMask(hCAN, EV_RXCHAR);

// Set events for overlapped functions.
olwrite.hEvent = CreateEvent(NULL, true, false, NULL);
olread.hEvent = CreateEvent(NULL, true, false, NULL);

// Setup RCV handles
HANDLE hRcvHandles[2] = {olread.hEvent,
                     olstatus.hEvent};

fDone = false;
DWORD result;

while(!fDone)
{
   SecureZeroMemory(buf, sizeof(buf));
   SecureZeroMemory(rcvData, sizeof(rcvData));
   if(!ReadFile(hCAN, buf, sizeof(buf), &bytesread, &olread))
   {
    // We have an error, and the only one accepted is
    //  ERROR_IO_PENDING.  Anything else means we are in
    //  trouble.
    if(GetLastError() == ERROR_IO_PENDING)
    {
        // We are reading the input
        print_status("Waiting for input");
        readingInput = true;

        result = WaitForSingleObject(olread.hEvent, 10000);
        switch (result)
        {
        // Read completed
        case WAIT_OBJECT_0:
            if(GetOverlappedResult(hCAN, &olread, &bytesread, false))
            {
                // We returned successfully
                if(bytesread > 0)
                {
                    CString myReturned;
                    myReturned.Format("%s", buf);
                    AfxMessageBox((LPCTSTR)myReturned, MB_OK, 0);
                }
            }    
            else
            {
                // Failed to get a result
                print_status("Did not get a response");
            }
            break;
        case WAIT_TIMEOUT:
            // No yet finished. Later put in an IdleFunction.
            AfxMessageBox("Timed out", MB_OK, 0);
            break;
        default:
            // Could be a problem here.  Handle it.
            AfxMessageBox("Problem with overlapped");
            break;
        }
    }
    else
    {
        // We failed to read response
        strcat_s(m_print_fail_msg, FAIL_MESSAGE_SIZE, "\n");
        strcat_s(m_print_fail_msg, FAIL_MESSAGE_SIZE, "Failed to get a response.");
    }
  }
  .
  .
  .
  .

thanks,
 

HyperEngineer
If it ain't broke, it probably needs improvement.

RE: Problem reading from the serial port.

In your call to CreateEvent(), the second parameter is "true" which creates a manual reset event. I think you have to explicitly call ResetEvent( hEvent ) right after CreateEvent() to set the event to non-signaled, otherwise WaitForSingleObject() just returns immediately. At least, I am quite sure I have seen this happen before.

HTH

Greg

RE: Problem reading from the serial port.

(OP)
Hi Greg,

  The WaitForSingleObject() does not return immediately.  It times out.  In this case it waits 10 seconds.

  The third parameter of the CreateEvent() sets the event to the non-signalled state.  I believe when I call the ReadFile() function it sets the event to the non-signalled state as well.

  But I know the data is there on the port, because I can put HyperTerminal on it and it will catch the data.

thanks,

HyperEngineer
If it ain't broke, it probably needs improvement.

RE: Problem reading from the serial port.

Admittedly I have only limited experience programming with the COM port, so I hope I'm not wasting your time. That being said, would using the SetCommTimeouts() function have any impact? Setting the ReadTotalTimeoutConstant and ReadTotalTimeoutMultiplier may cause the overlapped event to become signalled earlier, although these may not be relevant in overlapped or asynchronous I/O. Could it be that there just aren't sizeof(buf) bytes in the COM receive buffer? Although, even if there are not, the bytesread parameter should be set to the count of whatever is in the buffer. Sorry for just thinking out loud.

Greg

RE: Problem reading from the serial port.

(OP)
Greg,

 Thanks for the input, but the timeouts are not necessary in overlapped mode.  I'm only getting back 32 bytes and I have the buffers set for 256 bytes.  I should be OK there. I know that the data gets to the port.  If I put HyperTerminal on it, all the data is recovered.  I have to be doing something fundamentally wrong.  I, so far, can't figure it out.  I am going to try to use the ClearCommError() function to peek at the rcv buffer.  It it has anything, I will execute the ReadFile() function.  I'll let you know how it turns out.

thanks,  

HyperEngineer
If it ain't broke, it probably needs improvement.

RE: Problem reading from the serial port.

(OP)
Using the ClearCommError() I peeked into the rcv buffer.  There were 50 bytes.  Originally, I thought I was only getting 32, but there actually is 50 bytes.  But the ReadFile() function still can't read the port.

HyperEngineer
If it ain't broke, it probably needs improvement.

RE: Problem reading from the serial port.

hi,
to begin, use synchronous cosmunication;
leave overlapped technics, for later.
bye
victor

Red Flag This Post

Please let us know here why this post is inappropriate. Reasons such as off-topic, duplicates, flames, illegal, vulgar, or students posting their homework.

Red Flag Submitted

Thank you for helping keep Tek-Tips Forums free from inappropriate posts.
The Tek-Tips staff will check this out and take appropriate action.

Reply To This Thread

Posting in the Tek-Tips forums is a member-only feature.

Click Here to join Tek-Tips and talk with other members! Already a Member? Login

Close Box

Join Tek-Tips® Today!

Join your peers on the Internet's largest technical computer professional community.
It's easy to join and it's free.

Here's Why Members Love Tek-Tips Forums:

Register now while it's still free!

Already a member? Close this window and log in.

Join Us             Close