CSerial - A C++ Class for Serial Communications

This article was contributed by Tom Archer and Rick Leinecker.

Preface

This class is meant as a very simple alternative to the more robust, feature-rich CSerialPort class presented by Remon Spekreijse. In other words, if you need a very simple class to read or write data to the serial port, then this class might be perfect for you. However, if you need more control over just how the serial communications is to be conducted, then Remon's very fine class will probably be what you want.

Introduction

Common uses of remote communications are business applications that link differnet sites in order to keep tabs on inventories and transactions. For example, I once wrote a large drug-dispensing proram in which many clinic sites automatically received new orders and updated pharmacy information each evening from a centry host location. The centry host gets inventory levels and transaction information from each site during evening hours. A large part of my time was spent construction telecommunications routines that sent and received information packets. To that extent, I offer this simple CSerial class in the hopes that it will save someone from the grungy world of serial communications that I had to endure and will free your mind up to concentrate on the problem domain.

CSerial class member functions

  • CSerial::CSerial() -
  • CSerial::CSerial() - Basic c'tor that takes no arguments.
  • CSerial::Open(int nPort = 2, int nBaud = 9600 ) - This member function is used to open the serial port. It takes two interger arguments. The first argument contains the port number where the valid entries are 1 through 4. The second argument is the baud rate. Valid values for this argument are 1200, 2400, 4800, 9600, 19200, 38400 and 76800. This function returns TRUE if successful. Otherwise, it returns a value of FALSE.
  • CSerial::Close() - While the d'tor will automatically close the serial port for you, this function has been added just in case there is a reason that you need to explicit close the port.
  • CSerial::SendData(const char *, int) - This function writes data from a buffer to the serial port. The first argument it takes is a const char* to a buffer that contains the data being sent. The second argument is the number of bytes being sent. This function will return the actual number of bytes that are succesfully transmitted.
  • CSerial::ReadDataWaiting(void) - This function simply returns the number of bytes that waiting in the communication port's buffer. It basically allows you to "peek" at the buffer without actually retrieving the data.
  • CSerial::ReadData(void*, int) - This function reads data from the port's incoming buffer. The first argument that it takes is a void* to a buffer into which the data will be placed. The second argument is an integer value that gives the size of the buffer. The return value of this function contains the number of bytes that were successfully read into the provided data buffer.

Example Usage

Here are some examples of how easy it is to use this class.

Opening the serial port


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

Sending Data


CSerial serial;
if (serial.Open(2, 9600))
{
 static char* szMessage[] = "This is test data";
 int nBytesSent = serial.SendData(szMessage, strlen(szMessage));
 ASSERT(nBytesSent == strlen(szMessage));
}
else
 AfxMessageBox("Failed to open port!");

Reading Data


CSerial serial;
if (serial.Open(2, 9600))
{
 char* lpBuffer = new char[500];
 int nBytesRead = serial.ReadData(lpBuffer, 500);
 delete []lpBuffer;
}
else
 AfxMessageBox("Failed to open port!");

Downloads

Download source - 2 Kb


