Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / Languages / VC9.0

A simple class for using serial COM ports

3.38/5 (5 votes)
13 Oct 2008CPOL4 min read 2   1.9K  
This article introduces and explains the use of the serial_interface class. An easy way to add serial port interfaces to your C++ code.

Introduction

The above download, serial_interface.zip, contains a header and a source file (.hpp, and .cpp) that define the serial_interface class. This class was written to make it easier to implement and use serial ports in Windows for native C++ programs. While the references in the MSDN library for Programming Serial Connections are easy to follow, there may be times where the serial port should be configurable during runtime. This is a basic class, and does not support all of the features I would like, but it makes the initial setup much easier, thereby saving the software developer time.

The difficult part for the new COM programmer is the fact that Windows requires the user to fill out a structure containing over 20 variables, most of which will be set to 0, or NULL, or FALSE anyway. Using this structure, the user only needs to set the five most commonly used variables, which makes the setup process easier and faster.

Background

I wrote this code for a project I was doing at work because I needed it. Once it was done, it occurred to me that others may need it as well, so I'm am making it available.

Using the code

Using this class is very easy. It does not rely on any third party libraries, so all you have to do is include the serial_interface.hpp and serial_interface.cpp files in your project, #include "serial_interface.hpp" in files that need access to the serial port, get a pointer to the instance and handle, and start running.

Once the proper files are included in all the right places, using the class is very easy. The code looks like this:

C++
// set the namespace for the serial interface
using namespace SI;

// get a pointer to the class
serial_interface* serial_port = serial_interface::instance();

You could then get a structure for your configuration variables. This step is optional since the class will use the following default variables if you don't specify them. The default values are:

  • COM port: COM1
  • Baud rate: 38400
  • Byte size: 8
  • Stop bits: 1
  • Parity: none

However, if you would like to change those, a call to get_serial_interface will return the current port settings. Note that the software will attempt to open with these settings in the constructor as a self-test. The code to get the settings looks like this:

C++
// get the current port settings
serial_variables vars = serial_port->get_serial_interface();

The SI::serial_variables structure contains four members: baud, parity, bits, and stop_bits. These variables are all public, and can be easily changed. It is recommended that the users of the class make use of the constant variables included in Windows.h for these values, but any integer will work. For instance, to change the baud rate to 9600, use two stop bits, and enable parity, you could write:

C++
vars.baud = CBR_9600;            // 9600 baud
vars.parity = EVENPARITY;             // even parity is enabled (rare)
vars.bits = 4;                    // 4 bits in a byte (rare)
vars.stop_bits = TWOSTOPBITS        // use two stop bits

I should point out that the definitions of these variables are in the MSDN documentation of the DCB structure (one of the things that this class attempts to encapsulate). The MSDN link to the article can be found here: MSDN.

Once you have configured the port the way you want it (or decided that the default values are acceptable), you simply set up the port with a call to set_serial_interface, passing the COM port you wish to use (COM1, COM2, and COM3 are constants available for convenience) and the serial_variables structure.

C++
// set up the serial port

serial_port->set_serial_interface(COM1, vars);

And, that's all there is to it! Now, you can get a pointer to the serial port handle using get_serial_handle and start reading and writing to the serial port. The code looks like this:

C++
// get a pointer to the serial port's handle

HANDLE serial_handle = serial_port->get_serial_handle();

And, that's how you can set up a serial port in five lines of code.

Points of interest

Currently, the class does not support changing other factors of the configuration like timeouts or flow control. The reason for that is pretty simple: if you have to get access to those extra variables, then the encapsulation provided by this class is probably of little help to you, and you can use the standard Windows COM interface. The purpose of this class is to allow users with little knowledge of serial port configuration to get a COM port up and running quickly. It assumes that default values will be acceptable.

Also, the class makes use of the Singleton and p_impl* design patterns so that the software can only operate on one port at a time, and so that the user doesn't get lost in inaccessible functions if they are making use of the Visual Studio Intellisense feature.

Another feature of the class is that by making a call to set_serial_interface, the class will properly close out the current port and re-open with the new settings, allowing the user to configure the serial port on the fly, if needed.

History

This is the first release of this class, and I would welcome suggestions on any features that users would like to see implemented, or bugs that they have found. Feel free to contact me on CodeProject or on my regular blog. Thank you all.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)