How to Read & Write the COM Port – A Step by Step Approach by bagavathikumar

Choose New Project from Visual Studio’s File menu.

 

In the New Project dialog box, select the MFC Application template, type the name as ReadCOM, and click OK. It will open the MFC Application Wizard, accept all the defaults but two: On the Application Type page, select Single Document, and on the Generated Classes, select Base Class as CFormView. When you’re finished, click Finish
 

Part I.

Go to the ClassView and Select the CReadCOMView Class and do the following steps.

Step 1: Create a class variable called uResult of the type UINT, which is used to hold the return value of the SetTimer function.

Right click the CReadCOMView in ClassView and select add -> add Variable. It will show the Add

Member Variable Wizard. Enter the variable type is UINT and the name is uResult.

 

    UINT uResult;               // SetTimer’s return value

Step 2: Create a class variable called m_nPortNumber of the type int, which is used to hold COM port Number like 0, 1, 2. By Defult tha value of the port number is 0.

Right click the CReadCOMView in ClassView and select add -> add Variable. It will show the Add Member Variable Wizard. Enter the variable type is int and the name is m_nPortNumber.

 

    int    m_nPortNumber;

Step 3: Create a class variable called m_bConfigStatus of the type BOOL, which is used to hold the Status of the port initialization process. if it is success, it will return TRUE else FALSE.

Right click the CReadCOMView in ClassView and select add -> add Variable. It will show the Add Member Variable Wizard. Enter the variable type is BOOL and the name is m_bConfigStatus.

 

    BOOL m_bConfigStatus;

Step 4: Create a handle variable, which is a file handle. because we will read and write the port like a file.

Right click the CReadCOMView in ClassView and select add -> add Variable. It will show the Add Member Variable Wizard. Enter the variable type is HANDLE and the name is m_hFile.

 

       HANDLE m_hFile;

 

Part II.

Go to the Resource View, Select the Dialog folder and double click the IDD_READCOM_FORM.

 

It will open the main dialog box. Do the Following steps.

Step 5: Add a Button

   1. Change the ID Property to BTN_CONNECT and Caption to Connect.
   2. Add the Click Event for that Button. Simply double click the button. it will open the coding part.
   3. Enter the following Code to OnBnClickedConnect() method
 

   // TODO: Add your control notification handler code here
    UpdateData(TRUE);
    if(!ConfigureCOMPort(1))
        return;
    uResult = SetTimer(1,1000,NULL);

    if ( uResult == 0 )
        AfxMessageBox(“Error: Could not connect the RS232 port!”, MB_OK|MB_ICONEXCLAMATION);
 

Step 6: Add another Button

   1. Change the ID Property to BTN_STOP and Caption to Stop.
   2. Add the Click Event for that Button. Simply double click the button. it will open the coding part.
   3. Enter the following Code to OnBnClickedStop() method.

 

        // Stop the timer. Indirectly it will stop the reading
    BOOL blStatus = KillTimer(uResult) ;

    // Check Whether the timer is killed properly or not.
    if ( blStatus == 0 )
        AfxMessageBox(“Error: Could not stop the watching of RS232 port!”,  MB_OK|MB_ICONEXCLAMATION);

    // Reset the handle variable
    CloseHandle( m_hFile ) ;

 

Step 7: Add the Label Box.

   1. Change the ID Property to LBL_RECEIVEDDATA.

Step 8: Add a Edit Box.

   1. Select the Editbox in toolbox and Paste the Dialog window.
   2. Right click the editbox and go to the add variable option.
   3. Enter the Variable name (in our case m_txtRead) and simply press ok button.

 

    CEdit m_txtRead;

 

Part III.

The basic setup of a communication port takes place using a DCB, or device control block structure. Members of this structure specify the baud rate, parity, data and stop bits, handshaking, and other aspects of port behavior. The current settings can be obtained using the GetCommState function and can be set by calling the SetCommState function. A helper function, BuildCommDCB, can be used to fill in parts of this structure on the basis of a string formatted in the style of an MS-DOS MODE command.

Now you have to add some supporting methods.

Step 9: Add a Method called BOOL ConfigureCOMPort(int nPortNo)

   1.

 