Comments

  • Cannot convert 'char[15]' to 'wchar_t *'

    Posted by Eduardo on 10/22/2014 10:37am

    I'm using Embarcadero XE7 as compiler and I'm having this problem:Cannot convert 'char[15]' to 'wchar_t *'at lines:wsprintf( szPort, "COM%d", nPort ); m_hIDComDev = CreateFile( szPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL );

    Reply
  • beginner question

    Posted by RRR on 07/08/2014 08:30am

    Hi all, 1. I download Microsoft Visual Studio Express 2013 2. I create a new c++ Empty Project 3. import the source file to the project Result: I have lot o errors. please ca some one help me with the steps to make this works thanks. Errors: Error 1 error C1083: Cannot open include file: 'stdafx.h': No such file or directory c:\personal\projects\visual studio 2013\projects\project1\project1\serial.cpp 3 1 Project1 2 IntelliSense: identifier "BOOL" is undefined c:\Personal\Projects\visual studio 2013\Projects\Project1\Project1\Serial.h 23 2 Project1 3 IntelliSense: identifier "BOOL" is undefined c:\Personal\Projects\visual studio 2013\Projects\Project1\Project1\Serial.h 24 2 Project1 4 IntelliSense: identifier "BOOL" is undefined c:\Personal\Projects\visual studio 2013\Projects\Project1\Project1\Serial.h 30 2 Project1 5 IntelliSense: identifier "BOOL" is undefined c:\Personal\Projects\visual studio 2013\Projects\Project1\Project1\Serial.h 33 2 Project1 6 IntelliSense: identifier "HANDLE" is undefined c:\Personal\Projects\visual studio 2013\Projects\Project1\Project1\Serial.h 35 2 Project1 7 IntelliSense: identifier "OVERLAPPED" is undefined c:\Personal\Projects\visual studio 2013\Projects\Project1\Project1\Serial.h 36 2 Project1 8 IntelliSense: identifier "BOOL" is undefined c:\Personal\Projects\visual studio 2013\Projects\Project1\Project1\Serial.h 37 2 Project1 9 IntelliSense: cannot open source file "stdafx.h" c:\Personal\Projects\visual studio 2013\Projects\Project1\Project1\Serial.cpp 3 1 Project1 10 IntelliSense: identifier "memset" is undefined c:\Personal\Projects\visual studio 2013\Projects\Project1\Project1\Serial.cpp 9 2 Project1 11 IntelliSense: identifier "OVERLAPPED" is undefined c:\Personal\Projects\visual studio 2013\Projects\Project1\Project1\Serial.cpp 9 40 Project1 12 IntelliSense: identifier "NULL" is undefined c:\Personal\Projects\visual studio 2013\Projects\Project1\Project1\Serial.cpp 11 16 Project1 13 IntelliSense: identifier "FALSE" is undefined c:\Personal\Projects\visual studio 2013\Projects\Project1\Project1\Serial.cpp 12 14 Project1 14 IntelliSense: identifier "BOOL" is undefined c:\Personal\Projects\visual studio 2013\Projects\Project1\Project1\Serial.cpp 23 1 Project1 15 IntelliSense: identifier "TRUE" is undefined c:\Personal\Projects\visual studio 2013\Projects\Project1\Project1\Serial.cpp 26 26 Project1 16 IntelliSense: identifier "DCB" is undefined c:\Personal\Projects\visual studio 2013\Projects\Project1\Project1\Serial.cpp 30 2 Project1 17 IntelliSense: identifier "wsprintf" is undefined c:\Personal\Projects\visual studio 2013\Projects\Project1\Project1\Serial.cpp 32 2 Project1 18 IntelliSense: identifier "CreateFile" is undefined c:\Personal\Projects\visual studio 2013\Projects\Project1\Project1\Serial.cpp 33 16 Project1 19 IntelliSense: identifier "GENERIC_READ" is undefined c:\Personal\Projects\visual studio 2013\Projects\Project1\Project1\Serial.cpp 33 36 Project1 20 IntelliSense: identifier "GENERIC_WRITE" is undefined c:\Personal\Projects\visual studio 2013\Projects\Project1\Project1\Serial.cpp 33 51 Project1 21 IntelliSense: identifier "NULL" is undefined c:\Personal\Projects\visual astudio 2013\Projects\Project1\Project1\Serial.cpp 33 69 Project1 22 IntelliSense: identifier "OPEN_EXISTING" is undefined c:\Personal\Projects\visual studio 2013\Projects\Project1\Project1\Serial.cpp 33 75 Project1

    • maybe i can help you

      Posted by davide on 08/09/2014 04:17am

      step0: create stdafx.h in your project dir.. where there are serial.h , serial.cpp and your cpp main file step1: in serial.h #include #include #include step2: in your main c++ file #include "stdafx.h" #include #include "serial.h" maybe an error will remain : i'm talking about "wsprintf". to remove this error you should try to change the first parameter into TCHAR object. I solved the problem with this writing: wsprintf( tchar, L"your_text%d", your_int ); where tchar is a TCHAR object (ie: TCHAR tchar[15];) see msdn documentation sorry for the english.. i'm an italian student :)

      Reply
    Reply
  • How to set baudrate for serial port in c++

    Posted by Sushant on 07/17/2013 09:58pm

    I am start a program to set baudrate,parity,start/stop,parity bit .. but i dont understand to set baud rate????

    Reply
  • Visual Studio not recognizing BOOL, HANDLE, and OVERLAPPED

    Posted by Eddie on 05/24/2013 09:32am

    Hi, I've been trying to compile a program using the Serial library, but it doesn't seem to recognize BOOL, HANDLE, or OVERLAPPED. Is there another library I should be including? I was able to typedef the bool, but not handle or overlapped.

    • header file

      Posted by Clovis Caio on 10/15/2014 12:55pm

      at serial.h include windows header file

      Reply
    • bool, handle ...

      Posted by Fabian on 01/03/2014 06:42am

      Hi, have you figured out a solution? I have the same problem as you described. best regards!

      Reply
    • bool, handle ...

      Posted by Fabian on 01/03/2014 06:40am

      Hi, have you figured out how to use the serial libary? I have the same problem with BOOl, Handle and overlapped. best regards

      • Windows

        Posted by Sev on 01/08/2014 01:56am

        Dump an "#include " into the Serial.h file. Windows defines BOOL, HANDLES, and the OVERLAPPED struct, so you just need to include the windows.h header in there and you should be good to go.

        • Windows.h

          Posted by Diego Phoenix on 08/27/2014 11:51am

          Thanks! Solved my problem too. But I had another problem now: wsprintf( szPort, L"COM%d", nPort ); argument of type "char*" (szPort) is imcompatible with parameter of type "LPWSTR". What do I do?

          Reply
        Reply
      Reply
    • Same Problem

      Posted by Randall on 12/19/2013 03:12pm

      I have the same problem going on. Were you able to figure it out?

      Reply
    Reply
  • Reading Serial

    Posted by Javier Melendez on 04/24/2013 04:11pm

    I've tried to read some info coming from an Arduino Board. I'm using MFC in Visual Studio 2010, I haven't been able to read info, I've received the data correctly in the Serial Monitor of the Arduino IDE. Otherwise my variable in Visual Studio takes some strange values and i don't know why. Do I have to convert from ASCII code or something like that? Thanks!

    Reply
  • Working with higher COM port numbers

    Posted by Robert Schneckenhaus on 03/29/2013 09:43am

    If you want to use this class for high port numbers like COM10, COM11, COM12 ... you have to modify something in CSerial::Open. Just add "\\\\.\\" in front of the two occurences of "COM%d". This will also work for COM1, COM2 etc. This is very useful for working with Arduino boards as they may have high port numbers like COM13 and with this fix it's easy to communicate with the board through the serial interface.

    • ?

      Posted by Yas on 06/06/2014 12:25pm

      Actually you can just place L in front of "..COM%d". i.e. wsprintf( szPort, L"COM%d", nPort ); wsprintf( szComParams, L"COM%d:%d,n,8,1", nPort, nBaud );

      Reply
    • COM ports higher than COM9

      Posted by MA on 05/17/2013 09:52am

      if anybody is confused by what Robert Scneckenhaus means, read this http://playground.arduino.cc/Interfacing/CPPWindows, it is mentioned in the Furthermore part at the top.

      Reply
    Reply
  • response on above program

    Posted by asif ali on 12/20/2012 03:22am

    This program is not working it shows error "szport com%d, b0opened and many more" can anybody tell me why?

    • possible solution

      Posted by Jesper on 05/26/2014 02:06am

      ive had that same problem. Its probably your compiler that is set to use "unicode" instead of "multi-byte" Character sets.

      Reply
    • Find a valid COM port

      Posted by Robert Schneckenhaus on 03/29/2013 09:49am

      Maybe you try to access a COM port that is not accessible or connected. You may try the following code if you don't know the port number (but you can also look in your Windows Device Manager to see which COM-ports are available): #include int main(int argc, char **argv) { CSerial serial; int my_com_port = -1; // we start at COM1 but if you have external boards you want to communicate you may start at COM2 (int port = 2) for (int port = 1; port

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

Top White Papers and Webcasts

  • Live Event Date: October 29, 2014 @ 11:00 a.m. ET / 8:00 a.m. PT Are you interested in building a cognitive application using the power of IBM Watson? Need a platform that provides speed and ease for rapidly deploying this application? Join Chris Madison, Watson Solution Architect, as he walks through the process of building a Watson powered application on IBM Bluemix. Chris will talk about the new Watson Services just released on IBM bluemix, but more importantly he will do a step by step cognitive …

  • In support of their business continuity and disaster recovery plans, many midsized companies endeavor to avoid putting all their eggs in one basket. Understanding the critical role of last-mile connectivity and always available Internet access for their enterprises, savvy firms utilize redundant connections from multiple service providers. Despite the good intentions, their Internet connectivity risk may still be in a single basket. That is because internet service providers (ISPs) and competitive local …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds