Serial Communications with ActiveX

Introduction

In this article, we show a simple example to send and receive data through the serial port. In what concerns data reception, we use an event driven mechanism. An event is generated and transmitted to our program when a character arrives on the serial port. The MSComm control uses the OnComm event to trap and handle communications events. We check the event type; if it is a "receive event," we retrieve data from the serial input buffer and display it in a text box.

Example

Follow these steps to make a sample of serial communication under Visual C++:

  1. Select a "new" project from the "File" menu. Name the project "Serial".
  2. Under the "Projects" tab, select "MFC App Wizard" and click "OK".
  3. In the first step, select "Single Document" instead of "Multiple Documents".
  4. In the second step, click "Next".
  5. In the third step, make sure that "ActiveX Controls" is checked.
  6. In the fourth and fifth steps, click "Next".
  7. In the sixth step, change the base class of "CserrView" to "CFormView".
  8. Select "IDD_Serial_Form" under "Dialog" on the "Resources View" tab. Create two EditBoxes: one for sending data and the other for viewing received data. Make one button to confirm a send of data; change its caption to "Send".
  9. Next, you must add the ActiveX control. Go to the "Project" menu and select "Add To Project"; then select "Components And Controls". Next, find the "Microsoft Communications Control, version 6.0" in "Registered ActiveX Controls" and click the "Insert" button; then click "OK". At the end, click the "Close" button.
  10. Now, you must associate several variables for each control. Select "Class Wizard" in the "View" menu. On the "Member Variables" tab, you see all the controls IDs you have placed on the form. For each control, associate one variable by selecting the control and clicking "Add variable".
  11. With the "class Wizard", you must add two messages: one for the "send" button and the other for the MSComm event "OnComm". To do this, select the MSComm object ID. On the right, you see "OnComm" messages. Click to "Add Function", and repeat this step for "IDC_Button1".

Com Initialization

Before you send or receive data on the serial port, you should initialize it. You can make that in the code or directly by clicking the right button on the MSComm Control and selecting "Properties MSComm Object".

For more information about InputLen, InputMode, and RThreshold, you should see the help file "comm98.chm".

void CSerialView::OnInitialUpdate()
{
   CFormView::OnInitialUpdate();
   GetParentFrame()->RecalcLayout();
   ResizeParentToFit();
   // COM Port Initialization

   m_comm.SetCommPort(1);    // Com 1
   m_comm.SetSettings("9600,N,8,1");
   m_comm.SetInputLen(1);
   m_comm.SetInputMode(0);
   m_comm.SetRTSEnable(TRUE);
   m_comm.SetRThreshold(1);
   m_comm.SetPortOpen(TRUE);
}

Sending Data

You must begin by updating the data variable from the edit box. Next, you convert data to "Variant"; you can do that by calling the "COLeVariant" class that encapsulates the "Variant" structure.

void CSerialView::OnButton1()
{
   // TODO: Add your control notification handler code here

   UpdateData(TRUE);
   m_comm.SetOutput(COleVariant(m_output));
}

Receiving Data

"GetCommEvent()" permits us to know the event type, if it is equal to 2; it is concern a data arrival in serial port. To retrieve the data from a serial buffer, you must call the GetInput() method, which returns a Variant object. The next step consists of extracting a string from a Variant structure.

void CSerialView::OnOnCommMscomm1()
{
   // TODO: Add your control notification handler code here
   if (m_comm.GetCommEvent()==2 )
   {
      VARIANT in_dat;
      in_dat = m_comm.GetInput();
      CString strInput(in_dat.bstrVal);
      m_input = m_input + strInput;
      UpdateData(FALSE);
   }

}


Downloads

Comments

  • How to fix Invalid Port Number

    Posted by Nguyen Hien Hoa on 01/09/2013 08:17pm

    Dear Mongi MAHMOUDI, I am newbie of MFC and ActiveX. I run your project and created my project. Both of them built successfully but When I debug, there appears a message box "Invalid Port Number", I click "OK", and then, my program is displayed correctly, I entered some text in output to transmit, then click "Send" button, but there appears another message box "Operation valid only when port is open". The input didn't display output. Do I need to plug device in a COM port or use virtual port software? Can you tell me fix this error? Thanks, Nguyen Hien Hoa

    Reply
  • serial port programming to send and receive through data base

    Posted by apuamy on 03/28/2008 08:39am

    Hi there, i am sending th entire codes of the form down below i am able to send from a text box and receive in a text box line by line through com port. I know want to store this data in a data base line by line in records form. help me with codes. Dim strInput As String Dim ser As Long Private Sub Command1_Click() ser = 1 Text1.Enabled = False Text5.Enabled = False MSComm1.Output = Text2.Text Text1.Enabled = True Text5.Enabled = True Text2.Text = "" End Sub Private Sub Command2_Click() End Sub Private Sub Form_Load() MSComm1.PortOpen = True With Text1 'set the properties for the displaying textbox .BackColor = vbCyan .Locked = True .Text = "" End With 'Text1 With Text2 'set the properties for the 'send' textbox .TabIndex = 0 .Text = "" End With 'Text2 With Command1 'set the properties for the 'send' command button .Caption = "&Send" .Default = True .TabIndex = 1 End With 'Command1 End Sub Private Sub Form_Resize() Dim sngWidth As Single, sngHeight As Single Dim sngDisplayHeight As Single Dim sngTxtWidth As Single Dim sngCmdWidth As Single, sngCmdHeight As Single 'calculate the inner size of the form sngWidth = ScaleWidth sngHeight = ScaleHeight With Command1 'resize and reposition the command button sngCmdHeight = .Height sngCmdWidth = .Width sngDisplayHeight = sngHeight - sngCmdHeight sngTxtWidth = sngWidth - sngCmdWidth .Move sngTxtWidth, sngDisplayHeight, sngCmdWidth, sngCmdHeight End With 'Command1 'resize and reposition the label Text1.Move 0, 0, sngWidth, sngDisplayHeight 'resize and reposition the textbox Text2.Move 0, sngDisplayHeight, sngTxtWidth, sngCmdHeight End Sub Private Sub Timer1_Timer() If (MSComm1.InBufferCount > 0) Then strInput = MSComm1.Input Text1.Text = Text1.Text + strInput Text5.Text = Text5.Text + strInput End If 'storing input data in a data base Data2.RecordSource = "SELECT * FROM rxmsg WHERE SER=" & ser Data2.Refresh Data2.Recordset.Edit Data2.Recordset.Fields("RXMSG") = Text5.Text Data2.UpdateRecord ser = ser + 1 Text5.Text = "" End Sub After loading the form, i hit on command button to send data.After this the device replies back and can be seen in text box1.now i am simultaneously put the same receive data in textbox 5. After that i am trying to transfer the data to a data base. After a line is received , i erase the textbox 5 and again go for the next line. The error i am getting 1st on loading form- object doesnt support the property or method 2nd- Run time error '3021' No current record I have a doubt the codes written in the timer1 in red colour has to be written there or else where. On running the program cannot be stopped normally, but by task manager. data base 2 concerned table has two field i.e SER and RXMSG. ser is being incremented to go to the particular record and fill. Thanks for helping me.

    • Mscom to database

      Posted by mongi058 on 03/28/2008 05:56pm

      You must take the project lot by lot, you must also correct the com received routine.
      for the database your code is not clear...
      you must create a separate database first. next you can use the connection and recordset vb object  to move or read data to DB.
      
       
      'Inialize the COM1 properties
      MSComm1.RThreshold = 1 ' Nombre de caractC(res indiquC) par la propriC)tC) RThreshold
         
      MSComm1.SThreshold = 0
         
      MSComm1.CommPort = 1 
         
      MSComm1.Settings = "9600,N,8,1"
        
      MSComm1.InputLen = 1
      
      'Sending data with COM1
      MSComm1.Output = "ATV1Q0" & Chr$(13)
      'Receiving data from COM1 using interupt method
      Private Sub MSComm1_OnComm()
         Dim x As String
         
         Select Case MSComm1.CommEvent
        
      
          Case comEvReceive
          
            x = MSComm1.Input
          End Select
      End Sub
      
      ------------------
      for more info use this pseudo to send an email at hotmail.com

      Reply
    Reply
  • how can i send a binary data via rs232

    Posted by ojan_donk on 03/17/2008 12:32pm

    Haow can I send binary data using mscomm on visual basic... I'm using rs232 serial communication for interfacing my device with PC. for example, so far i wrote : mscomm1.output = chr$ (5) {5 is example] and mscomm1.output = "5" this two doesn't work. I'm newbie in VB. Thanks for the help. I'm sorry if my english is bad. I'm from Indonesia, and i'm not good in English.

    • Send binary data

      Posted by mongi058 on 03/28/2008 06:29pm

      'Inialize the COM1 properties
      MSComm1.RThreshold = 1 ' Nombre de caractC(res indiquC) par la propriC)tC) RThreshold
         
      MSComm1.SThreshold = 0
         
      MSComm1.CommPort = 1 
         
      MSComm1.Settings = "9600,N,8,1"
        
      MSComm1.InputLen = 1
      
      'Sending data with COM1
      MSComm1.Output = Chr$(13)
      'Receiving data from COM1 using interupt method
      Private Sub MSComm1_OnComm()
         Dim x As String
         
         Select Case MSComm1.CommEvent
        
      
          Case comEvReceive
          
            x = MSComm1.Input
          End Select
      End Sub
      
      ------------------
      for more info use this pseudo to send an email at hotmail.com

      Reply
    Reply
  • serial communication using mfc appwizard

    Posted by savyasachi_marwaha on 09/17/2006 02:16pm

    can any body tell me how to communicate with the serial port using mfc appwizard.I am making a server which sends messages recd from the client to the seial port.I have been able to send text msg to server from the client but how to get them accross from there to the serial port is the big problem.reply urgently or send links

    Reply
  • how to transfer binary data or data containing NULL character

    Posted by priya161 on 05/26/2006 07:51am

    how to transfer binary data or data containing NULL character?? because the method u have explained works only for Strings. i want to transmit and receive binary data. please explain how to send this one using Varaint and VT_UI1

    Reply
  • why it doesn't work on win2000 ?

    Posted by tomjey on 04/25/2006 10:36am

    can anybody help me ?

    • even the attached zip files?

      Posted by leelsuc on 05/03/2006 02:14am

      worked very well on xp-pro here. something omitted: 1. adding member variables m_input and others 2. drag the telephone icon "the control" onto forms

      Reply
    Reply
  • Thanks,But need more improvement!

    Posted by Picstudent on 04/12/2006 02:06am

    Code description is not enough for a beginner. Should add more detailed description if helping newbies is intended. But thanks for this much work.

    • memory leak

      Posted by maunopulos on 09/28/2006 07:15am

      when sending and receiving lot of data, it seems to have a memory leak problem. Am I right or wrong?

      Reply
    Reply
  • MSCOMM

    Posted by rrammalar on 03/20/2006 02:37am

    now i am in need of ur help. i can able send a data. through this code., void CSerialView::OnButton1() { // TODO: Add your control notification handler code here UpdateData(TRUE); m_comm.SetOutput(COleVariant(m_output)); } how to receive data without make click in receiving side . where to i placed this code., if (m_comm.GetCommEvent()==2 ) { VARIANT in_dat; in_dat = m_comm.GetInput(); CString strInput(in_dat.bstrVal); m_input = m_input + strInput; UpdateData(FALSE); } if anybody know help me..

    • thread exited with code 1

      Posted by maunopulos on 09/28/2006 09:02am

      The thread 0xBA4 has exited with code 1 (0x1). I got this message in DEBUG mode when I was canceling application. The thread belongs to MSCOMM. Does anyody knows why?

      Reply
    • Reply to MSCOMM and a Memory Leak problem

      Posted by dalbinblue on 04/04/2006 10:01am

      The code written in the article should automatically recieve the data.  The OnOnCommMscomm1() function is called whenever the serial port receives data, so it will be triggered automatically.  Note that if you have looped the serial cable back such that the output line feeds the input line, then the only time event is triggered is when the button is pressed because that is the only source of serial data.
      
      Additionally, depending on the amount of serial communications you perform you could have memory errors because the code has a memory leak.  The problem is that the data in VARIANT in_dat is a pointer to a bstring not the data itself.  Thus each time the receive data event is processed, a small amount of memory is lost.  If you use this on a embedded platform like the PocketPC it causes problems very quickly.  The proper way to deal with this is to attach it to the bstr wrapper class CComBSTR then empty the string, as shown below.
      
      CComBSTR bstr;
      bstr.Attach(in_dat.bstrVal);
      bstr.Empty();

      Reply
    Reply
  • Mr. Svpe

    Posted by svpe on 01/31/2006 02:09am

    This is only a comment: I would say this is a good article. It helped me to solve my serial communication problems. Petr, beginner in Visual C++

    Reply
  • help

    Posted by Sunlight on 04/19/2005 06:44am

    I read the above context and i very like it, but i want transfer with ASCII code.
     
    Please, Help me

    Reply
  • Loading, Please Wait ...

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Live Event Date: December 11, 2014 @ 1:00 p.m. ET / 10:00 a.m. PT Market pressures to move more quickly and develop innovative applications are forcing organizations to rethink how they develop and release applications. The combination of public clouds and physical back-end infrastructures are a means to get applications out faster. However, these hybrid solutions complicate DevOps adoption, with application delivery pipelines that span across complex hybrid cloud and non-cloud environments. Check out this …

  • On-demand Event Event Date: October 29, 2014 It's well understood how critical version control is for code. However, its importance to DevOps isn't always recognized. The 2014 DevOps Survey of Practice shows that one of the key predictors of DevOps success is putting all production environment artifacts into version control. In this webcast, Gene Kim discusses these survey findings and shares woeful tales of artifact management gone wrong! Gene also shares examples of how high-performing DevOps …

Most Popular Programming Stories

More for Developers

RSS Feeds