Goto the Class View and select the CReadCOMView class.
   2. Right click the CReadCOMView in ClassView and select add -> add Function.
   3. Enter the method name and parameters.
   4. Add the following code to that method.

 

    CString strPort;
    BOOL fSuccess;
    COMMTIMEOUTS timeout;
    DCB dcb;

    strPort.Format(“COM%d”, nPortNo) ;

    //Create the handle for read the COM port
    m_hFile =  CreateFile( strPort,
                    GENERIC_READ | GENERIC_WRITE,
                    (DWORD)NULL,   // exclusive access
                    NULL,          // no security
                    OPEN_EXISTING,
                    FILE_ATTRIBUTE_NORMAL,
                    NULL           // hTemplate
                    );

    //Check weather the handle is valid or not
    if (INVALID_HANDLE_VALUE == m_hFile)
    {
        AfxMessageBox(“Error: Could not open the RS232 port!”, MB_OK|MB_ICONEXCLAMATION);
        return FALSE;
    }

    // set up the comms parameters now that we have a handle
    SetupComm(m_hFile,(DWORD)2048, (DWORD)2048);

    // Set up the DCB with our settings
    // Get it first so we fill all members
    fSuccess = GetCommState(m_hFile,&dcb);

    if (!fSuccess)
    {
        // Handle the error.
        AfxMessageBox (“Error: Failed to Get the System Communication Settings.”, MB_OK|MB_ICONEXCLAMATION );
                return FALSE;
    }

    dcb.BaudRate = CBR_9600;
    dcb.ByteSize = 8;            // data size
    dcb.Parity = NOPARITY;        // No Parity Bit
    dcb.StopBits = ONESTOPBIT;

    // assign it
    fSuccess = SetCommState(m_hFile, &dcb);

    //Now check the configuration of the communication device is valid or
    //not after assign the comms parameters
    if ( fSuccess == 0 )
    {
        AfxMessageBox(“Error: In Control Setting for a Serial Communications Device.”, MB_OK|MB_ICONEXCLAMATION);
        return FALSE;
    }

    // Set up the timeouts to use, they are quite short, since we will loop anyway.
    // Do not make them zero, else we will have a CPU load problem. Too large a value,
    // and we have to wait for comms to time out when shutting down

    // fill timeout structure
    GetCommTimeouts(m_hFile, &timeout);
    timeout.ReadIntervalTimeout = 100;           // 500ms between incomming chars.
    timeout.ReadTotalTimeoutConstant = 500;
    timeout.ReadTotalTimeoutMultiplier = 0;
    timeout.WriteTotalTimeoutConstant = 2000;
    timeout.WriteTotalTimeoutMultiplier = 60;    // 60ms per char sent

    SetCommTimeouts(m_hFile, &timeout);

    return TRUE;

Step 10: Add the OnTimer Message

   1. Go to solution explorer and double click the ReadCOM file.
   2. Go to Properties window and select Messages icon.
   3. Select the WM_TIMER Message and Add the OnTimer Event.
   4. Add the following code.

 

    unsigned char set_Data[15];

    // Prepare the Dummy Data for read and write the COM Port.
    for(int c=0; c<10; c++)
            set_Data[c] = 65 + c;

    // Write the Data to COM Port
    WriteToCOMPort(set_Data);

    unsigned char get_Data[15];

    ReadFromCOMPort(get_Data);

    m_txtRead.SetWindowText( (LPCTSTR)get_Data );
    CFormView::OnTimer(nIDEvent);
 

Step 11: Add the ReadFromCOMPort(unsigned char* c_Data) method.

 

BOOL CReadCOMView::ReadFromCOMPort(unsigned char* c_Data)
{
    BOOL error;

    DWORD numberOfBytesRead = 0;
    error = ReadFile(m_hFile,
                c_Data,
                10,                 // Number Of Bytes To                 Read,
                &numberOfBytesRead,
                NULL);

    if(numberOfBytesRead == 0)
        return FALSE;

    c_Data[numberOfBytesRead] = ‘’ ;
    SetDlgItemText(LBL_VIS_SLABEL, (LPCTSTR)c_Data);

    return TRUE;
}
 

Step 12: Add the WriteToCOMPort(unsigned char* c_Data) method.

 

BOOL CReadCOMView::WriteToCOMPort(unsigned char* c_Data)
{
    BOOL fSuccess;
    DWORD numberOfBytesWritten=0;

    // send the bytes out on the wire
    if (INVALID_HANDLE_VALUE == m_hFile)
    {
        MessageBox(“Error: Cannot send. Port closed!n”);   // busy shutting down the app
        return FALSE;
    }

    fSuccess = WriteFile(m_hFile,
                c_Data,
                10,                 //  Number Of Bytes To                     Write,
                &numberOfBytesWritten,
                NULL);
    return TRUE;

    if(!fSuccess)
    {
        AfxMessageBox(“Error: Could not Write the data to RS232 port!”, MB_OK|MB_ICONEXCLAMATION);
        return FALSE;
    }
    return TRUE;
}

Now run the program. it will read & write the COM port. The out put of the program is ABCDEFGHIJ.


Attachments

Source Files Sample Program