Still celebrating National IT Professionals Day with 3 months of free Premium Membership. Use Code ITDAY17

x
?
Solved

How to use Cserial ?

Posted on 2001-08-28
10
Medium Priority
?
2,762 Views
Last Modified: 2008-02-26
Firstly I know hardly any C++ and I'm using VC++ to try and make a little app that will open a com port at a set baud rate.

I was just reading this;
http://www.codeguru.com/network/serial.shtml

but dont know how to put it into action for my purposes.

So far I have a MFC dialog with an edit box for the com port number(m_Port) and one for the baud rate (m_baud)  and a OK button.

Where do I go from here?

This is my first attempt at C++ so please be gentle.
0
Comment
Question by:xSinbad
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 5
  • 4
10 Comments
 
LVL 14

Expert Comment

by:AlexVirochovsky
ID: 6435186
>>Where do I go from here?
...
CSerial serial;
if (serial.Open(m_Port, m_baud))
  {
    AfxMessageBox("Port opened successfully");
    static char* szMessage[] = "This is test data";
     int nBytesSent = serial.SendData(szMessage, strlen  (szMessage));
     ASSERT(nBytesSent == strlen(szMessage));
     serial.Close() ;
  }
else
 AfxMessageBox("Failed to open port!");
...
And download full test project, as sceleton
of your  Apps.
0
 
LVL 6

Author Comment

by:xSinbad
ID: 6435202
Ok Im guessing that I have to stick that after this;
void CSerialSetDlg::OnOK()

I download the serial.h and serial.cpp , what do I do with them?
0
 
LVL 14

Expert Comment

by:AlexVirochovsky
ID: 6435259
serial.h save in your directory and add in begin
of you code next line:
#include  "serial.h"
serial.c you can use for references.
>>Ok Im guessing that I have to stick that after this;
void CSerialSetDlg::OnOK()
Yes.
>>This is my first attempt at C++ so please be gentle.
I recomend you spend some time to understand serial.c and read some good tutorial
by C++. Next is small list:
Relisoft (C++) : http://www.relisoft.com/index.htm
http://www.eckelobjects.com/ThinkingInCPP2e.html
http://www.aul.fiu.edu/tech/visualc.html
http://www.swcp.com/~dodrill/cppdoc/cpplist.htm
http://www.mcp.com
http://www.cprogramming.com/tutorial.html
http://www.strath.ac.uk/CC/Courses/OldCcourse/tableofcontents3_1.html
http://www.athena.auth.gr/doc/ctutorial/tutorial.html
http://www.itlibrary.com
http://www.macaskill.com/freebooks/freebooks.html
(must register free).
0
Independent Software Vendors: We Want Your Opinion

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
LVL 6

Author Comment

by:xSinbad
ID: 6438860
Ok tried that and recieved these errors;

--------------------Configuration: Serial Set - Win32 Debug--------------------
Compiling...
Serial SetDlg.cpp
C:\Program Files\Microsoft Visual Studio\MyProjects\Serial Set\Serial SetDlg.cpp(103) : error C2440: 'initializing' : cannot convert from 'char [18]' to 'char *[]'
        There is no context in which this conversion is possible
C:\Program Files\Microsoft Visual Studio\MyProjects\Serial Set\Serial SetDlg.cpp(104) : error C2664: 'strlen' : cannot convert parameter 1 from 'char *[]' to 'const char *'
        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
C:\Program Files\Microsoft Visual Studio\MyProjects\Serial Set\Serial SetDlg.cpp(104) : error C2664: 'SendData' : cannot convert parameter 1 from 'char *[]' to 'const char *'
        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
C:\Program Files\Microsoft Visual Studio\MyProjects\Serial Set\Serial SetDlg.cpp(105) : error C2664: 'strlen' : cannot convert parameter 1 from 'char *[]' to 'const char *'
        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
Error executing cl.exe.

Serial SetDlg.obj - 4 error(s), 0 warning(s)
0
 
LVL 14

Expert Comment

by:AlexVirochovsky
ID: 6439587
Change
>> static char* szMessage[] = "This is test data";
To
 char* szMessage = "This is test data";
   
That is reason to all 4 errors
   
0
 
LVL 1

Expert Comment

by:RideOn
ID: 6439591
u could also use WinAPI for serial communications.
if the CSerial solution won't work, let me know and i'll give u my class i wrote...

=:=RideOn
0
 
LVL 6

Author Comment

by:xSinbad
ID: 6442961
OK this is what I have;

