?
Solved

How to use Cserial ?

Posted on 2001-08-28
10
Medium Priority
?
2,871 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
  • 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
Concerto Cloud for Software Providers & ISVs

Can Concerto Cloud Services help you focus on evolving your application offerings, while delivering the best cloud experience to your customers? From DevOps to revenue models and customer support, the answer is yes!

Learn how Concerto can help you.

 
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

[Webinar] Database Backup and Recovery

Does your company store data on premises, off site, in the cloud, or a combination of these? If you answered “yes”, you need a data backup recovery plan that fits each and every platform. Watch now as as Percona teaches us how to build agile data backup recovery plan.

Question has a verified solution.

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

Introduction This article is a continuation of the C/C++ Visual Studio Express debugger series. Part 1 provided a quick start guide in using the debugger. Part 2 focused on additional topics in breakpoints. As your assignments become a little more …
Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
The viewer will learn how to pass data into a function in C++. This is one step further in using functions. Instead of only printing text onto the console, the function will be able to perform calculations with argumentents given by the user.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.

579 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