Solved

How to use Cserial ?

Posted on 2001-08-28
10
2,675 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
Technology Partners: 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 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

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

Suggested Solutions

Title # Comments Views Activity
C++ question 3 82
Which Linux flavors will this run on? 6 116
Gaming Software 1 38
How to determine if the result of an equation is an integer in C++? 3 32
Article by: SunnyDark
This article's goal is to present you with an easy to use XML wrapper for C++ and also present some interesting techniques that you might use with MS C++. The reason I built this class is to ease the pain of using XML files with C++, since there is…
C++ Properties One feature missing from standard C++ that you will find in many other Object Oriented Programming languages is something called a Property (http://www.experts-exchange.com/Programming/Languages/CPP/A_3912-Object-Properties-in-C.ht…
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 be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.

738 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