void CSerialSetDlg::OnOK()
{
CSerial serial;
if (serial.Open(m_Port, 76800))
 {
   AfxMessageBox("Port opened successfully");
   char* szMessage = "This is test data";

    int nBytesSent = serial.SendData(szMessage, strlen  (szMessage));
    ASSERT(nBytesSent == strlen(szMessage));
    serial.Close() ;
 }
else
AfxMessageBox("Failed to open port!");


}




Here are the errors returned;

Compiling...
Serial SetDlg.cpp
C:\Program Files\Microsoft Visual Studio\MyProjects\Serial Set\Serial SetDlg.cpp(106) : warning C4018: '==' : signed/unsigned mismatch
Linking...
Serial SetDlg.obj : error LNK2001: unresolved external symbol "public: __thiscall CSerial::~CSerial(void)" (??1CSerial@@QAE@XZ)
Serial SetDlg.obj : error LNK2001: unresolved external symbol "public: int __thiscall CSerial::Close(void)" (?Close@CSerial@@QAEHXZ)
Serial SetDlg.obj : error LNK2001: unresolved external symbol "public: int __thiscall CSerial::SendData(char const *,int)" (?SendData@CSerial@@QAEHPBDH@Z)
Serial SetDlg.obj : error LNK2001: unresolved external symbol "public: int __thiscall CSerial::Open(int,int)" (?Open@CSerial@@QAEHHH@Z)
Serial SetDlg.obj : error LNK2001: unresolved external symbol "public: __thiscall CSerial::CSerial(void)" (??0CSerial@@QAE@XZ)
Debug/Serial Set.exe : fatal error LNK1120: 5 unresolved externals
Error executing link.exe.
Creating browse info file...

Serial Set.exe - 6 error(s), 1 warning(s)


RideOn, the reason Im doing this is to help out someone in another question. And they need to set the serial port speed to 76800, I have searched the M$ knowledge base long and hard for info on doing this(API would have been great) and 76800 baud is appparently not a constant in the MS comm driver. But by using Cserial I supposedly can acheive this speed.
Im a VB/VBA developer and I thought it was time to take the step up and this is a good a time as any to start...

Sorry for all the suffing around, will up the points to the max.


Cheers
Marcus
0
 
LVL 14

Accepted Solution

by:
AlexVirochovsky earned 1200 total points
ID: 6443642
O, you need add file serial.c in your project.

Or in end of your code add next:
CSerial::CSerial()
{

      memset( &m_OverlappedRead, 0, sizeof( OVERLAPPED ) );
       memset( &m_OverlappedWrite, 0, sizeof( OVERLAPPED ) );
      m_hIDComDev = NULL;
      m_bOpened = FALSE;

}

CSerial::~CSerial()
{

      Close();

}

BOOL CSerial::Open( int nPort, int nBaud )
{

      if( m_bOpened ) return( TRUE );

      char szPort[15];
      char szComParams[50];
      DCB dcb;

      wsprintf( szPort, "COM%d", nPort );
      m_hIDComDev = CreateFile( szPort, GENERIC_READ | GENERIC_WRITE, 0, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED, NULL );
      if( m_hIDComDev == NULL ) return( FALSE );

      memset( &m_OverlappedRead, 0, sizeof( OVERLAPPED ) );
       memset( &m_OverlappedWrite, 0, sizeof( OVERLAPPED ) );

      COMMTIMEOUTS CommTimeOuts;
      CommTimeOuts.ReadIntervalTimeout = 0xFFFFFFFF;
      CommTimeOuts.ReadTotalTimeoutMultiplier = 0;
      CommTimeOuts.ReadTotalTimeoutConstant = 0;
      CommTimeOuts.WriteTotalTimeoutMultiplier = 0;
      CommTimeOuts.WriteTotalTimeoutConstant = 5000;
      SetCommTimeouts( m_hIDComDev, &CommTimeOuts );

      wsprintf( szComParams, "COM%d:%d,n,8,1", nPort, nBaud );

      m_OverlappedRead.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
      m_OverlappedWrite.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );

      dcb.DCBlength = sizeof( DCB );
      GetCommState( m_hIDComDev, &dcb );
      dcb.BaudRate = nBaud;
      dcb.ByteSize = 8;
      unsigned char ucSet;
      ucSet = (unsigned char) ( ( FC_RTSCTS & FC_DTRDSR ) != 0 );
      ucSet = (unsigned char) ( ( FC_RTSCTS & FC_RTSCTS ) != 0 );
      ucSet = (unsigned char) ( ( FC_RTSCTS & FC_XONXOFF ) != 0 );
      if( !SetCommState( m_hIDComDev, &dcb ) ||
            !SetupComm( m_hIDComDev, 10000, 10000 ) ||
            m_OverlappedRead.hEvent == NULL ||
            m_OverlappedWrite.hEvent == NULL ){
            DWORD dwError = GetLastError();
            if( m_OverlappedRead.hEvent != NULL ) CloseHandle( m_OverlappedRead.hEvent );
            if( m_OverlappedWrite.hEvent != NULL ) CloseHandle( m_OverlappedWrite.hEvent );
            CloseHandle( m_hIDComDev );
            return( FALSE );
            }

      m_bOpened = TRUE;

      return( m_bOpened );

}

