Solved

How to use Cserial ?

Posted on 2001-08-28
10
2,544 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
Comment Utility
>>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
Comment Utility
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
Comment Utility
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
 
LVL 6

Author Comment

by:xSinbad
Comment Utility
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
Comment Utility
Change
>> static char* szMessage[] = "This is test data";
To
 char* szMessage = "This is test data";
   
That is reason to all 4 errors
   
0
What Should I Do With This Threat Intelligence?

Are you wondering if you actually need threat intelligence? The answer is yes. We explain the basics for creating useful threat intelligence.

 
LVL 1

Expert Comment

by:RideOn
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
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
Comment Utility
It doesnt appear to work but that is not your your fault. Thank you very much for your help.

Cheers
Marcus
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Errors will happen. It is a fact of life for the programmer. How and when errors are detected have a great impact on quality and cost of a product. It is better to detect errors at compile time, when possible and practical. Errors that make their wa…
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.

762 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

Need Help in Real-Time?

Connect with top rated Experts

9 Experts available now in Live!

Get 1:1 Help Now