Reading from serial ports using C++

Discussion in 'C++' started by Andres, Oct 3, 2008.

  1. Andres

    Andres New Member

    Joined:
    Jul 22, 2008
    Messages:
    34
    Likes Received:
    0
    Trophy Points:
    0
    Hi does anyone here know how to read from a serial port using c++?

    I just got this got from the internet but it doesnt work:

    CSerial serial;
    if (serial.Open(2, 9600))
    AfxMessageBox("Port opened successfully");
    else
    AfxMessageBox("Failed to open port!");
     
  2. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,009
    Likes Received:
    203
    Trophy Points:
    63
    Occupation:
    Senior Support Engineer
    Location:
    England
    I've used the WinAPI directly; this was to open the com port for writing and I just had a terminal emulator on the other end listening and displaying debug messages from my program. Probably doesn't take a lot of adapting (in fact may be usable directly for reading from the port):
    Code:
    CommPortHandle = OpenComm("com1",CommBufferSize,CommBufferSize);
    if (CommPortHandle >= 0)
    {
    DCB dcb;
    BuildCommDCB("com1:9600,n,8,1", &dcb);
    dcb.BaudRate = 19200;
    SetCommState(&dcb);
    }
    
     
  3. Andres

    Andres New Member

    Joined:
    Jul 22, 2008
    Messages:
    34
    Likes Received:
    0
    Trophy Points:
    0
    thanks xpi0t0s...hey does the following code do the same thing?
    Code:
    #include "windows.h"
    #include "time.h"
    #include "string.h"
    #include "stdio.h"
    
    BOOL SetCommDefaults(HANDLE hSerial);
    
    int main(int argc, char* argv[])
    {
        HANDLE hSerial = CreateFile("COM2",GENERIC_READ | GENERIC_WRITE,0,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED |FILE_FLAG_NO_BUFFERING,NULL);
        if (hSerial == INVALID_HANDLE_VALUE) return GetLastError();
        SetCommDefaults(hSerial);
    
        HANDLE hReadEvent = CreateEvent(NULL,TRUE,FALSE,"RxEvent");
        OVERLAPPED ovRead;
        OVERLAPPED ovWrite;
        memset(&ovRead,0,sizeof(ovRead));
        memset(&ovWrite,0,sizeof(ovWrite));
    
        ovRead.hEvent = hReadEvent;
    
        char szRxChar = 0;
        DWORD dwBytesRead = 0;
        DWORD dwBytesWritten = 0;
    
        while(szRxChar != 'q')
        {
            // Check if a read is outstanding
            if (HasOverlappedIoCompleted(&ovRead))
            {
                // Issue a serial port read
                if (!ReadFile(hSerial,&szRxChar,1,
                        &dwBytesRead,&ovRead))
                {
                    DWORD dwErr = GetLastError();
                    if (dwErr!=ERROR_IO_PENDING)
                        return dwErr;
                }
            }
    
            // Write the time out to the serial port
            time_t t_time = time(0);
            char buf[50];
            sprintf(buf,"Time is %s\n\r",ctime(&t_time));
            if (HasOverlappedIoCompleted(&ovWrite))
            {
                WriteFile(hSerial,buf,strlen(buf),
                        &dwBytesWritten,&ovWrite);
            }
    
    
            // ... Do some other processing
    
            // Wait 5 seconds for serial input
            if (!(HasOverlappedIoCompleted(&ovRead)))
                WaitForSingleObject(hReadEvent,5000);
    
            // Check if serial input has arrived
            if (GetOverlappedResult(hSerial,&ovRead,
                    &dwBytesRead,FALSE))
            {
                // Wait for the write
                GetOverlappedResult(hSerial,&ovWrite,
                    &dwBytesWritten,TRUE);
                // Display a response to input
                sprintf(buf,"You pressed the '%c' key\n\r",
                    szRxChar);
                WriteFile(hSerial,buf,strlen(buf),
                        &dwBytesWritten,&ovWrite);
            }
    
        }
    
        CloseHandle(hSerial);
        CloseHandle(hReadEvent);
        return 0;
    }
    
    BOOL SetCommDefaults(HANDLE hSerial)
    {
        DCB dcb;
        memset(&dcb,0,sizeof(dcb));
        dcb.DCBlength=sizeof(dcb);
        if (!GetCommState(hSerial,&dcb))
            return FALSE;
        dcb.BaudRate=9600;
        dcb.ByteSize=8;
        dcb.Parity=0;
        dcb.StopBits=ONESTOPBIT;
        if (!SetCommState(hSerial,&dcb))
            return FALSE;
        return TRUE;
    }
     
    Last edited by a moderator: Oct 7, 2008
  4. xpi0t0s

    xpi0t0s Mentor

    Joined:
    Aug 6, 2004
    Messages:
    3,009
    Likes Received:
    203
    Trophy Points:
    63
    Occupation:
    Senior Support Engineer
    Location:
    England
    No. I vaguely remember (from about 1993) experimenting with CreateFile as the "correct" way to use COM ports, not getting anywhere (probably because it involved millions of cryptic parameters), then finding that OpenComm worked perfectly well for what I wanted.

    Checking the help in VS2005 it seems OpenComm has disappeared, so ignore what I said earlier. That code was written back in the Windows 3.1 days and seems now to be completely obsolete. Sorry about that...
     

Share This Page

  1. This site uses cookies to help personalise content, tailor your experience and to keep you logged in if you register.
    By continuing to use this site, you are consenting to our use of cookies.
    Dismiss Notice