BOOL CSerial::Close( void )
{

      if( !m_bOpened || m_hIDComDev == NULL ) return( TRUE );

      if( m_OverlappedRead.hEvent != NULL ) CloseHandle( m_OverlappedRead.hEvent );
      if( m_OverlappedWrite.hEvent != NULL ) CloseHandle( m_OverlappedWrite.hEvent );
      CloseHandle( m_hIDComDev );
      m_bOpened = FALSE;
      m_hIDComDev = NULL;

      return( TRUE );

}

BOOL CSerial::WriteCommByte( unsigned char ucByte )
{
      BOOL bWriteStat;
      DWORD dwBytesWritten;

      bWriteStat = WriteFile( m_hIDComDev, (LPSTR) &ucByte, 1, &dwBytesWritten, &m_OverlappedWrite );
      if( !bWriteStat && ( GetLastError() == ERROR_IO_PENDING ) ){
            if( WaitForSingleObject( m_OverlappedWrite.hEvent, 1000 ) ) dwBytesWritten = 0;
            else{
                  GetOverlappedResult( m_hIDComDev, &m_OverlappedWrite, &dwBytesWritten, FALSE );
                  m_OverlappedWrite.Offset += dwBytesWritten;
                  }
            }

      return( TRUE );

}

int CSerial::SendData( const char *buffer, int size )
{

      if( !m_bOpened || m_hIDComDev == NULL ) return( 0 );

      DWORD dwBytesWritten = 0;
      int i;
      for( i=0; i<size; i++ ){
            WriteCommByte( buffer[i] );
            dwBytesWritten++;
            }

      return( (int) dwBytesWritten );

}

int CSerial::ReadDataWaiting( void )
{

      if( !m_bOpened || m_hIDComDev == NULL ) return( 0 );

      DWORD dwErrorFlags;
      COMSTAT ComStat;

      ClearCommError( m_hIDComDev, &dwErrorFlags, &ComStat );

      return( (int) ComStat.cbInQue );

}

int CSerial::ReadData( void *buffer, int limit )
{

      if( !m_bOpened || m_hIDComDev == NULL ) return( 0 );

      BOOL bReadStatus;
      DWORD dwBytesRead, dwErrorFlags;
      COMSTAT ComStat;

      ClearCommError( m_hIDComDev, &dwErrorFlags, &ComStat );
      if( !ComStat.cbInQue ) return( 0 );

      dwBytesRead = (DWORD) ComStat.cbInQue;
      if( limit < (int) dwBytesRead ) dwBytesRead = (DWORD) limit;

      bReadStatus = ReadFile( m_hIDComDev, buffer, dwBytesRead, &dwBytesRead, &m_OverlappedRead );
      if( !bReadStatus ){
            if( GetLastError() == ERROR_IO_PENDING ){
                  WaitForSingleObject( m_OverlappedRead.hEvent, 2000 );
                  return( (int) dwBytesRead );
                  }
            return( 0 );
            }

      return( (int) dwBytesRead );

}

0
 
LVL 6

Author Comment

by:xSinbad
ID: 6449387
Another warning....

Serial SetDlg.cpp
C:\Program Files\Microsoft Visual Studio\MyProjects\Serial Set\Serial SetDlg.cpp(106) : warning C4018: '==' : signed/unsigned mismatch

Serial SetDlg.obj - 0 error(s), 1 warning(s)


This occurs in the following line

    ASSERT(nBytesSent == strlen(szMessage));
0
 
LVL 6

Author Comment

by:xSinbad
ID: 6449397
It doesnt appear to work but that is not your your fault. Thank you very much for your help.

Cheers
Marcus
0

Featured Post

Concerto's Cloud Advisory Services

Want to avoid the missteps to gaining all the benefits of the cloud? Learn more about the different assessment options from our Cloud Advisory team.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Written by John Humphreys C++ Threading and the POSIX Library This article will cover the basic information that you need to know in order to make use of the POSIX threading library available for C and C++ on UNIX and most Linux systems.   [s…
This article will show you some of the more useful Standard Template Library (STL) algorithms through the use of working examples.  You will learn about how these algorithms fit into the STL architecture, how they work with STL containers, and why t…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

721 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question