Question

I want to read and write from serial using events/interrupts. Currently, I have it in a while loop and it continuously reads and writes through the serial. I want it to only read when something comes from the serial port. How do I implement this in C++?

This is my current code:

    while(true)
    {
        //read
        if(!ReadFile(hSerial, szBuff, n, &dwBytesRead, NULL)){
        //error occurred. Report to user.
        }

        //write
        if(!WriteFile(hSerial, szBuff, n, &dwBytesRead, NULL)){
        //error occurred. Report to user.
        }


        //print what you are reading
        printf("%s\n", szBuff);

    }
Was it helpful?

Solution

Use a select statement, which will check the read and write buffers without blocking and return their status, so you only need to read when you know the port has data, or write when you know there's room in the output buffer.

The third example at http://www.developerweb.net/forum/showthread.php?t=2933 and the associated comments may be helpful.

Edit: The man page for select has a simpler and more complete example near the end. You can find it at http://linux.die.net/man/2/select if man 2 select doesn't work on your system.

Note: Mastering select() will allow you to work with both serial ports and sockets; it's at the heart of many network clients and servers.

OTHER TIPS

For a Windows environment the more native approach would be to use asynchronous I/O. In this mode you still use calls to ReadFile and WriteFile, but instead of blocking you pass in a callback function that will be invoked when the operation completes.

It is fairly tricky to get all the details right though.

Here is a copy of an article that was published in the c/C++ users journal a few years ago. It goes into detail on the Win32 API.

here a code that read serial incomming data using interruption on windows you can see the time elapsed during the waiting interruption time

int pollComport(int comport_number, LPBYTE buffer, int size) { BYTE Byte; DWORD dwBytesTransferred; DWORD dwCommModemStatus; int n; double TimeA,TimeB; // Specify a set of events to be monitored for the port. SetCommMask (m_comPortHandle[comport_number], EV_RXCHAR ); while (m_comPortHandle[comport_number] != INVALID_HANDLE_VALUE) { // Wait for an event to occur for the port. TimeA = clock(); WaitCommEvent (m_comPortHandle[comport_number], &dwCommModemStatus, 0); TimeB = clock(); if(TimeB-TimeA>0) cout <<" ok "<<TimeB-TimeA<<endl; // Re-specify the set of events to be monitored for the port. SetCommMask (m_comPortHandle[comport_number], EV_RXCHAR); if (dwCommModemStatus & EV_RXCHAR) { // Loop for waiting for the data. do { ReadFile(m_comPortHandle[comport_number], buffer, size, (LPDWORD)((void *)&n), NULL); // Display the data read. if (n>0) cout << buffer <<endl; } while (n > 0); } return(0); } }

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top