Solved

How to use Cserial ?

Posted on 2001-08-28
10
2,715 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
VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

 
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 300 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

On Demand Webinar - Networking for the Cloud Era

This webinar discusses:
-Common barriers companies experience when moving to the cloud
-How SD-WAN changes the way we look at networks
-Best practices customers should employ moving forward with cloud migration
-What happens behind the scenes of SteelConnect’s one-click button

Question has a verified solution.

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

Often, when implementing a feature, you won't know how certain events should be handled at the point where they occur and you'd rather defer to the user of your function or class. For example, a XML parser will extract a tag from the source code, wh…
What is C++ STL?: STL stands for Standard Template Library and is a part of standard C++ libraries. It contains many useful data structures (containers) and algorithms, which can spare you a lot of the time. Today we will look at the STL Vector. …
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 additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.

624 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